class SwitchTest(cst.TContainerMixin): @dataclasses.dataclass class Case1(cst.TContainerMixin): case1_1: int = cst.sfield(cs.Int16sb) case1_2: int = cst.sfield(cs.Int16sb) @dataclasses.dataclass class Case2(cst.TContainerMixin): case2_1: int = cst.sfield(cs.Int8sb) case2_2: int = cst.sfield(cs.Int8sb) case2_3: int = cst.sfield(cs.Int8sb) case2_4: int = cst.sfield(cs.Int8sb) @dataclasses.dataclass class CaseDefault(cst.TContainerMixin): case_default_1: int = cst.sfield(cs.Int32sb) choice: int = cst.sfield(cs.Int8ub) switch: t.Union[Case1, Case2, CaseDefault] = cst.sfield( cs.Switch( cs.this.choice, { 1: cst.TStruct(Case1), 2: cst.TStruct(Case2), }, cst.TStruct(CaseDefault), ))
def test_tstruct() -> None: @dataclasses.dataclass class TestContainer(cst.TContainerBase): a: int = cst.TStructField(cs.Int16ub) b: int = cst.TStructField(cs.Int8ub) common(cst.TStruct(TestContainer), b"\x00\x01\x02", TestContainer(a=1, b=2), 3) # check __getattr__ c = cst.TStruct(TestContainer) assert c.a.name == "a" assert c.b.name == "b" assert c.a.subcon is cs.Int16ub assert c.b.subcon is cs.Int8ub
def test_tstruct_swapped() -> None: @dataclasses.dataclass class TestContainer(cst.TContainerBase): a: int = cst.TStructField(cs.Int16ub) b: int = cst.TStructField(cs.Int8ub) common( cst.TStruct(TestContainer, swapped=True), b"\x02\x00\x01", TestContainer(a=1, b=2), 3, ) normal = cst.TStruct(TestContainer) swapped = cst.TStruct(TestContainer, swapped=True) assert str(normal.parse(b"\x00\x01\x02")) == str( swapped.parse(b"\x02\x00\x01"))
def test_tstruct_no_tcontainerbase() -> None: @dataclasses.dataclass class TestContainer: a: int = cst.TStructField(cs.Int16ub) b: int = cst.TStructField(cs.Int8ub) assert raises(lambda: cst.TStruct(TestContainer)) == TypeError
def test_tstruct_const_field() -> None: @dataclasses.dataclass class TestContainer(cst.TContainerBase): const_field: cst.Opt[bytes] = cst.TStructField(cs.Const(b"\x00")) common( cst.TStruct(TestContainer), bytes(1), setattrs(TestContainer(), const_field=b"\x00"), 1, ) assert (raises( cst.TStruct(TestContainer).build, setattrs(TestContainer(), const_field=b"\x01"), ) == cs.ConstError)
class IfThenElse(cst.TContainerMixin): @dataclasses.dataclass class Then(cst.TContainerMixin): then_1: int = cst.sfield(cs.Int16sb) then_2: int = cst.sfield(cs.Int16sb) @dataclasses.dataclass class Else(cst.TContainerMixin): else_1: int = cst.sfield(cs.Int8sb) else_2: int = cst.sfield(cs.Int8sb) else_3: int = cst.sfield(cs.Int8sb) else_4: int = cst.sfield(cs.Int8sb) choice: int = cst.sfield(cs.Int8ub) if_then_else: t.Union[Then, Else] = cst.sfield( cs.IfThenElse(cs.this.choice == 0, cst.TStruct(Then), cst.TStruct(Else)))
def test_tstruct_add_offsets() -> None: @dataclasses.dataclass class TestContainer(cst.TContainerBase): a: int = cst.TStructField(cs.Int16ub) b: int = cst.TStructField(cs.Int8ub) common( cst.TStruct(TestContainer, add_offsets=True), b"\x00\x01\x02", TestContainer(a=1, b=2), 3, ) c = cst.TStruct(TestContainer, add_offsets=True) obj = c.parse(b"\x00\x01\x02") assert obj["@<a"] == 0 assert obj["@>a"] == 2 assert obj["@<b"] == 2 assert obj["@>b"] == 3
class TStructTest(cst.TContainerMixin): @dataclasses.dataclass class Entry(cst.TContainerMixin): id: int = cst.sfield(cs.Int8sb) width: int = cst.sfield(cs.Int8sb) height: int = cst.sfield(cs.Int8sb) entries: t.List[Entry] = cst.sfield(cs.GreedyRange(cst.TStruct(Entry))) cnt: int = cst.sfield(cs.Computed(lambda ctx: len(ctx.entries)))
def test_tstruct_anonymus_fields_2() -> None: @dataclasses.dataclass class TestContainer(cst.TContainerBase): _1: int = cst.TStructField(cs.Computed(7)) _2: cst.Opt[bytes] = cst.TStructField(cs.Const(b"JPEG")) _3: None = cst.TStructField(cs.Pass) _4: None = cst.TStructField(cs.Terminated) d = cst.TStruct(TestContainer) assert d.build(TestContainer()) == d.build(TestContainer())
class JBSQ(ct.TContainerMixin): magic: Optional[bytes] = ct.sfield( c.Select(c.Const(b"IJBQ"), c.Const(b"IJSQ"), c.Const(b"JBSQ"))) num_events: int = ct.sfield(c.Int32ul) combo: int = ct.sfield(c.Int32ul) end_time: int = ct.sfield(c.Int32ul) _1: None = ct.sfield(c.Padding(2)) starting_buttons: int = ct.sfield(c.Int16ul) start_time: int = ct.sfield(c.Int32ul) _2: None = ct.sfield(c.Padding(12)) density_graph: List[int] = ct.sfield(c.Byte[60]) events: List[Event] = ct.sfield( c.Array(c.this.num_events, ct.TStruct(Event)))
class TStructTest(cst.TContainerMixin): width: int = cst.sfield(cs.Int8sb, doc="Das hier ist die Dokumentation von 'width'") height: int = cst.sfield(cs.Int8sb, doc="Und hier von 'height") @dataclasses.dataclass class Nested(cst.TContainerMixin): nested_width: int = cst.sfield(cs.Int16sb) nested_height: int = cst.sfield(cs.Int16sb) nested_bytes: bytes = cst.sfield(cs.Bytes(2)) nested_array: t.List[int] = cst.sfield(cs.Array(2, cs.Int8sb)) nested: Nested = cst.sfield((cst.TStruct(Nested)))
def test_tstruct_wrong_container() -> None: @dataclasses.dataclass class TestContainer1(cst.TContainerBase): a: int = cst.TStructField(cs.Int16ub) b: int = cst.TStructField(cs.Int8ub) @dataclasses.dataclass class TestContainer2(cst.TContainerBase): a: int = cst.TStructField(cs.Int16ub) b: int = cst.TStructField(cs.Int8ub) assert (raises( cst.TStruct(TestContainer1).build, TestContainer2(a=1, b=2)) == TypeError)
def test_tstruct_anonymus_fields_1() -> None: @dataclasses.dataclass class TestContainer(cst.TContainerBase): _1: cst.Opt[bytes] = cst.TStructField(cs.Const(b"\x00")) _2: None = cst.TStructField(cs.Padding(1)) _3: None = cst.TStructField(cs.Pass) _4: None = cst.TStructField(cs.Terminated) common( cst.TStruct(TestContainer), bytes(2), setattrs(TestContainer(), _1=b"\x00"), cs.SizeofError, )
def test_tstruct_nested() -> None: @dataclasses.dataclass class TestContainer(cst.TContainerBase): @dataclasses.dataclass class InnerDataclass(cst.TContainerBase): b: int = cst.TStructField(cs.Byte) a: InnerDataclass = cst.TStructField(cst.TStruct(InnerDataclass)) common( cst.TStruct(TestContainer), b"\x01", TestContainer(a=TestContainer.InnerDataclass(b=1)), 1, )
def test_tcontainer_order() -> None: @dataclasses.dataclass class Image(cst.TContainerBase): signature: cst.Opt[bytes] = cst.TStructField(cs.Const(b"BMP")) width: int = cst.TStructField(cs.Int8ub) height: int = cst.TStructField(cs.Int8ub) format = cst.TStruct(Image) obj = Image(width=3, height=2) assert (str(obj) == "Container: \n signature = None\n width = 3\n height = 2") obj = format.parse(format.build(obj)) assert ( str(obj) == "Container: \n signature = b'BMP' (total 3)\n width = 3\n height = 2" )
def test_tstruct_default_field() -> None: @dataclasses.dataclass class Image(cst.TContainerBase): width: int = cst.TStructField(cs.Int8ub) height: int = cst.TStructField(cs.Int8ub) pixels: cst.Opt[bytes] = cst.TStructField( cs.Default( cs.Bytes(cs.this.width * cs.this.height), lambda ctx: bytes(ctx.width * ctx.height), )) common( cst.TStruct(Image), b"\x02\x03\x00\x00\x00\x00\x00\x00", setattrs(Image(2, 3), pixels=bytes(6)), sample_building=Image(2, 3), )
def test_tenum_in_tstruct() -> None: class TestEnum(cst.EnumBase): a = 1 b = 2 @dataclasses.dataclass class TestContainer(cst.TContainerBase): a: TestEnum = cst.TStructField(cst.TEnum(cs.Int8ub, TestEnum)) b: int = cst.TStructField(cs.Int8ub) common( cst.TStruct(TestContainer), b"\x01\x02", TestContainer(a=TestEnum.a, b=2), 2, ) assert (raises( cst.TEnum(cs.Byte, TestEnum).build, TestContainer(a=1, b=2)) == TypeError # type: ignore )
def test_tstruct_doc() -> None: @dataclasses.dataclass class TestContainer(cst.TContainerBase): a: int = cst.TStructField(cs.Int16ub, "This is the documentation of a") b: int = cst.TStructField( cs.Int8ub, doc="This is the documentation of b\nwhich is multiline") c: int = cst.TStructField( cs.Int8ub, """ This is the documentation of c which is also multiline """, ) format = cst.TStruct(TestContainer) common(format, b"\x00\x01\x02\x03", TestContainer(a=1, b=2, c=3), 4) assert format.subcon.a.docs == "This is the documentation of a" assert format.subcon.b.docs == "This is the documentation of b\nwhich is multiline" assert (format.subcon.c.docs == "This is the documentation of c\nwhich is also multiline")
MEASURE = 3 HAKU = 4 TEMPO = 5 LONG = 6 @dataclass class Event(ct.TContainerMixin): type_: EventType = ct.sfield(ct.TEnum(c.Byte, EventType)) time_in_ticks: int = ct.sfield(c.Int24ul) value: int = ct.sfield(c.Int32ul) @dataclass class JBSQ(ct.TContainerMixin): magic: Optional[bytes] = ct.sfield( c.Select(c.Const(b"IJBQ"), c.Const(b"IJSQ"), c.Const(b"JBSQ"))) num_events: int = ct.sfield(c.Int32ul) combo: int = ct.sfield(c.Int32ul) end_time: int = ct.sfield(c.Int32ul) _1: None = ct.sfield(c.Padding(2)) starting_buttons: int = ct.sfield(c.Int16ul) start_time: int = ct.sfield(c.Int32ul) _2: None = ct.sfield(c.Padding(12)) density_graph: List[int] = ct.sfield(c.Byte[60]) events: List[Event] = ct.sfield( c.Array(c.this.num_events, ct.TStruct(Event))) jbsq = ct.TStruct(JBSQ)
import construct as cs import construct_typed as cst import dataclasses from . import GalleryItem @dataclasses.dataclass class TBitsStructTest(cst.TContainerMixin): @dataclasses.dataclass class Nested(cst.TContainerMixin): test_bit: int = cst.sfield(cs.Bit) test_nibble: int = cst.sfield(cs.Nibble) test_bits_1: int = cst.sfield(cs.BitsInteger(3)) test_bits_2: int = cst.sfield(cs.BitsInteger(6)) test_bits_3: int = cst.sfield(cs.BitsInteger(2)) nested: Nested = cst.sfield(cs.ByteSwapped(cst.TBitStruct(Nested))) nested_reverse: Nested = cst.sfield(cst.TBitStruct(Nested, reverse=True)) constr = cst.TStruct(TBitsStructTest) gallery_item = GalleryItem( construct=constr, example_binarys={ "Zeros": bytes(constr.sizeof()), }, )
@dataclasses.dataclass class IfThenElse(cst.TContainerMixin): @dataclasses.dataclass class Then(cst.TContainerMixin): then_1: int = cst.sfield(cs.Int16sb) then_2: int = cst.sfield(cs.Int16sb) @dataclasses.dataclass class Else(cst.TContainerMixin): else_1: int = cst.sfield(cs.Int8sb) else_2: int = cst.sfield(cs.Int8sb) else_3: int = cst.sfield(cs.Int8sb) else_4: int = cst.sfield(cs.Int8sb) choice: int = cst.sfield(cs.Int8ub) if_then_else: t.Union[Then, Else] = cst.sfield( cs.IfThenElse(cs.this.choice == 0, cst.TStruct(Then), cst.TStruct(Else))) constr = cst.TStruct(IfThenElse) gallery_item = GalleryItem( construct=constr, example_binarys={ "Zeros": bytes([0, 0, 0, 0, 0]), "1": bytes([0, 1, 2, 1, 2]), }, )
import construct as cs import construct_typed as cst import dataclasses import typing as t import arrow from . import GalleryItem @dataclasses.dataclass class Timestamps(cst.TContainerMixin): time_int8: arrow.Arrow = cst.sfield( cs.Timestamp(cs.Int8ul, unit=1, epoch=arrow.Arrow(2020, 1, 1)) ) time_int16: arrow.Arrow = cst.sfield( cs.Timestamp(cs.Int16ul, unit=1, epoch=arrow.Arrow(2019, 1, 1)) ) time_int32: arrow.Arrow = cst.sfield( cs.Timestamp(cs.Int32ul, unit=1, epoch=arrow.Arrow(2080, 1, 1)) ) constr = cst.TStruct(Timestamps) gallery_item = GalleryItem( construct=constr, example_binarys={ "Zeros": bytes(constr.sizeof()), "1": bytes([4, 4, 12, 4, 4, 4, 4]), }, )
import typing as t from . import GalleryItem @dataclasses.dataclass class RenamedTest(cst.TContainerMixin): height: int = cst.sfield(cs.Int8sb, doc="Und hier von 'height") doc: int = cst.sfield(cs.Int8sb, doc="Das hier ist die Dokumentation von 'width'") doc_multiline: int = cst.sfield( cs.Int8sb, doc=""" Das hier ist die Dokumentation von 'width' """, ) doc2: int = cst.sfield(cs.Int8sb * "Das hier ist die Dokumentation von 'width'") doc2_multiline: int = cst.sfield( cs.Int8sb * """ Das hier ist die Dokumentation von 'width' """ ) constr = cst.TStruct(RenamedTest) gallery_item = GalleryItem( construct=constr, example_binarys={ "Zeros": bytes(constr.sizeof()), }, )
def test_tstruct_no_dataclass() -> None: class TestContainer(cst.TContainerBase): a: int = cst.TStructField(cs.Int16ub) b: int = cst.TStructField(cs.Int8ub) assert raises(lambda: cst.TStruct(TestContainer)) == TypeError
class CarBrand(cst.EnumBase): Porsche = 0 Audi = 4 VW = 7 class CarColor(cst.EnumBase): Red = 1 Green = 10 Blue = 11 Black = 12 @dataclasses.dataclass class Car(cst.TContainerMixin): brand: CarBrand = cst.sfield(cst.TEnum(cs.Int8ul, CarBrand)) wheels: int = cst.sfield(cs.Int8ul) color: CarColor = cst.sfield(cst.TEnum(cs.Int8ul, CarColor)) constr = cst.TStruct(Car) gallery_item = GalleryItem( construct=constr, example_binarys={ "Zeros": bytes(constr.sizeof()), "1": bytes([4, 4, 12]), "2": bytes([4, 4, 13]), "3": bytes([7, 2, 1]), }, )
class TestContainer(cst.TContainerBase): @dataclasses.dataclass class InnerDataclass(cst.TContainerBase): b: int = cst.TStructField(cs.Byte) a: InnerDataclass = cst.TStructField(cst.TStruct(InnerDataclass))
import construct as cs import construct_typed as cst import dataclasses import typing as t from . import GalleryItem @dataclasses.dataclass class TStructTest(cst.TContainerMixin): static: t.List[int] = cst.sfield(cs.Array(5, cs.Int8sb)) dynamic_len: int = cst.sfield(cs.Int8sb, doc="Die Länge des dynamischen Array'") dynamic: t.List[int] = cst.sfield(cs.Array(cs.this.dynamic_len, cs.Int8sb)) constr = cst.TStruct(TStructTest) gallery_item = GalleryItem( construct=constr, example_binarys={ "Zeros": bytes([0, 0, 0, 0, 0, 0]), "1": bytes([1, 2, 3, 4, 5, 4, 1, 2, 3, 4]), "2": bytes([1, 2, 3, 4, 5, 8, 7, 6, 5, 4, 3, 2, 1, 0]), }, )
class Case2(cst.TContainerMixin): case2_1: int = cst.sfield(cs.Int8sb) case2_2: int = cst.sfield(cs.Int8sb) case2_3: int = cst.sfield(cs.Int8sb) case2_4: int = cst.sfield(cs.Int8sb) @dataclasses.dataclass class CaseDefault(cst.TContainerMixin): case_default_1: int = cst.sfield(cs.Int32sb) choice: int = cst.sfield(cs.Int8ub) switch: t.Union[Case1, Case2, CaseDefault] = cst.sfield( cs.Switch( cs.this.choice, { 1: cst.TStruct(Case1), 2: cst.TStruct(Case2), }, cst.TStruct(CaseDefault), )) constr = cst.TStruct(SwitchTest) gallery_item = GalleryItem( construct=constr, example_binarys={ "Zeros": bytes([0, 0, 0, 0, 0]), "1": bytes([1, 1, 2, 1, 2]), }, )