def convert_fields_to_struct_fields(fields, verbose=False): total_bits = 0 struct_fields = [] for identifier, op, options in fields: s_field = None if op == "&": bits = len(options) description = f"{bits}-bit bitfield" f_enum = enum.IntFlag( identifier, [(op, 1 << i) for (i, op) in enumerate(options)] ) s_field = identifier / construct.FlagsEnum( construct.BitsInteger(bits), f_enum ) elif op == "|": bits = math.ceil(math.log2(len(options))) description = f"{bits}-bit enum" if set(options) == {True, False}: s_field = identifier / construct.Flag else: f_enum = enum.IntEnum( identifier, [(op, 1 << i) for (i, op) in enumerate(options)] ) s_field = identifier / construct.Enum( construct.BitsInteger(bits), f_enum ) struct_fields.append(s_field) if verbose: print(f"{identifier:15}: {description} ({len(options)} options)") assert bits == s_field.sizeof() total_bits += bits if verbose: print(f"Total bits: {total_bits}") return (struct_fields, total_bits)
""" return bytes(~b & 0xFF for b in data)[::-1] # fmt: off Toif = c.Struct( "magic" / c.Const(b"TOI"), "format" / c.Enum(c.Byte, full_color=b"f", grayscale=b"g"), "width" / c.Int16ul, "height" / c.Int16ul, "data" / c.Prefixed(c.Int32ul, c.GreedyBytes), ) VendorTrust = c.Transformed( c.BitStruct( "reserved" / c.Default(c.BitsInteger(9), 0), "show_vendor_string" / c.Flag, "require_user_click" / c.Flag, "red_background" / c.Flag, "delay" / c.BitsInteger(4), ), _transform_vendor_trust, 2, _transform_vendor_trust, 2) VendorHeader = c.Struct( "_start_offset" / c.Tell, "magic" / c.Const(b"TRZV"), "_header_len" / c.Padding(4), "expiry" / c.Int32ul, "version" / c.Struct( "major" / c.Int8ul, "minor" / c.Int8ul, ),
rotate_bytes(obj, ctx.header.bytes_rotation, ctx.header.bytes_rotation, inverse)) PermalinkBinary = construct.FocusedSeq( "fields", schema_version=construct.Const(_CURRENT_SCHEMA_VERSION, construct.Byte), fields=construct.RawCopy( construct.Aligned( 3, construct.Struct( header=construct.BitStruct( has_seed_hash=construct.Rebuild( construct.Flag, construct.this._.seed_hash != None), bytes_rotation=construct.Rebuild( construct.BitsInteger(7), lambda ctx: single_byte_hash(ctx._.generator_params) >> 1, )), seed_hash=construct.If(construct.this.header.has_seed_hash, construct.Bytes(5)), randovania_version=construct.Bytes(4), # short git hash generator_params=construct.ExprAdapter( construct.Prefixed(construct.VarInt, construct.GreedyBytes), # parsing decoder=create_rotator(inverse=True), # building encoder=create_rotator(inverse=False), ), ))),
_CLEAR_MEMORY = 0x52 _MODEL_STRUCT = construct.Struct( construct.Const(b'\x77\x42'), construct.Byte, construct.Byte, ) _DATETIME_STRUCT = construct.Struct( 'day' / construct.Int16ul, 'minute' / construct.Byte, 'hour' / construct.Byte, ) _DAY_BITSTRUCT = construct.BitStruct( 'year' / construct.BitsInteger(7), 'month' / construct.BitsInteger(4), 'day' / construct.BitsInteger(5), ) _READING_COUNT_STRUCT = construct.Struct( 'count' / construct.Int16ul, construct.Int16ul, ) _READING_SELECTION_STRUCT = construct.Struct( 'record_id' / construct.Int16ul, construct.Const(b'\x00\x00'), ) _MEAL_FLAG = {
) def JointData(num): return c2.Float32l[num] SequenceNumber = SM_Integer TriState = SM_Integer Time = SM_Float ValidFields = c2.BitStruct('time' / c2.Flag, 'position' / c2.Flag, 'velocity' / c2.Flag, 'accelerations' / c2.Flag, 'reserved' / c2.BitsInteger(28)) GenericBody = c2.Struct( # use optional here, as body may be zero-length c2.GreedyRange('data' / c2.Int8ub)) GenericBody = c2.GreedyRange('data' / c2.Int8ub) # generic simple message GenericMessage = c2.Struct('Header' / Header, 'body' / c2.Renamed(GenericBody), c2.Terminated) PingBody = c2.Struct('joint_data' / JointData(10)) Ping = c2.Struct('Header' / Header, 'body' / c2.Renamed(PingBody), c2.Terminated)
def LEBitsInteger(n): return ct.ByteSwapped(ct.BitsInteger(n))
# fmt: off Toif = c.Struct( "magic" / c.Const(b"TOI"), "format" / c.Enum(c.Byte, full_color=b"f", grayscale=b"g"), "width" / c.Int16ul, "height" / c.Int16ul, "data" / c.Prefixed(c.Int32ul, c.GreedyBytes), ) VendorTrust = c.Transformed( c.BitStruct( "reserved" / c.Padding(9), "show_vendor_string" / c.Flag, "require_user_click" / c.Flag, "red_background" / c.Flag, "delay" / c.BitsInteger(4), ), bytes_not, 2, bytes_not, 2) VendorHeader = c.Struct( "_start_offset" / c.Tell, "magic" / c.Const(b"TRZV"), "_header_len" / c.Padding(4), "expiry" / c.Int32ul, "version" / c.Struct( "major" / c.Int8ul, "minor" / c.Int8ul, ), "vendor_sigs_required" / c.Int8ul, "vendor_sigs_n" / c.Rebuild(c.Int8ul, c.len_(c.this.pubkeys)), "vendor_trust" / VendorTrust, "reserved" / c.Padding(14),
_CLEAR_MEMORY = 0x52 _MODEL_STRUCT = construct.Struct( model=construct.Int16ul, unknown_1=construct.Byte, unknown_2=construct.Byte, ) _DATETIME_STRUCT = construct.Struct( day=construct.Int16ul, minute=construct.Byte, hour=construct.Byte, ) _DAY_BITSTRUCT = construct.BitStruct( year=construct.BitsInteger(7), month=construct.BitsInteger(4), day=construct.BitsInteger(5), ) _READING_COUNT_STRUCT = construct.Struct( count=construct.Int16ul, unknown=construct.Int16ul, ) _READING_SELECTION_STRUCT = construct.Struct( record_id=construct.Int16ul, const=construct.Const(b"\x00\x00"), ) _MEAL_FLAG = {
lambda ctx: int(ctx.fcf.dst_addressing_mode), { int(addressing_mode_t.SHORT): short_addr_t, int(addressing_mode_t.LONG): long_addr_t, }), "src_addr" / ct.If( lambda ctx: is_address_present(ctx.fcf.src_addressing_mode), ct.Struct( "pan_id" / ct.IfThenElse( lambda ctx: ctx._.fcf.pan_id_comp and is_address_present( ctx._.fcf.dst_addressing_mode), ct.Computed(ct.this._.dst_addr.pan_id), ct.Hex(ct.Int16ul)), "addr" / ct.Switch( lambda ctx: int(ctx._.fcf.src_addressing_mode), { int(addressing_mode_t.SHORT): ct.Hex(ct.Int16ul), int(addressing_mode_t.LONG): ct.Hex(ct.Int64ul) }))), ) mpdu_t = ct.Struct( "mac" / mac_header_t, "pdu_offset" / ct.Tell, "pdu" / ct.ExprAdapter(ct.HexDump(ct.GreedyBytes), ct.obj_[:-2], ct.obj_ + "AA"), ct.Seek(-2, ct.io.SEEK_CUR), "fcs_offset" / ct.Tell, ct.If(ct.this.pdu_offset > ct.this.fcs_offset, ct.Error), "fcs" / ct.Hex(ct.Int16ul)) phr_t = ct.BitStruct("reserved" / ct.Bit, "size" / ct.BitsInteger(7)) frame_t = ct.Struct("phr" / phr_t, "mpdu" / mpdu_t # warn if phr.size != len(mpdu) )
delta_table.append((-delta) & 0xFFFFFFFF) delta_table.append((delta + (code >> 5))) return delta_table ########################## # # Construct declaration # ########################## # # Sound Flags # gdv_soundflags = construct.BitStruct( construct.Padding(4), construct.FlagsEnum("audio_coding" / construct.BitsInteger(1), PCM = 0x00, DPCM = 0x01), construct.FlagsEnum("sample_width" / construct.BitsInteger(1), BIT_8 = 0x00, BIT_16 = 0x01), construct.FlagsEnum("audio_channels" / construct.BitsInteger(1), MONO = 0x00, STEREO = 0x01), construct.FlagsEnum("audio_present" / construct.BitsInteger(1), AUDIO_NOT_PRESENT = 0x00, AUDIO_PRESENT = 0x01), construct.Padding(8), ) # # Image type # gdv_imagetype = construct.BitStruct( construct.Padding(5), construct.Enum("video_depth" / construct.BitsInteger(3), PIXEL_8_BITS = 0x01, PIXEL_15_BITS = 0x02, PIXEL_16_BITS = 0x03,
# typedef struct Inode_Struct { # InodeType type :1; # int name_len :6; # int padding: 1; # uint16_t size; # uint32_t parent; # uint32_t oid; # uint8_t name[32]; # uint8_t data[CHUNK_SIZE - 44]; # } __attribute((packed)) Inode_t; Inode = construct.Struct( 'bits' / construct.BitStruct('type' / construct.Flag, "name_len" / construct.BitsInteger(6), construct.Padding(1)), "size" / construct.Int16ul, 'parent' / construct.Int32ul, 'oid' / construct.Int32ul, 'name' / construct.String(length=32), 'data' / construct.String(length=84), ) # typedef struct Data_Struct { # uint16_t seq; # uint32_t oid; # uint8_t data[CHUNK_SIZE-8]; # } __attribute((packed)) Data_t; Dnode = construct.Struct( 'seq' / construct.Int16ul,
_CLEAR_MEMORY = 0x52 _MODEL_STRUCT = construct.Struct( construct.Const(b"\x77\x42"), construct.Byte, construct.Byte, ) _DATETIME_STRUCT = construct.Struct( "day" / construct.Int16ul, "minute" / construct.Byte, "hour" / construct.Byte, ) _DAY_BITSTRUCT = construct.BitStruct( "year" / construct.BitsInteger(7), "month" / construct.BitsInteger(4), "day" / construct.BitsInteger(5), ) _READING_COUNT_STRUCT = construct.Struct( "count" / construct.Int16ul, construct.Int16ul, ) _READING_SELECTION_STRUCT = construct.Struct( "record_id" / construct.Int16ul, construct.Const(b"\x00\x00"), ) _MEAL_FLAG = {
class TestContainer(DataclassMixin): a: int = csfield(cs.BitsInteger(7)) b: int = csfield(cs.Bit) c: int = csfield(cs.BitsInteger(8))
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))
import math import itertools import construct values = {} for value, chs in enumerate(itertools.product("bcdfghjklmnprstvwxz", "aeiou")): values[value] = "".join(chs) inv_values = {chs: value for (value, chs) in values.items()} value_bits = int(math.log2(max(values))) # not ceil! value_bint = construct.BitsInteger(value_bits) value_enc_len = max(len(chs) for chs in inv_values) def to_shortcode(bits: bytes) -> str: acc = [] for start in range(0, len(bits), value_bits): slice = bits[start : start + value_bits].ljust(value_bits, b"\x00") chs = values[value_bint.parse(slice)] if acc and chs == acc[-1][0]: acc[-1][1] += 1 else: acc.append([chs, 1, value]) return "".join((s * n if n == 1 or n > 9 else f"{n}{s}") for (s, n, v) in acc) def from_shortcode(shortcode: str) -> bytes: bits = [] i = 0 n = 1
import construct accelerometer_data = construct.Struct("accel_x" / construct.Int16sl, "accel_y" / construct.Int16sl, "accel_z" / construct.Int16sl) gyroscope_data = construct.BitStruct("gyro_roll" / construct.BitsInteger(24), "gyro_yaw" / construct.BitsInteger(24), "gyro_pitch" / construct.BitsInteger(24)) magnet_data = construct.Struct(construct.Padding(6)) touchscreen_coords_data = construct.BitStruct( "touch_pad" / construct.Bit, "touch_extra" / construct.BitsInteger(3), "touch_value" / construct.BitsInteger(12)) touchscreen_points_data = construct.Struct( "coords" / construct.Array(2, touchscreen_coords_data)) touchscreen_data = construct.Struct( "points" / construct.Array(10, touchscreen_points_data)) input_data = construct.Struct( "sequence_id" / construct.Int16ub, "buttons" / construct.Int16ub, "power_status" / construct.Int8ub, "battery_charge" / construct.Int8ub, "left_stick_x" / construct.Int16ub, "left_stick_y" / construct.Int16ub, "right_stick_x" / construct.Int16ub, "right_stick_y" / construct.Int16ub, "audio_volume" / construct.Int8ub, construct.Embedded(accelerometer_data), construct.Embedded(gyroscope_data), construct.Embedded(magnet_data), construct.Embedded(touchscreen_data), "unkown_0" / construct.BytesInteger(4), "extra_buttons" / construct.Int8ub, "unknown_1" / construct.BytesInteger(46), "fw_version_neg" / construct.Int8ub)