Core API: Integers and Floats¶
- construct.FormatField(endianity, format)¶
Field that uses struct module to pack and unpack CPU-sized integers and floats and booleans. This is used to implement most Int* Float* fields, but for example cannot pack 24-bit integers, which is left to
BytesInteger
class. For booleans I also recommend using Flag class instead.See struct module documentation for instructions on crafting format strings.
Parses into an integer or float or boolean. Builds from an integer or float or boolean into specified byte count and endianness. Size is determined by struct module according to specified format string.
- Parameters:
endianity – string, character like: < > =
format – string, character like: B H L Q b h l q e f d ?
- Raises:
StreamError – requested reading negative amount, could not read enough bytes, requested writing different amount than actual data, or could not write all bytes
FormatFieldError – wrong format string, or struct.(un)pack complained about the value
Example:
>>> d = FormatField(">", "H") or Int16ub >>> d.parse(b"\x01\x00") 256 >>> d.build(256) b"\x01\x00" >>> d.sizeof() 2
- construct.BytesInteger(length, signed=False, swapped=False)¶
Field that packs integers of arbitrary size. Int24* fields use this class.
Parses into an integer. Builds from an integer into specified byte count and endianness. Size is specified in ctor.
Analog to
BitsInteger
which operates on bits. In fact:BytesInteger(n) <--> Bitwise(BitsInteger(8*n)) BitsInteger(8*n) <--> Bytewise(BytesInteger(n))
Byte ordering refers to bytes (chunks of 8 bits) so, for example:
BytesInteger(n, swapped=True) <--> Bitwise(BitsInteger(8*n, swapped=True))
- Parameters:
length – integer or context lambda, number of bytes in the field
signed – bool, whether the value is signed (two’s complement), default is False (unsigned)
swapped – bool or context lambda, whether to swap byte order (little endian), default is False (big endian)
- Raises:
StreamError – requested reading negative amount, could not read enough bytes, requested writing different amount than actual data, or could not write all bytes
IntegerError – length is negative or zero
IntegerError – value is not an integer
IntegerError – number does not fit given width and signed parameters
Can propagate any exception from the lambda, possibly non-ConstructError.
Example:
>>> d = BytesInteger(4) or Int32ub >>> d.parse(b"abcd") 1633837924 >>> d.build(1) b'\x00\x00\x00\x01' >>> d.sizeof() 4
- construct.BitsInteger(length, signed=False, swapped=False)¶
Field that packs arbitrarily large (or small) integers. Some fields (Bit Nibble Octet) use this class. Must be enclosed in
Bitwise
context.Parses into an integer. Builds from an integer into specified bit count and endianness. Size (in bits) is specified in ctor.
Analog to
BytesInteger
which operates on bytes. In fact:BytesInteger(n) <--> Bitwise(BitsInteger(8*n)) BitsInteger(8*n) <--> Bytewise(BytesInteger(n))
Note that little-endianness is only defined for multiples of 8 bits.
Byte ordering (i.e. swapped parameter) refers to bytes (chunks of 8 bits) so, for example:
BytesInteger(n, swapped=True) <--> Bitwise(BitsInteger(8*n, swapped=True))
Swapped argument was recently fixed. To obtain previous (faulty) behavior, you can use ByteSwapped, BitsSwapped and Bitwise in whatever particular order (see examples).
- Parameters:
length – integer or context lambda, number of bits in the field
signed – bool, whether the value is signed (two’s complement), default is False (unsigned)
swapped – bool or context lambda, whether to swap byte order (little endian), default is False (big endian)
- Raises:
StreamError – requested reading negative amount, could not read enough bytes, requested writing different amount than actual data, or could not write all bytes
IntegerError – length is negative or zero
IntegerError – value is not an integer
IntegerError – number does not fit given width and signed parameters
IntegerError – little-endianness selected but length is not multiple of 8 bits
Can propagate any exception from the lambda, possibly non-ConstructError.
Examples:
>>> d = Bitwise(BitsInteger(8)) or Bitwise(Octet) >>> d.parse(b"\x10") 16 >>> d.build(255) b'\xff' >>> d.sizeof() 1
Obtaining other byte or bit orderings:
>>> d = BitsInteger(2) >>> d.parse(b'\x01\x00') # Bit-Level Big-Endian 2 >>> d = ByteSwapped(BitsInteger(2)) >>> d.parse(b'\x01\x00') # Bit-Level Little-Endian 1 >>> d = BitsInteger(16) # Byte-Level Big-Endian, Bit-Level Big-Endian >>> d.build(5 + 19*256) b'\x00\x00\x00\x01\x00\x00\x01\x01\x00\x00\x00\x00\x00\x01\x00\x01' >>> d = BitsInteger(16, swapped=True) # Byte-Level Little-Endian, Bit-Level Big-Endian >>> d.build(5 + 19*256) b'\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x01\x00\x00\x01\x01' >>> d = ByteSwapped(BitsInteger(16)) # Byte-Level Little-Endian, Bit-Level Little-Endian >>> d.build(5 + 19*256) b'\x01\x00\x01\x00\x00\x00\x00\x00\x01\x01\x00\x00\x01\x00\x00\x00' >>> d = ByteSwapped(BitsInteger(16, swapped=True)) # Byte-Level Big-Endian, Bit-Level Little-Endian >>> d.build(5 + 19*256) b'\x01\x01\x00\x00\x01\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00'
- construct.VarInt()¶
VarInt encoded unsigned integer. Each 7 bits of the number are encoded in one byte of the stream, where leftmost bit (MSB) is unset when byte is terminal. Scheme is defined at Google site related to Protocol Buffers.
Can only encode non-negative numbers.
Parses into an integer. Builds from an integer. Size is undefined.
- Raises:
StreamError – requested reading negative amount, could not read enough bytes, requested writing different amount than actual data, or could not write all bytes
IntegerError – given a negative value, or not an integer
Example:
>>> VarInt.build(1) b'\x01' >>> VarInt.build(2**100) b'\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x04'
- construct.ZigZag()¶
ZigZag encoded signed integer. This is a variant of VarInt encoding that also can encode negative numbers. Scheme is defined at Google site related to Protocol Buffers.
Can also encode negative numbers.
Parses into an integer. Builds from an integer. Size is undefined.
- Raises:
StreamError – requested reading negative amount, could not read enough bytes, requested writing different amount than actual data, or could not write all bytes
IntegerError – given not an integer
Example:
>>> ZigZag.build(-3) b'\x05' >>> ZigZag.build(3) b'\x06'