def test_anonymous_union_struct(compiled): d = """ typedef struct test { union { uint32 a; struct { char b[3]; char c; }; }; uint32 d; } """ c = cstruct.cstruct() c.load(d, compiled=compiled) b = b'\x01\x01\x02\x02\x03\x03\x04\x04' a = c.test(b) assert a.a == 0x02020101 assert a.b == b'\x01\x01\x02' assert a.c == b'\x02' assert a.d == 0x04040303 assert a.dumps() == b
def test_dumpstruct(capsys, compiled): c = cstruct.cstruct() c.load(""" struct test { uint32 testval; }; """, compiled=compiled) data = b'\x39\x05\x00\x00' a = c.test(data) dumpstruct(c.test, data) captured_1 = capsys.readouterr() dumpstruct(a) captured_2 = capsys.readouterr() assert captured_1.out == captured_2.out out_1 = dumpstruct(c.test, data, output='string') out_2 = dumpstruct(a, output='string') assert out_1 == out_2 with pytest.raises(ValueError) as excinfo: dumpstruct(a, output='generator') assert str( excinfo.value ) == "Invalid output argument: 'generator' (should be 'print' or 'string')."
def test_nested_union(compiled): d = """ struct test { char magic[4]; union { struct { uint32 a; uint32 b; } a; struct { char b[8]; } b; } c; }; """ c = cstruct.cstruct() c.load(d, compiled=False) assert len(c.test) == 12 a = c.test(b'zomgholybeef') assert a.magic == b'zomg' assert a.c.a.a == 0x796c6f68 assert a.c.a.b == 0x66656562 assert a.c.b.b == b'holybeef' assert a.dumps() == b'zomgholybeef'
def test_struct_sizes(compiled): c = cstruct.cstruct() c.load(""" struct static { uint32 test; }; struct dynamic { uint32 test[]; }; """, compiled=compiled) assert len(c.static) == 4 if not compiled: c.static.add_field("another", c.uint32) assert len(c.static) == 8 c.static.add_field("atoffset", c.uint32, 12) assert len(c.static) == 16 a = c.static( b'\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00' ) assert a.test == 1 assert a.another == 2 assert a.atoffset == 3 with pytest.raises(TypeError) as excinfo: len(c.dynamic) assert str(excinfo.value) == "Dynamic size" else: with pytest.raises(NotImplementedError) as excinfo: c.static.add_field("another", c.uint32) assert str(excinfo.value) == "Can't add fields to a compiled structure"
def test_pointers(): d = """ struct test { char magic[4]; wchar wmagic[4]; uint8 a; uint16 b; uint32 c; char string[]; wchar wstring[]; }; struct ptrtest { test *ptr; }; """ c = cstruct.cstruct(pointer='uint16') c.load(d, compiled=True) d = b'\x02\x00testt\x00e\x00s\x00t\x00\x01\x02\x03\x04\x05\x06\x07lalala\x00t\x00e\x00s\x00t\x00\x00\x00' p = c.ptrtest(d) a = p.ptr assert a.magic == b'test' assert a.wmagic == 'test' assert a.a == 0x01 assert a.b == 0x0302 assert a.c == 0x07060504 assert a.string == b'lalala' assert a.wstring == 'test'
def test_bitfield_be(): d = """ struct test { uint16 a:4; uint16 b:4; uint16 c:4; uint16 d:4; uint32 e; uint16 f:2; uint16 g:3; uint16 h:4; uint32 i; }; """ c = cstruct.cstruct(endian='>') c.load(d, compiled=False) d = b'\x12\x34\x00\x00\x00\xff\x1f\x00\x00\x00\x00\x01' a = c.test(d) assert a.a == 0b01 assert a.b == 0b10 assert a.c == 0b011 assert a.d == 0b100 assert a.e == 0xff assert a.f == 0 assert a.g == 0b11 assert a.h == 0b1110 assert a.i == 1 assert a.dumps() == d
def to_kmodel(self, arg_oft, eight_bit_mode, buf_map): cparser = cstruct.cstruct() cparser.load(kmodel_def) layer_header = cparser.kpu_model_layer_header_t() layer_body = cparser.kpu_model_quant_max_pool2d_layer_argument_t() # fill layer body layer_body.flags = 0 buf_map, layer_body.main_mem_in_address, layer_body.main_mem_out_address = \ cal_in_out_addr(buf_map, self.outsize) layer_body.in_shape.width = self.in_shape[1] layer_body.in_shape.height = self.in_shape[2] layer_body.in_shape.channels = self.in_shape[3] layer_body.out_shape.width = self.out_shape[1] layer_body.out_shape.height = self.out_shape[2] layer_body.out_shape.channels = self.out_shape[3] layer_body.kernel_width = self.kernel_width layer_body.kernel_height = self.kernel_height layer_body.stride_width = self.stride_width layer_body.stride_height = self.stride_height layer_body.padding_width = self.padding_width layer_body.padding_height = self.padding_height # fill header layer_header.type = self.type layer_header.body_size = len(layer_body) # header, bin, memsize, (s,b) return layer_header, layer_body.dumps(), buf_map, (0, 0)
def test_write_struct_be(compiled): d = """ struct test { char magic[4]; wchar wmagic[4]; uint8 a; uint16 b; uint32 c; char string[]; wchar wstring[]; }; """ c = cstruct.cstruct(endian='>') c.load(d, compiled=compiled) a = c.test() a.magic = 'test' a.wmagic = 'test' a.a = 0x01 a.b = 0x0203 a.c = 0x04050607 a.string = b'lalala' a.wstring = 'test' assert a.dumps( ) == b'test\x00t\x00e\x00s\x00t\x01\x02\x03\x04\x05\x06\x07lalala\x00\x00t\x00e\x00s\x00t\x00\x00'
def test_compiled_struct(): d = """ struct test { char magic[4]; wchar wmagic[4]; uint8 a; uint16 b; uint32 c; char string[]; wchar wstring[]; }; """ c = cstruct.cstruct() c.load(d, compiled=True) d = b'testt\x00e\x00s\x00t\x00\x01\x02\x03\x04\x05\x06\x07lalala\x00t\x00e\x00s\x00t\x00\x00\x00' a = c.test(d) assert a.magic == b'test' assert a.wmagic == 'test' assert a.a == 0x01 assert a.b == 0x0302 assert a.c == 0x07060504 assert a.string == b'lalala' assert a.wstring == 'test' assert d == a.dumps()
def test_simple_struct_be(): d = """ struct test { char magic[4]; wchar wmagic[4]; uint8 a; uint16 b; uint32 c; char string[]; wchar wstring[]; }; """ c = cstruct.cstruct(endian='>') c.load(d, compiled=False) d = b'test\x00t\x00e\x00s\x00t\x01\x02\x03\x04\x05\x06\x07lalala\x00\x00t\x00e\x00s\x00t\x00\x00' a = c.test(d) assert a.magic == b'test' assert a.wmagic == 'test' assert a.a == 0x01 assert a.b == 0x0203 assert a.c == 0x04050607 assert a.string == b'lalala' assert a.wstring == 'test' assert d == a.dumps()
def test_bitfield(compiled): d = """ struct test { uint16 a:4; uint16 b:4; uint16 c:4; uint16 d:4; uint32 e; uint16 f:2; uint16 g:3; uint32 h; }; """ c = cstruct.cstruct() c.load(d, compiled=compiled) d = b'\x12\x34\xff\x00\x00\x00\x1f\x00\x01\x00\x00\x00' a = c.test(d) assert a.a == 0b10 assert a.b == 0b01 assert a.c == 0b100 assert a.d == 0b011 assert a.e == 0xff assert a.f == 0b11 assert a.g == 0b111 assert a.h == 1 assert a.dumps() == d
def to_kmodel(self, arg_oft, eight_bit_mode, buf_map): cparser = cstruct.cstruct() cparser.load(kmodel_def) layer_header = cparser.kpu_model_layer_header_t() layer_body = cparser.kpu_model_fully_connected_layer_argument_t() # fill layer body layer_body.flags = 0 buf_map, layer_body.main_mem_in_address, layer_body.main_mem_out_address = \ cal_in_out_addr(buf_map, self.outsize) layer_body.in_channels = self.in_channels layer_body.out_channels = self.out_channels layer_body.act = self.act # weights layer_weights = bytearray() layer_bias = bytearray() weights = self.W bias = self.b for i in range(self.out_channels): for j in range(self.in_channels): layer_weights += struct.pack("<f", weights[j][i]) layer_bias += struct.pack("<f", bias[i]) layer_bin = layer_body.dumps() + layer_weights + layer_bias # fill header layer_header.type = self.type layer_header.body_size = len(layer_bin) # header, bin, memsize, (s,b) #logging.info(layer_body) #logging.info(layer_body.dumps()) return layer_header, layer_bin, buf_map, (0, 0)
def test_struct_sizes(): c = cstruct.cstruct() c.load(""" struct static { uint32 test; }; struct dynamic { uint32 test[]; }; """, compiled=False) assert len(c.static) == 4 c.static.add_field("another", c.uint32) assert len(c.static) == 8 c.static.add_field("atoffset", c.uint32, 12) assert len(c.static) == 16 a = c.static( b'\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00') assert a.test == 1 assert a.another == 2 assert a.atoffset == 3 with pytest.raises(TypeError) as excinfo: len(c.dynamic) assert str(excinfo.value) == "Dynamic size"
def test_enum_name(): d = """ enum Color: uint16 { RED = 1, GREEN = 2, BLUE = 3, }; struct Pixel { uint8 x; uint8 y; Color color; uint32 hue; }; """ c = cstruct.cstruct() c.load(d, compiled=False) Color = c.Color Pixel = c.Pixel pixel = Pixel(b'\xFF\x0A\x01\x00\xAA\xBB\xCC\xDD') assert pixel.x == 255 assert pixel.y == 10 assert pixel.color.name == 'RED' assert pixel.color.value == Color.RED assert pixel.color.value == 1 assert pixel.hue == 0xDDCCBBAA # unknown enum values default to <enum name>_<value> pixel = Pixel(b'\x00\x00\xFF\x00\xAA\xBB\xCC\xDD') assert pixel.color.name == 'Color_255' assert pixel.color.value == 0xFF
def test_lookups(): c = cstruct.cstruct() c.load(""" #define test_1 1 #define test_2 2 $a = {'test_1': 3, 'test_2': 4} """, compiled=False) assert c.lookups['a'] == {1: 3, 2: 4}
def test_duplicate_type(): d = """ struct test { uint32 a; }; """ c = cstruct.cstruct() c.load(d, compiled=False) with pytest.raises(ValueError): c.load(d)
def test_underscores_attribute(compiled): c = cstruct.cstruct() c.load(""" struct __test { uint32 test_val; }; """, compiled=compiled) data = b'\x39\x05\x00\x00' a = c.__test(data) assert a.test_val == 1337
def test_simple_types(): c = cstruct.cstruct() assert c.uint32(b'\x01\x00\x00\x00') == 1 assert c.uint32[10](b"A" * 20 + b"B" * 20) == [0x41414141] * 5 + [0x42424242] * 5 assert c.uint32[None](b"A" * 20 + b"\x00" * 4) == [0x41414141] * 5 with pytest.raises(EOFError): c.char[None](b'aaa') with pytest.raises(EOFError): c.wchar[None](b'a\x00a\x00a')
def test_compiler_slicing_multiple(compiled): c = cstruct.cstruct() c.load(""" struct compile_slicing { char single; char multiple[2]; }; """, compiled=compiled) a = c.compile_slicing(b'\x01\x02\x03') assert a.single == b'\x01' assert a.multiple == b'\x02\x03'
def test_bytes_integer_signed(): c = cstruct.cstruct() assert c.int24(b'\xff\x00\x00') == 255 assert c.int24(b'\xff\xff\xff') == -1 assert c.int24[4](b'\xff\xff\xff\xfe\xff\xff\xfd\xff\xff\xfc\xff\xff') == [ -1, -2, -3, -4 ] int40 = BytesInteger(c, 'int40', 5, signed=True) assert int40(b'AAAAA') == 0x4141414141 assert int40(b'\xff\xff\xff\xff\xff') == -1 assert int40[2](b'\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff') == [-1, -2]
def test_write_be(): c = cstruct.cstruct(endian='>') assert c.uint32.dumps(1) == b'\x00\x00\x00\x01' assert c.uint16.dumps(255) == b'\x00\xff' assert c.int8.dumps(-10) == b'\xf6' assert c.uint8[4].dumps([1, 2, 3, 4]) == b'\x01\x02\x03\x04' assert c.uint24.dumps(300) == b'\x00\x01\x2c' assert c.int24.dumps(-1337) == b'\xff\xfa\xc7' assert c.uint24[4].dumps( [1, 2, 3, 4]) == b'\x00\x00\x01\x00\x00\x02\x00\x00\x03\x00\x00\x04' assert c.char.dumps(0x61) == b'a' assert c.wchar.dumps('lala') == b'\x00l\x00a\x00l\x00a'
def test_bytes_integer_unsigned_be(): c = cstruct.cstruct() c.endian = '>' assert c.uint24(b'\x00\x00\xff') == 255 assert c.uint24(b'\xff\xff\xff') == 0xffffff assert c.uint24[3](b'\x00\x00\xff\x00\x00\xfe\x00\x00\xfd') == [ 255, 254, 253 ] uint40 = BytesInteger(c, 'uint40', 5, signed=False) assert uint40(b'\x00\x00\x00\x00\xff') == 255 assert uint40(b'\xff\xff\xff\xff\xff') == 0xffffffffff assert uint40[2](b'\x00\x00\x00\x00A\x00\x00\x00\x00B') == [0x41, 0x42]
def test_flag(compiled): d = """ flag Test { a, b, c, d }; flag Odd { a = 2, b, c, d = 32, e, f, g }; """ c = cstruct.cstruct() c.load(d, compiled=compiled) assert c.Test.a == 1 assert c.Test.b == 2 assert c.Test.c == 4 assert c.Test.d == 8 assert c.Odd.a == 2 assert c.Odd.b == 4 assert c.Odd.c == 8 assert c.Odd.d == 32 assert c.Odd.e == 64 assert c.Odd.f == 128 assert c.Odd.g == 256 assert c.Test.a == c.Test.a assert c.Test.a != c.Test.b assert bool(c.Test(0)) is False assert bool(c.Test(1)) is True assert c.Test.a | c.Test.b == 3 assert str(c.Test.c | c.Test.d) == 'Test.d|c' assert repr(c.Test.a | c.Test.b) == '<Test.b|a: 3>' assert c.Test(2) == c.Test.b assert c.Test(3) == c.Test.a | c.Test.b assert c.Test.c & 12 == c.Test.c assert c.Test.b & 12 == 0 assert c.Test.b ^ c.Test.a == c.Test.a | c.Test.b assert ~c.Test.a == -2 assert str(~c.Test.a) == 'Test.d|c|b'
def test_constants(): d = """ #define a 1 #define b 0x2 #define c "test" #define d 1 << 1 """ c = cstruct.cstruct() c.load(d) assert c.a == 1 assert c.b == 2 assert c.c == "test" assert c.d == 2
def to_kmodel(self, arg_oft, eight_bit_mode, buf_map): cparser = cstruct.cstruct() cparser.load(kmodel_def) layer_header = cparser.kpu_model_layer_header_t() layer_body = cparser.kpu_model_softmax_layer_argument_t() # fill layer body layer_body.flags = 0 buf_map, layer_body.main_mem_in_address, layer_body.main_mem_out_address = \ cal_in_out_addr(buf_map, self.outsize) layer_body.channels = self.channels # fill header layer_header.type = self.type layer_header.body_size = len(layer_body) return layer_header, layer_body.dumps(), buf_map, (0, 0)
def test_bytes_integer_signed_be(): c = cstruct.cstruct() c.endian = '>' assert c.int24(b'\x00\x00\xff') == 255 assert c.int24(b'\xff\xff\x01') == -255 assert c.int24[3](b'\xff\xff\x01\xff\xff\x02\xff\xff\x03') == [ -255, -254, -253 ] int40 = BytesInteger(c, 'int40', 5, signed=True) assert int40(b'\x00\x00\x00\x00\xff') == 255 assert int40(b'\xff\xff\xff\xff\xff') == -1 assert int40(b'\xff\xff\xff\xff\x01') == -255 assert int40[2](b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe') == [-1, -2]
def test_flag_read(compiled): d = """ flag Test16 : uint16 { A = 0x1, B = 0x2 }; flag Test24 : uint24 { A = 0x1, B = 0x2 }; flag Test32 : uint32 { A = 0x1, B = 0x2 }; struct test { Test16 a16; Test16 b16; Test24 a24; Test24 b24; Test32 a32; Test32 b32; Test16 l[2]; Test16 c16; }; """ c = cstruct.cstruct() c.load(d, compiled=compiled) a = c.test( b'\x01\x00\x02\x00\x01\x00\x00\x02\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x00\x02\x00\x03\x00' ) assert a.a16.enum == c.Test16 and a.a16.value == c.Test16.A assert a.b16.enum == c.Test16 and a.b16.value == c.Test16.B assert a.a24.enum == c.Test24 and a.a24.value == c.Test24.A assert a.b24.enum == c.Test24 and a.b24.value == c.Test24.B assert a.a32.enum == c.Test32 and a.a32.value == c.Test32.A assert a.b32.enum == c.Test32 and a.b32.value == c.Test32.B assert len(a.l) == 2 assert a.l[0].enum == c.Test16 and a.l[0].value == c.Test16.A assert a.l[1].enum == c.Test16 and a.l[1].value == c.Test16.B assert a.c16 == c.Test16.A | c.Test16.B assert a.c16 & c.Test16.A assert str(a.c16) == 'Test16.B|A'
def test_write(): c = cstruct.cstruct() assert c.uint32.dumps(1) == b'\x01\x00\x00\x00' assert c.uint16.dumps(255) == b'\xff\x00' assert c.int8.dumps(-10) == b'\xf6' assert c.uint8[4].dumps([1, 2, 3, 4]) == b'\x01\x02\x03\x04' assert c.uint24.dumps(300) == b'\x2c\x01\x00' assert c.int24.dumps(-1337) == b'\xc7\xfa\xff' assert c.uint24[4].dumps( [1, 2, 3, 4]) == b'\x01\x00\x00\x02\x00\x00\x03\x00\x00\x04\x00\x00' assert c.uint24[None].dumps([1, 2]) == b'\x01\x00\x00\x02\x00\x00\x00\x00\x00' assert c.char.dumps(0x61) == b'a' assert c.wchar.dumps('lala') == b'l\x00a\x00l\x00a\x00' assert c.uint32[None].dumps([1]) == b'\x01\x00\x00\x00\x00\x00\x00\x00'
def test_type_resolve(): c = cstruct.cstruct() assert c.resolve('byte') == c.int8 with pytest.raises(cstruct.ResolveError) as excinfo: c.resolve('fake') assert "Unknown type" in str(excinfo.value) c.addtype('ref0', 'uint32') for i in range(1, 15): # Recursion limit is currently 10 c.addtype('ref{}'.format(i), 'ref{}'.format(i - 1)) with pytest.raises(cstruct.ResolveError) as excinfo: c.resolve('ref14') assert "Recursion limit exceeded" in str(excinfo.value)
def to_kmodel(self, arg_oft, eight_bit_mode, buf_map): cparser = cstruct.cstruct() cparser.load(kmodel_def) layer_header = cparser.kpu_model_layer_header_t() layer_body = cparser.kpu_model_tf_flatten_layer_argument_t() # fill layer body layer_body.flags = 0 buf_map, layer_body.main_mem_in_address, layer_body.main_mem_out_address = \ cal_in_out_addr(buf_map, self.outsize) layer_body.width = self.shape[1] layer_body.height = self.shape[2] layer_body.channels = self.shape[3] # fill header layer_header.type = self.type layer_header.body_size = len(layer_body) # header, bin, memsize, (s,b) return layer_header, layer_body.dumps(), buf_map, (0, 0)