예제 #1
0
    class Class(binobj.Struct):
        n_items = fields.UInt16(endian="little")
        items = fields.Array(fields.UInt16(endian="little"), count=n_items)

        @n_items.computes
        def _n_items(self, all_fields):
            return len(all_fields["items"])
예제 #2
0
class SimpleBMPFileHeader(binobj.Struct):
    """A class representing a specific kind of Windows Bitmap file (.bmp).

    For the sake of simplicity this spec assumes the file uses the legacy DIB
    header. Validation will fail if this isn't true, even if the BMP file itself
    is valid.
    """

    magic = fields.Bytes(const=b"BM", discard=True)
    file_size = fields.UInt32()
    _reserved = fields.Bytes(const=b"\0\0\0\0", discard=True)
    pixels_offset = fields.UInt32()

    # Legacy DIB header (BITMAPINFOHEADER)
    header_size = fields.UInt32(const=40, discard=True)
    image_width = fields.Int32()
    image_height = fields.Int32()
    n_color_planes = fields.UInt16(const=1)
    n_bits_per_pixel = fields.UInt16()
    compression_method = fields.UInt32()
    bitmap_size = fields.UInt32()
    v_resolution = fields.Int32()
    h_resolution = fields.Int32()
    n_palette_colors = fields.UInt32()
    n_important_colors = fields.UInt32()
예제 #3
0
class CPIOFileHeader(binobj.Struct):
    magic = fields.UInt16(const=0o070707, discard=True, endian="little")
    device_id = fields.UInt16(default=0, endian="little")
    inumber = fields.UInt16(default=0, endian="little")
    mode = fields.UInt16(default=0o644, endian="little")
    owner_uid = fields.UInt16(default=0, endian="little")
    owner_gid = fields.UInt16(default=0, endian="little")
    n_links = fields.UInt16(default=0, endian="little")
    device_version = fields.UInt16(default=0, endian="little")
    modified_time = fields.Timestamp32(default=_NOW, tz_aware=True, endian="little")
    name_size = fields.UInt16(endian="little")
    file_size = fields.UInt32(endian="little")
    filename = fields.StringZ(encoding="utf-8")
    _filename_padding = fields.Bytes(
        const=b"\0", discard=True, present=lambda f, *_: f["name_size"] % 2
    )
    data = fields.Bytes(size=file_size)

    @name_size.computes
    def _name_size(self, all_fields):
        return len((all_fields["filename"] + "\0").encode("utf-8"))

    @file_size.computes
    def _file_size(self, all_fields):
        return len(all_fields["data"])
예제 #4
0
class BasicPresentStruct(binobj.Struct):
    flags = fields.UInt16(endian="little")
    thing = fields.StringZ(present=lambda f, *_: f["flags"] & 0x8000)
    other_thing = fields.UInt16(const=0x1234, endian="little")

    @flags.computes
    def _flags(self, all_values):
        existing = all_values.get("flags", 0)
        if "thing" in all_values:
            return existing | 0x8000
        return existing
예제 #5
0
class StructWithArgs(binobj.Struct):
    def __init__(self, required, **values):
        super().__init__(**values)
        self.required = required

    field_1 = fields.UInt16(endian="little")
    field_2 = fields.UInt32(endian="big")
예제 #6
0
class FieldsUnionContainer(binobj.Struct):
    data_type = fields.UInt8()
    item = fields.Union(
        fields.StringZ(),
        fields.UInt16(endian="little"),
        load_decider=fields_load_decider,
        dump_decider=fields_dump_decider,
    )
예제 #7
0
파일: wav_test.py 프로젝트: dargueta/binobj
class WAVFormatChunk(binobj.Struct):
    chunk_id = fields.Bytes(const=b"fmt ")
    size = fields.UInt32(const=16, endian="little")
    audio_format = fields.UInt16(endian="little")
    n_channels = fields.UInt16(endian="little")
    sample_rate = fields.UInt32(endian="little")
    byte_rate = fields.UInt32(endian="little")
    block_alignment = fields.UInt16(endian="little")
    bits_per_sample = fields.UInt16(endian="little")

    @byte_rate.computes
    def _byte_rate(self, all_fields):
        return (all_fields["sample_rate"] * all_fields["n_channels"] *
                all_fields["bits_per_sample"] // 8)

    @block_alignment.computes
    def _block_alignment(self, all_fields):
        return all_fields["n_channels"] * all_fields["bits_per_sample"] // 8
예제 #8
0
class CircularReferenceComputedSize(binobj.Struct):
    """A struct with a size field and array that reference each other."""

    count = fields.UInt16(endian="big")
    stuff = fields.Array(fields.StringZ(), count=count)

    @count.computes
    def compute_count(self, all_fields):
        return len(all_fields["stuff"])
예제 #9
0
def test_array__sentinel():
    """Test deserializing a sequence that has a sentinel terminator."""
    def halt(_seq, _str, values, _context, _loaded_fields):
        return values and (values[-1] == 0xDEAD)

    sequence = fields.Array(fields.UInt16(endian="little"), halt_check=halt)

    result = sequence.from_bytes(b"\x00\x00\xff\x00\xad\xde\xff\xff",
                                 exact=False)
    assert result == [0, 0xFF, 0xDEAD]
예제 #10
0
파일: fat_test.py 프로젝트: dargueta/binobj
class FAT12BootSector(binobj.Struct):
    jump = fields.Bytes(const=b"\xeb\x3c\x90")
    oem_name = fields.String(size=8,
                             default="mkdosfs",
                             pad_byte=b" ",
                             encoding="ascii")
    bytes_per_sector = fields.UInt16(default=512)
    sectors_per_cluster = fields.UInt8()
    reserved_sectors = fields.UInt16(default=1)
    num_fats = fields.UInt8(default=2)
    max_root_entries = fields.UInt16(default=240)
    total_logical_sectors_16 = fields.UInt16()
    media_descriptor = fields.UInt8()
    sectors_per_fat = fields.UInt16()
    sectors_per_track = fields.UInt16()
    num_heads = fields.UInt16()
    num_hidden_sectors = fields.UInt32(default=0)
    total_logical_sectors_32 = fields.UInt32()
    drive_number = fields.UInt8()
    _reserved = fields.Bytes(const=b"\0", discard=True)
    _ex_boot_signature = fields.Bytes(const=b"\x29", discard=True)
    volume_id = fields.UInt32(default=lambda: random.randrange(2**32))
    volume_label = fields.String(size=11)
    fs_type = fields.String(size=8,
                            default="FAT12",
                            pad_byte=b" ",
                            encoding="ascii")
    boot_code = fields.Bytes(size=448, default=b"\xcc" * 448)
    boot_signature = fields.Bytes(const=b"\x55\xaa")

    @property
    def total_logical_sectors(self):
        return self.total_logical_sectors_16 or self.total_logical_sectors_32

    @total_logical_sectors.setter
    def total_logical_sectors(self, total_sectors):
        if total_sectors < 1 or total_sectors >= 2**32:
            raise ValueError("Total sectors must be in [1, 2^32). Got: %d" %
                             total_sectors)
        if total_sectors < 65535:
            self.total_logical_sectors_16 = total_sectors
            self.total_logical_sectors_32 = 0
        else:
            self.total_logical_sectors_16 = 0
            self.total_logical_sectors_32 = total_sectors
예제 #11
0
class StringZTestStruct(binobj.Struct):
    header = fields.UInt32()
    string = fields.StringZ()
    trailer = fields.UInt16()
예제 #12
0
 class _BrokenClass(binobj.Struct):
     normal_field = fields.UInt16()
     pep526_field: fields.StringZ
예제 #13
0
        class Class(binobj.Struct):
            n_items = fields.UInt16(endian="little")

            @decorators.validates(n_items)
            def _n_items(self, all_fields):
                pass
예제 #14
0
        class Class(binobj.Struct):
            blah = fields.UInt16(const=1234)

            @blah.computes
            def _blah(self, all_fields):
                return 5678
예제 #15
0
class BasicStructWithArray(binobj.Struct):
    header = fields.String(const="ABC")
    numbers = fields.Array(fields.UInt16(endian="big"), count=2)
    trailer = fields.String(const="XYZ")
예제 #16
0
class BasicStructWithArray(binobj.Struct):
    """A basic structure with a sized array."""

    header = fields.Bytes(const=b"ABC")
    numbers = fields.Array(fields.UInt16(endian="big"), count=2)
    trailer = fields.Bytes(const=b"XYZ")
예제 #17
0
class UnionItemB(binobj.Struct):
    _id = fields.UInt8(const=0x7F)
    other = fields.UInt16(endian="little")