Complex Types
ByteStruct
- class oser.ByteStruct
- decode(data: bytes, full_data: bytes = b'', context_data: bytes = b'') int
Decode a binary string and return the number of bytes that were decoded.
- Parameters:
data – the data buffer that is decoded.
full_data – the binary data string until the part to be decoded. The user normally does not need to supply this.
context_data – the binary data of the current context. The user normally does not need to supply this.
- Returns:
the number of bytes that were decoded.
- Return type:
- encode(full_data: bytes = b'', context_data: bytes = b'') bytes
Return the encoded binary string.
- Parameters:
full_data – the binary data string until the part to be encoded. The user normally does not need to supply this.
context_data – the binary data of the current context. The user normally does not need to supply this.
- from_dict(data: Dict) None
Fill self with data.
- Parameters:
data – data to be used to fill the calling instance.
- fuzzing_iterator(copy: bool = False) Generator[Any, None, None]
The fuzzing iterator iterates over all combinations of set fuzzing values (
oser.ByteType.set_fuzzing_values()
). If no fuzzing values are set the current struct is yielded.- Parameters:
copy=False – if set to
True
the generated fuzzing values are deep copies of the original. Creating these deep copies is slow. If set toFalse
the original struct is retruned and the generated value must be used immediately since the next generated overwrites the values on the same value.- Yields:
the fuzzing combinations.
- get_byte_size() int
Return the size in bytes.
- Returns:
the length of the byte type in bytes.
- Return type:
- get_size() int
Return the size in bytes.
- Returns:
the length of the byte type in bytes.
- Return type:
- introspect(stop_at: ByteStruct | BitStruct | ByteType | BitType | None = None) str
Return the introspection representation of the object as a string.
- Parameters:
stop_at=None – stop introspection at
stop_at
.
- root() ByteStruct | BitStruct
return root element
- up() ByteStruct | BitStruct
return parent element
Usage:
>>> from oser import ByteStruct, UBInt8, UBInt16, UBInt32, to_hex
>>> class Data(ByteStruct):
... def __init__(self):
... super(Data, self).__init__()
...
... self.a = UBInt8(1)
... self.b = UBInt16(1000)
... self.c = UBInt32(1000000)
>>> instance = Data()
>>> print(instance)
Data():
a: 1 (UBInt8)
b: 1000 (UBInt16)
c: 1000000 (UBInt32)
>>> print(instance.introspect())
- - Data():
0 \x01 a: 1 (UBInt8)
1 \x03 b: 1000 (UBInt16)
2 \xe8
3 \x00 c: 1000000 (UBInt32)
4 \x0f
5 \x42
6 \x40
>>> binary = instance.encode()
>>> print(to_hex(binary))
0| 1| 2| 3| 4| 5| 6
\x01\x03\xE8\x00\x0F\x42\x40
>>> bytes_decoded = instance.decode(binary)
>>> print(bytes_decoded)
7
>>> print(instance)
Data():
a: 1 (UBInt8)
b: 1000 (UBInt16)
c: 1000000 (UBInt32)
BitStruct
oser.BitStruct
is like a oser.ByteStruct
for
bit-aligned types.
Note: The result of oser.OserNode.encode()
is byte-aligned. If the amount of
bits is not a multiple of 8 the last bits are filled with don’t care values.
- class oser.BitStruct
- decode(data: bytes, full_data: bytes = b'', context_data: bytes = b'') int
Decode a binary string and return the number of bytes that were decoded.
- Parameters:
data – the data buffer that is decoded.
full_data – the binary data string until the part to be decoded. The user normally does not need to supply this.
context_data – the binary data of the current context. The user normally does not need to supply this.
- encode(full_data: bytes = b'', context_data: bytes = b'') bytes
Return the encoded binary string.
- Parameters:
full_data – the binary data string until the part to be encoded. The user normally does not need to supply this.
context_data – the binary data of the current context. The user normally does not need to supply this.
- from_dict(data: Dict) None
Fill self with data.
- Parameters:
data – data to be used to fill the calling instance.
- fuzzing_iterator(copy: bool = False) Generator[Any, None, None]
The fuzzing iterator iterates over all combinations of set fuzzing values (
oser.ByteType.set_fuzzing_values()
). If no fuzzing values are set the current struct is yielded.- Parameters:
copy=False – if set to
True
the generated fuzzing values are deep copies of the original. Creating these deep copies is slow. If set toFalse
the original struct is retruned and the generated value must be used immediately since the next generated overwrites the values on the same value.- Yields:
the fuzzing combinations.
- get_byte_size() int
Return the size in bytes.
- Returns:
the length of the byte type in bytes.
- Return type:
- introspect(stop_at: ByteStruct | BitStruct | ByteType | BitType | None = None) str
Return the introspection representation of the object as a string.
- Parameters:
stop_at=None – stop introspection at
stop_at
.
- root() ByteStruct | BitStruct
return root element
- up() ByteStruct | BitStruct
return parent element
Usage:
>>> from oser import BitStruct, Flag, Nibble, BitField, to_hex
>>> class Data(BitStruct):
... def __init__(self):
... super(Data, self).__init__()
...
... self.a = Flag(1)
... self.b = Nibble(5)
... self.c = BitField(value=57, length=6)
...
>>> instance = Data()
>>> print(instance)
Data():
a: 1 (Flag)
b: 5 (Nibble)
c: 57 (BitField(6))
>>> print(instance.introspect())
- - Data():
0.7 1 a: 1 (Flag)
0.6 0 b: 5 (Nibble)
0.5 1
0.4 0
0.3 1
0.2 1 c: 57 (BitField(6))
0.1 1
0.0 1
1.7 0
1.6 0
1.5 1
1.4 x
1.3 x
1.2 x
1.1 x
1.0 x
>>> binary = instance.encode()
>>> print(to_hex(binary))
0| 1
\xAF\x20
>>> bytes_decoded = instance.decode(binary)
>>> print(bytes_decoded)
2
>>> print(instance)
Data():
a: 1 (Flag)
b: 5 (Nibble)
c: 57 (BitField(6))
Enum
An oser.Enum
is most commonly used to give values human readable names.
It can be used in bit-aligned context and byte-aligned context.
- class oser.Enum(prototype: ByteStruct | BitStruct | ByteType | BitType, values: Dict[ByteStruct | BitStruct | ByteType | BitType, Any], value: Any | None = None, strict: bool = False)
An enumeration serializer.
- Parameters:
prototype – the class of the underlying data type.
values – a dictionary of key-value-pairs. The keys are translated into binary data represented by the values.
value=None (object) – the initial value.
strict=False (bool) – If set to True only keys and values appearing in values are accepted. Else all values are accepted.
- decode(data: bytes, full_data: bytes = b'', context_data: bytes = b'') int
Decode a binary string and return the number of bytes that were decoded.
- Parameters:
- Returns:
the number of bytes that were decoded.
- Return type:
- get() Any
Return the value as string representation if possible of the raw value else.
- Returns:
the value as string or raw
- Return type:
- introspect(stop_at: ByteStruct | BitStruct | ByteType | BitType | None = None) str
Return the introspection representation of the object as a string.
- Parameters:
stop_at=None (object) – stop introspection at
stop_at
.
- root() ByteStruct | BitStruct
return root element
- set_fuzzing_values(values: Generator[Any, None, None] | List[Any] | None) None
Set fuzzing values.
- Parameters:
values (iterable) – the values used for fuzzing.
- up() ByteStruct | BitStruct
Return the parent element.
Usage in byte context:
>>> from oser import ByteStruct, Enum, UBInt16, to_hex
>>> class Data(ByteStruct):
... def __init__(self):
... super(Data, self).__init__()
... self.enum = Enum(prototype=UBInt16,
... values={
... "A": 1,
... "B": 2,
... "C": 3,
... "D": 4,
... }, value="C")
...
>>> instance = Data()
>>> print(instance)
Data():
enum: 'C' (UBInt16)
>>> print(instance.introspect())
- - Data():
0 \x00 enum: 3 (UBInt16)
1 \x03
>>> binary = instance.encode()
>>> print(to_hex(binary))
0| 1
\x00\x03
>>> instance.enum.set("B")
>>> print(instance)
Data():
enum: 'B' (UBInt16)
>>> print(instance.introspect())
- - Data():
0 \x00 enum: 2 (UBInt16)
1 \x02
>>> binary = instance.encode()
>>> print(to_hex(binary))
0| 1
\x00\x02
>>> bytes_decoded = instance.decode(binary)
>>> print(bytes_decoded)
2
>>> print(instance)
Data():
enum: 'B' (UBInt16)
>>> instance.decode(b"\x01\x4D")
2
>>> print(instance)
Data():
enum: '333' (UBInt16)
>>> print(instance.introspect())
- - Data():
0 \x01 enum: 333 (UBInt16)
1 \x4d
Usage in bit context:
>>> from oser import BitStruct, Enum, Flag, to_hex
>>> class Data(BitStruct):
... def __init__(self):
... super(Data, self).__init__()
... self.enum = Enum(prototype=Flag,
... values={
... "false" : 0,
... "true" : 1,
... }, value="true")
...
>>> instance = Data()
>>> print(instance)
Data():
enum: 'true' (Flag)
>>> print(instance.introspect())
- - Data():
0.7 1 enum: 1 (Flag)
0.6 x
0.5 x
0.4 x
0.3 x
0.2 x
0.1 x
0.0 x
>>> binary = instance.encode()
>>> print(to_hex(binary))
0
\x80
>>> instance.enum.set("false")
>>> print(instance)
Data():
enum: 'false' (Flag)
>>> print(instance.introspect())
- - Data():
0.7 0 enum: 0 (Flag)
0.6 x
0.5 x
0.4 x
0.3 x
0.2 x
0.1 x
0.0 x
>>> binary = instance.encode()
>>> print(to_hex(binary))
0
\x00
>>> bytes_decoded = instance.decode(binary)
>>> print(bytes_decoded)
1
>>> print(instance)
Data():
enum: 'false' (Flag)
>>> instance.decode(b"\x80")
1
>>> print(instance)
Data():
enum: 'true' (Flag)
>>> print(instance.introspect())
- - Data():
0.7 1 enum: 1 (Flag)
0.6 x
0.5 x
0.4 x
0.3 x
0.2 x
0.1 x
0.0 x