def test_parse(self): struct = BitStruct("foo", BitField("a", 3), Flag("b"), Padding(3), Nibble("c"), BitField("d", 5), ) self.assertEqual(struct.parse(six.b("\xe1\x1f")), Container(a=7, b=False, c=8, d=31))
def test(self): struct = BitStruct( "bitstruct", BitField("a", 3), Flag("b"), Padding(3), Nibble("c"), BitField("d", 5), ) self.assertEqual(struct.parse(b"\xe1\x1f"), Container(a=7)(b=False)(c=8)(d=31)) self.assertEqual(struct.build(Container(a=7)(b=False)(c=8)(d=31)), b"\xe1\x1f")
def perf_event_header(): return Embedded(Struct(None, Enum(UNInt32("type"), MMAP = 1, LOST = 2, COMM = 3, EXIT = 4, THROTTLE = 5, UNTHROTTLE = 6, FORK = 7, READ = 8, SAMPLE = 9, MMAP2 = 10, RECORD_AUX = 11, ITRACE_START = 12, LOST_SAMPLES = 13, SWITCH = 14, SWITCH_CPU_WIDE = 15, NAMESPACES = 16, KSYMBOL = 17, BPF_EVENT = 18, CGROUP = 19, HEADER_ATTR = 64, HEADER_EVENT_TYPE = 65, TRACING_DATA = 66, HEADER_BUILD_ID = 67, FINISHED_ROUND = 68, ID_INDEX = 69, AUXTRACE_INFO = 70, AUXTRACE = 71, AUXTRACE_ERROR = 72, THREAD_MAP = 73, CPU_MAP = 74, STAT_CONFIG = 75, STAT = 76, STAT_ROUND = 77, EVENT_UPDATE = 78, TIME_CONV = 79, HEADER_FEATURE = 80, COMPRESSED = 81), Embedded(BitStruct(None, Padding(1), Enum(BitField("cpumode", 7), UNKNOWN = 0, KERNEL = 1, USER = 2, HYPERVISOR = 3, GUEST_KERNEL = 4, GUEST_USER = 5), Flag("ext_reserved"), Flag("exact_ip"), Flag("mmap_data"), Padding(5))), UNInt16("size"), If(has_sample_id_all, Pointer(lambda ctx: ctx.start + ctx.size - 8, UNInt64("end_id"))), Value("attr", lookup_event_attr)))
def test_parse_nested(self): struct = BitStruct("foo", BitField("a", 3), Flag("b"), Padding(3), Nibble("c"), Struct( "bar", Nibble("d"), Bit("e"), )) self.assertEqual( struct.parse(b"\xe1\x1f"), Container(a=7, b=False, bar=Container(d=15, e=1), c=8))
def test_nested(self): struct = BitStruct("bitstruct", BitField("a", 3), Flag("b"), Padding(3), Nibble("c"), Struct( "sub", Nibble("d"), Bit("e"), )) self.assertEqual( struct.parse(b"\xe1\x1f"), Container(a=7)(b=False)(c=8)(sub=Container(d=15)(e=1))) self.assertEqual( struct.build( Container(a=7)(b=False)(c=8)(sub=Container(d=15)(e=1))), b"\xe1\x1f")
def perf_event_header(): return Embedded( Struct( None, Enum(UNInt32("type"), MMAP=1, LOST=2, COMM=3, EXIT=4, THROTTLE=5, UNTHROTTLE=6, FORK=7, READ=8, SAMPLE=9, MMAP2=10, TRACING_DATA=66, FINISHED_ROUND=68, ID_INDEX=69, AUXTRACE_INFO=70, AUXTRACE=71, AUXTRACE_ERROR=72), Embedded( BitStruct( None, Padding(1), Enum(BitField("cpumode", 7), UNKNOWN=0, KERNEL=1, USER=2, HYPERVISOR=3, GUEST_KERNEL=4, GUEST_USER=5), Flag("ext_reserved"), Flag("exact_ip"), Flag("mmap_data"), Padding(5))), UNInt16("size"), If( has_sample_id_all, Pointer(lambda ctx: ctx.start + ctx.size - 8, UNInt64("end_id"))), Value("attr", lookup_event_attr)))
Flag("read"), Flag("addr"), Flag("time"), Flag("tid"), Flag("ip"), Flag("data_src"), Flag("weight"), Flag("stack_user"), Flag("regs_user"), Flag("branch_stack"), Flag("raw"), Flag("stream_id"), Flag("period"), Padding(5), Flag("regs_intr"), Flag("transaction"), Flag("identifier"), Padding(64 - 3 * 8)), BitStruct("read_format", Padding(4), Flag("group"), Flag("id"), Flag("total_time_running"), Flag("total_time_enabled"), Padding(64 - 1 * 8)), Embedded( BitStruct(None, Flag("disabled"), Flag("inherit"), Flag("pinned"), Flag("exclusive"), Flag("exclude_user"), Flag("exclude_kernel"), Flag("exclude_hv"), Flag("exclude_idle"), Flag("mmap"), Flag("comm"), Flag("freq"), Flag("inherit_stat"), Flag("enable_on_exec"), Flag("task"), Flag("watermark"), BitField("precise_ip", 2), Flag("mmap_data"), Flag("sample_id_all"), Flag("exclude_host"), Flag("exclude_guest"), Flag("exclude_callchain_kernel"), Flag("exclude_callchain_user"), Padding(41))), UNInt32("wakeup_events"), UNInt32("bp_type"), UNInt64("config1"), If(lambda ctx: ctx.size >= perf_event_attr_sizes[1], UNInt64("config2")), If(lambda ctx: ctx.size >= perf_event_attr_sizes[2], UNInt64("branch_sample_type")), If( lambda ctx: ctx.size >= perf_event_attr_sizes[3], Embedded( Struct(None, UNInt64("sample_regs_user"), UNInt32("sample_stack_user"), UNInt32("__reserved_2")))), If(lambda ctx: ctx.size >= perf_event_attr_sizes[4],
Flag("disabled"), Flag("inherit"), Flag("pinned"), Flag("exclusive"), Flag("exclude_user"), Flag("exclude_kernel"), Flag("exclude_hv"), Flag("exclude_idle"), Flag("mmap"), Flag("comm"), Flag("freq"), Flag("inherit_stat"), Flag("enable_on_exec"), Flag("task"), Flag("watermark"), BitField("precise_ip", 2), Flag("mmap_data"), Flag("sample_id_all"), Flag("exclude_host"), Flag("exclude_guest"), Flag("exclude_callchain_kernel"), Flag("exclude_callchain_user"), Padding(41))), UNInt32("wakeup_events"), UNInt32("bp_type"), UNInt64("config1"), If(lambda ctx: ctx.size >= perf_event_attr_sizes[1], UNInt64("config2")), If(lambda ctx: ctx.size >= perf_event_attr_sizes[2], UNInt64("branch_sample_type")), If(lambda ctx: ctx.size >= perf_event_attr_sizes[3],
see http://libdrc.org/docs/re/sc-input.html TODO tests """ from construct import (ULint8, ULint16, Array, Struct, BitStruct, BitField, Byte, SLInt16, Padding, Rename) u16 = ULint16 s16 = SLInt16 u8 = ULint8 AccelerometerData = Struct("AccelerometerData", s16("x_accel"), s16("y_accel"), s16("z_accel")) Dummy24Bits = BitStruct("s24", BitField("value", 24)) GyroscopeData = Struct("AccelerometerData", Rename("roll", Dummy24Bits), Rename("yaw", Dummy24Bits), Rename("pitch", Dummy24Bits)) MagnetData = Struct("MagnetData", Array(6, Byte("unknown"))) ### Some notes on the Point field usage ## Touchscreen Pressure # Stored as a 12 bit integer in the extra data of the first two points. It is # not yet known how to translate this value to a usable pressure value - # currently it is assumed to be a resistance value reading. ## UIC firmware version # 16 bit integer stored in the extra data of points 6 to 8 (only one bit of the # first coordinate of point 6 is used).
SBInt32("y"), SBInt32("z"), ), } # Metadata subconstruct. entity_metadata = MetadataAdapter( Struct( "metadata", RepeatUntil( lambda obj, context: obj["peeked"] == 0x7f, Struct( "data", BitStruct( "id", BitField("data_type", 3), # first BitField("identifier", 5), # second ), Switch("value", lambda context: context["id"]["data_type"], metadata_switch), Peek(SBInt8("peeked")), ), ), Const(UBInt8("terminator"), 0x7f), ), ) # The actual packet list. packets = { 0: Struct( "keep alive",
SCB_VTOR = 0xe000ed08 SCB_ICSR = 0xe000ed04 scb_icsr = BitStruct( "scb_icsr", Flag('NMIPENDSET'), Padding(2), Flag('PENDSVSET'), Flag('PENDSVCLR'), Flag('PENDSTSET'), Flag('PENDSTCLR'), Padding(2), #Padding(1), #Flag('DEBUG'), Flag('ISRPENDING'), BitField('VECTPENDING', 10), Flag('RETOBASE'), Padding(2), BitField('VECTACTIVE', 9), ) SCB_SHCSR = 0xe000ed24 scb_shcsr = BitStruct("scb_shcsr", Padding(13), Flag('USGFAULTENA'), Flag('BUSFAULTENA'), Flag('MEMFAULTENA'), Flag('SVCALLPENDED'), Flag('BUSFAULTPENDED'), Flag('MEMFAULTPENDED'), Flag('USGFAULTPENDED'), Flag('SYSTICKACT'), Flag('PENDSVACT'), Padding(1), Flag('MONITORACT'), Flag('SVCALLACT'), Padding(3), Flag('USGFAULTACT'), Padding(1), Flag('BUSFAULTACT'), Flag('MEMFAULTACT'))
from construct import Struct, ULInt8, ULInt24, BitStruct, Enum, BitField, Padding RPLIDAR_CMD_SYNC_BYTE = 0XA5 RPLIDAR_CMDFLAG_HAS_PAYLOAD = 0X80 RPLIDAR_ANS_SYNC_BYTE1 = 0XA5 RPLIDAR_ANS_SYNC_BYTE2 = 0X5A RPLIDAR_ANS_PKTFLAG_LOOP = 0X1 RPLIDAR_ANS_HEADER_SIZE_MASK = 0x3FFFFFFF RPLIDAR_ANS_HEADER_SUBTYPE_SHIFT = 30 rplidar_cmd_format = Struct( "cmd_format", ULInt8("sync_byte"), # Must be RPLIDAR_CMD_SYNC_BYTE ULInt8("cmd_flag")) rplidar_response_header_format = Struct( "ans_header", ULInt8("sync_byte_1"), # Must be RPLIDAR_ANS_SYNC_BYTE1 ULInt8("sync_byte_2"), # Must be RPLIDAR_ANS_SYNC_BYTE2 # _u32 size_q30_subtype; // see _u32 size:30; _u32 subType:2; # The size will contain the majority of the bytes, the subtype # is only 2 bits with either SINGLE or MULTI response currently available ULInt24("size"), BitStruct( "subtype_mode", Enum(BitField("mode", 2), SINGLE=0x0, MULTI=0x1, _default_="RESERVED"), Padding(6)), ULInt8("type"))
CLASS, TTL, RDLENGTH, RDATA, ) # The DNS packet header itself, combining all of the above DNSHeader = Struct( 'DNSHeader', Anchor('packet_start'), UBInt16('identification'), BitStruct( 'flags_and_codes', Enum( BitField('qr', 1), # query/response QUERY=0, RESPONSE=1, ), Nibble('opcode'), # opcode Enum( Flag('aa'), # authoritative answer NON_AUTHORITATIVE=0, AUTHORITATIVE=1, ), Enum( Flag('tc'), # truncated NOT_TRUNCATED=0, TRUNCATED=1, ), Enum(
RPLIDAR_ANS_TYPE_DEVHEALTH = 0x6 RPLIDAR_STATUS_OK = 0x0 RPLIDAR_STATUS_WARNING = 0x1 RPLIDAR_STATUS_ERROR = 0x2 RPLIDAR_RESP_MEASUREMENT_SYNCBIT = 0x1 << 0 RPLIDAR_RESP_MEASUREMENT_QUALITY_SHIFT = 2 RPLIDAR_RESP_MEASUREMENT_CHECKBIT = 0x1 << 0 RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT = 1 ## #As defined by Figure 9. in "rplidar_interface_protocol_en.pdf" ## rplidar_response_device_measurement_format = Struct( "measurement_format", BitStruct("byte0", BitField("quality", 6), Flag("syncbit_inverse"), Flag("syncbit")), BitStruct( "byte1", BitField("angle_low", 7), Const(Flag("check_bit"), 1) # Must be set to 1 ), ULInt8("angle_high"), ULInt16("distance_q2")) ## # As defined by Figure 12. in "rplidar_interface_protocol_en.pdf" ## rplidar_response_device_info_format = Struct("info_format", ULInt8("model"), ULInt8("firmware_minor"), ULInt8("firmware_major"),
ULInt16('move2_id'), ULInt16('move3_id'), ULInt16('move4_id'), ULInt8('move1_pp'), ULInt8('move2_pp'), ULInt8('move3_pp'), ULInt8('move4_pp'), ULInt8('move1_pp_ups'), ULInt8('move2_pp_ups'), ULInt8('move3_pp_ups'), ULInt8('move4_pp_ups'), LittleEndianBitStruct('ivs', Flag('is_nicknamed'), Flag('is_egg'), BitField('iv_special_defense', 5), BitField('iv_special_attack', 5), BitField('iv_speed', 5), BitField('iv_defense', 5), BitField('iv_attack', 5), BitField('iv_hp', 5), ), LittleEndianBitStruct('hoenn_ribbons', Flag('world_ribbon'), Flag('earth_ribbon'), Flag('national_ribbon'), Flag('country_ribbon'), Flag('sky_ribbon'), Flag('land_ribbon'), Flag('marine_ribbon'), Flag('effort_ribbon'),
from construct import BitStruct, BitField, Padding, Enum, Flag SCB_ICSR = 0xe000ed04 scb_icsr = BitStruct( "scb_icsr", Flag('NMIPENDSET'), Padding(2), Flag('PENDSVSET'), Flag('PENDSVCLR'), Flag('PENDSTSET'), Flag('PENDSTCLR'), Padding(1), Flag('DEBUG'), Flag('ISRPENDING'), BitField('VECTPENDING', 10), Flag('RETOBASE'), Padding(2), BitField('VECTACTIVE', 9), ) SCB_SHCSR = 0xe000ed24 scb_shcsr = BitStruct("scb_shcsr", Padding(13), Flag('USGFAULTENA'), Flag('BUSFAULTENA'), Flag('MEMFAULTENA'), Flag('SVCALLPENDED'), Flag('BUSFAULTPENDED'), Flag('MEMFAULTPENDED'), Flag('USGFAULTPENDED'), Flag('SYSTICKACT'), Flag('PENDSVACT'), Padding(1), Flag('MONITORACT'), Flag('SVCALLACT'), Padding(3), Flag('USGFAULTACT'), Padding(1), Flag('BUSFAULTACT'), Flag('MEMFAULTACT'))
"coords", UBInt32("x"), UBInt32("y"), UBInt32("z"), ), } # Metadata subconstruct. metadata = Struct( "metadata", OptionalGreedyRange( Struct( "data", BitStruct( "id", BitField("first", 3), BitField("second", 5), ), Switch("value", lambda context: context["id"]["first"], metadata_switch), ), ), Const(UBInt8("terminator"), 0x7f), ) # Build faces, used during dig and build. faces = { "noop": -1, "-y": 0, "+y": 1, "-z": 2, "+z": 3,
UBInt32("y"), UBInt32("z"), ), } # Metadata subconstruct. metadata = MetadataAdapter( Struct( "metadata", RepeatUntil( lambda obj, context: obj["peeked"] == 0x7f, Struct( "data", BitStruct( "id", BitField("type", 3), BitField("key", 5), ), Switch("value", lambda context: context["id"]["type"], metadata_switch), Peek(UBInt8("peeked")), ), ), Const(UBInt8("terminator"), 0x7f), ), ) # Build faces, used during dig and build. faces = { "noop": -1, "-y": 0, "+y": 1,
# record number ULInt16('number'), If(lambda x: x['type'] == 'STRING', ULInt16('array_element_size')), If(lambda x: x['type'] == 'STRING', ULInt16('template')), If(lambda x: x['type'] == 'CSTRING', ULInt16('array_element_size')), If(lambda x: x['type'] == 'CSTRING', ULInt16('template')), If(lambda x: x['type'] == 'PSTRING', ULInt16('array_element_size')), If(lambda x: x['type'] == 'PSTRING', ULInt16('template')), If(lambda x: x['type'] == 'PICTURE', ULInt16('array_element_size')), If(lambda x: x['type'] == 'PICTURE', ULInt16('template')), If(lambda x: x['type'] == 'DECIMAL', Byte('decimal_count')), If(lambda x: x['type'] == 'DECIMAL', Byte('decimal_size')), allow_overwrite=True, ) INDEX_TYPE_STRUCT = Enum(BitField('type', 2), KEY=0, INDEX=1, DYNAMIC_INDEX=2) INDEX_FIELD_ORDER_TYPE_STRUCT = Enum(ULInt16('field_order_type'), ASCENDING=0, DESCENDING=1, _default_='DESCENDING') TABLE_DEFINITION_INDEX_STRUCT = Struct( 'record_table_definition_index', # May be external_filename # if external_filename == 0, no external file index CString('external_filename'), If(lambda x: len(x['external_filename']) == 0, Const(Byte('index_mark'), 1)), CString('name'), Embed(
admin_report = Struct( "admin", Const(UBInt16("length"), 13), Const(Byte("ID"), 1), Const(Byte("types"), 4), Const(PascalString("name", length_field=Byte("length"), encoding="utf8"), "admin"), Struct("version", Byte("major"), Byte("minor"), Byte("patch"))) HID_report = OptionalGreedyRange( Struct( "report", UBInt16("length"), Byte("ID"), FlagsEnum(Byte("types"), feature=4, output=2, input=1), PascalString("name", length_field=Byte("length"), encoding="utf8"), Array( lambda ctx: ctx.length - (len(ctx.name) + 1) - 4, BitStruct( "serialization", BitField("length", 6), Enum(BitField("type", 2), utf8=0, Uint=1, Int=2, Float=3))))) def hexstring_to_bytearray(string): return bytearray([int(pair.strip(','), 16) for pair in string.split(" ")]) def serialize(data): if hasattr(data[0], 'version'): return admin_report.build(data[0]) + HID_report.build(data[1:]) return HID_report.build(data) def deserialize(_bytes): if ' ' in _bytes: