Core API: Tunneling

construct.RawCopy(subcon)

Returns a dict containing both parsed subcon, the raw bytes that were consumed by it, starting and ending offset in the stream, and the amount of bytes. Builds either from raw bytes or a value used by subcon.

Context does contain a dict with data (if built from raw bytes) or with both (if built from value or parsed).

Raises:ConstructError – when building and neither data or value is given

Example:

>>> d = RawCopy(Byte)
>>> d.parse(b"\xff")
Container(data=b'\xff')(value=255)(offset1=0)(offset2=1)(length=1)
>>> d.build(dict(data=b"\xff"))
'\xff'
>>> d.build(dict(value=255))
'\xff'
construct.ByteSwapped(subcon)

Swap the byte order within boundaries of the given subcon. Requires a fixed sized subcon.

Parameters:subcon – the subcon on top of byte swapped bytes

Example:

Int24ul <--> ByteSwapped(Int24ub) <--> BytesInteger(3, swapped=True)
construct.BitsSwapped(subcon)

Swap the bit order within each byte within boundaries of the given subcon. Does NOT require a fixed sized subcon.

Parameters:subcon – the subcon on top of bit swapped bytes

Example:

>>> d = Bitwise(Bytes(8))
>>> d.parse(b"\x01")
'\x00\x00\x00\x00\x00\x00\x00\x01'
>>>> BitsSwapped(d).parse(b"\x01")
'\x01\x00\x00\x00\x00\x00\x00\x00'
construct.Prefixed(lengthfield, subcon, includelength=False)

Parses the length field. Then reads that amount of bytes and parses the subcon using only those bytes. Constructs that consume entire remaining stream are constrained to consuming only the specified amount of bytes. When building, data is prefixed by its length. Optionally, length field can include its own size.

See also

The VarInt encoding should be preferred over Int* fixed sized fields. VarInt is more compact and never overflows.

Parameters:
  • lengthfield – a subcon used for storing the length
  • subcon – the subcon used for storing the value
  • includelength – optional, whether length field should include own size

Example:

>>> Prefixed(VarInt, GreedyRange(Int32ul)).parse(b"\x08abcdefgh")
[1684234849, 1751606885]

>>> PrefixedArray(VarInt, Int32ul).parse(b"\x02abcdefgh")
[1684234849, 1751606885]
construct.Checksum(checksumfield, hashfunc, bytesfunc)

Field that is build or validated by a hash of a given byte range.

Parameters:
  • checksumfield – a subcon field that reads the checksum, usually Bytes(int)
  • hashfunc – a function taking bytes and returning whatever checksumfield takes when building
  • bytesfunc – a function taking context and returning the bytes or object to be hashed, usually like this.rawcopy1.data

Example:

import hashlib
d = Struct(
    "fields" / RawCopy(Struct(
        "a" / Byte,
        "b" / Byte,
    )),
    "checksum" / Checksum(Bytes(64), lambda data: hashlib.sha512(data).digest(), this.fields.data),
)
d.build(dict(fields=dict(value=dict(a=1,b=2))))
-> b'\x01\x02\xbd\xd8\x1a\xb23\xbc\xebj\xd23\xcd'...
construct.Compressed(subcon, encoding, level=None)

Compresses and decompresses underlying stream when processing the subcon. When parsing, entire stream is consumed. When building, puts compressed bytes without marking the end. This construct should be used with Prefixed() or entire stream.

Parameters:
  • subcon – the subcon used for storing the value
  • encoding – any of the module names like zlib/gzip/bzip2/lzma, otherwise any of codecs module bytes<->bytes encodings, usually requires some Python version
  • level – optional, an integer between 0..9, lzma discards it

Example:

Prefixed(VarInt, Compressed(GreedyBytes, "zlib"))