Skip to content

Feature request: SizeOfSelf for structs #1120

Description

@matejcik

The number one sore spot for me when using construct is the absence of specifying that some field carries the size of the enclosing struct.

Consider this C struct:

struct header {
    int magic;
    int hdr_size;
    int version_major;
    int version_minor;
};

struct header_ext {
    struct header hdr;
    char name[30];
    char surname[30];
};

the intention of struct header is that it can be extended.

if i want to parse it generically out of a stream, i'm currently writing something like this:

Header = c.Struct(
    "_start" / c.Tell,
    "magic" / c.Int32ul,
    "hdr_size" / c.Int32ul,
    "version_major" / c.Int32ul,
    "version_minor" / c.Int32ul,
    "_end" / c.Tell,
    "trailing_data" / # the abomination!
        c.Bytes(c.this.hdr_size - c.this._end + c.this._start)
)

but then I can't build that from scratch!
i can either

  • hard-code that the size of the common prefix is, in this case, 16 bytes, which will break if i ever modify the common header
  • say that trailing_data is actually c.Default(c.Bytes(<the horrible expression>), b"\x00 * <the horrible expression>, then not provide the trailing data, set hdr_size to something big enough, read out the trailing data ......... blech

consider the alternative:

Header = c.Struct(
    "magic" / c.Int32ul,
    "hdr_size" / c.SizeOfSelf(c.Int32ul),
    "version_major" / c.Int32ul,
    "version_minor" / c.Int32ul,
    "trailing_data" / c.GreedyBytes,
)

when parsing hdr_size, the parser will limit the current struct to hdr_size - <size of already parsed>, and raise if that ends up negative
and when building, the builder will just do what it does, then go back Pointer-like to the right place and write the final value

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions