I'm new to Construct, but I'm trying to understand the RepeatUntil type of object (at least, I think that's what I want to use!). What I have is a data structure (TLV = Type, Length, Value). Type is an unsigned byte, length is the length (in bytes) of the value, and value is a string of bytes of the given length, which is interpreted according to the type.
Type 0 is a simple byte string. So I have
TLV = Struct("TLV",
UBInt8("type"),
UBInt16("length"),
Switch("value", lambda ctx: ctx.type, {
# Type 0 - raw bytes data
0 : Bytes("data", lambda ctx: ctx.length),
}
)
)
Type 1 is where things get messy. A type 1 entry contains as its value, a series of TLV objects. Each subobject has its own type and value, and the combined length of the subobjects (including their type and length fields) must equal the length specified in the containing type=1 object.
So this is valid: b"\1\0\9\0\0\1a\0\0\2bc". It's Container(type=1, length=9, value=[Container(type=0, length=1, value=b"a"), Container(type=0, length=2, value=b"bc")]).
How would I define a structure like this?
One other thing, I want length values to be checked to ensure there are no "extra" bytes. TVP.parse(data) by default ignores trailing bytes that aren't needed. Can that be turned into an error? Also, I don't want type 1 values to be allowed to have unused trailing bytes.
Thanks for any help. I'm sorry if this is documented somewhere, I have spent some time looking through the docs but couldn't find anything. I *think* that I should be using RepeatUntil, but I'm not entirely sure how to do so (I'd need to keep track of "number of bytes remaining unused" somehow, and I'm not clear how that would work).
Thanks,
Paul