Fields
Fields
Fields are the primitive objects that hold data, and can be converted to (and from) bytes
>>> from hydration import * >>> f = UInt16(1512) >>> bytes(f) b'\xe8\x05' >>> UInt16().from_bytes(b'\xe8\x05') UInt16(1512)
Scalars
Scalars are simple fields that represent low-level primitive data types:
| Scalar class | Size |
|---|---|
UInt8 |
1 byte |
UInt16 |
2 bytes |
UInt32 |
4 bytes |
UInt64 |
8 bytes |
Int8 |
1 byte |
Int16 |
2 bytes |
Int32 |
4 bytes |
Int64 |
8 bytes |
Float |
4 bytes |
Double |
8 bytes |
Validation
Fields have a validator keyword argument, which allows you catch errors during early
stages of the object creation, whether by construction or from_bytes
from hydration import * range_ok = UInt8(validator=range(3)) list_ok = UInt8(validator=[10, 20])
>>> range_ok.value = 4 ValueError: Given value 4 is not in range(0, 3) >>> list_ok.value = 5 ValueError: Given value 5 is not in {0, 10, 20}
Endianness
You can control the endianness of scalars that are longer than 1 byte:
>>> bytes(UInt32(3, endianness=BigEndian)) b'\x00\x00\x00\x03' >>> bytes(UInt32(3, endianness=LittleEndian)) b'\x03\x00\x00\x00'
NOTE: The default endianness is that of your architecture, so it might be different on other processor architectures.
Enum
Enums are scalars that makes working with enum.IntEnum easier.
from enum import IntEnum class Color(IntEnum): RED = 1 GREEN = 2 BLUE = 3
By using enums, you get clean, readable code. The constructor receives the class of the Enum and takes care of initialization and validation for you. (The default value is the first enum)
>>> field = Enum(UInt8, Color) >>> field.name 'RED' >>> field.value 1 >>> field.value = 4 ValueError: 4 is not a valid Color
Sequences
Sequences are homogeneous collection of fields or structs, e.g. Array and Vector
Array
Arrays are sequences of constant size
>>> bytes(Array(3, value=[1, 2, 3])) b'\x01\x02\x03'
By default, an Array is a construct of UInt8s, this can be changed.
>>> bytes(Array(3, field_type=UInt16, value=[1, 2, 3])) b'\x01\x00\x02\x00\x03\x00'
Notice that an Array has a fixed size. If the given value doesn't fill the array,
the rest of the scalars will have the default field_type value (usually 0):
>>> print(Array(6, value=(3, 4))) Array(3, 4, 0, 0, 0, 0) >>> print(Array(5, field_type=UInt8(5), value=(3, 4))) Array(3, 4, 5, 5, 5, 5)
Vector
Vectors are sequences of variable size, and can only be used inside a Struct,
so it is documented in docs/struct.md