Structure Serializer
Network packet serializer module based on structures.
- class easynetwork.serializers.struct.StructSerializer
Bases:
AbstractStructSerializer[tuple[Any, …],tuple[Any, …]]Generic class to handle a
tupleof data with astruct.Structobject.Example
>>> s = StructSerializer(">ii") >>> data = s.serialize((10, 20)) >>> data b'\x00\x00\x00\n\x00\x00\x00\x14' >>> s.deserialize(data) (10, 20)
Note
If the endianness is not specified, the network byte-order is used:
>>> s = StructSerializer("qq") >>> s.struct.format '!qq'
- final iter_values(packet: tuple[Any, ...], /) tuple[Any, ...]
Returns an object suitable for
struct.Struct.pack().See
serialize()for details.
- easynetwork.serializers.struct._T_NamedTuple
Type:
TypeVarInvariant
TypeVarbound totyping.NamedTuple.
- class easynetwork.serializers.struct.NamedTupleStructSerializer
Bases:
AbstractStructSerializer[_T_NamedTuple,_T_NamedTuple]Generic class to handle a named tuple with a
struct.Structobject.Accepts classes created directly from
collections.namedtuple()factory:>>> import collections >>> Point = collections.namedtuple("Point", ("x", "y"))
…or declared with
typing.NamedTuple:from typing import NamedTuple class Point(NamedTuple): x: int y: int
They are used like this:
>>> s = NamedTupleStructSerializer(Point, {"x": "i", "y": "i"}, format_endianness=">") >>> s.struct.format '>ii' >>> data = s.serialize(Point(x=10, y=20)) >>> data b'\x00\x00\x00\n\x00\x00\x00\x14' >>> s.deserialize(data) Point(x=10, y=20)
Note
If the endianness is not specified, the network byte-order is used:
>>> s = NamedTupleStructSerializer(Point, {"x": "i", "y": "i"}) >>> s.struct.format '!ii'
- __init__(namedtuple_cls: type[_T_NamedTuple], field_formats: SupportsKeysAndGetItem[str, str], format_endianness: str = '', encoding: str | None = 'utf-8', unicode_errors: str = 'strict', strip_string_trailing_nul_bytes: bool = True, *, debug: bool = False) None
- Parameters:
namedtuple_cls (type[_T_NamedTuple]) – A named tuple type.
field_formats (SupportsKeysAndGetItem[str, str]) – A mapping of string format for the namedtuple_cls fields.
format_endianness (str) – The endianness character. Defaults to empty string.
encoding (str | None) – String fields encoding. Can be disabled by setting it to
None.unicode_errors (str) – Controls how encoding errors are handled. Ignored if encoding is set to
None.strip_string_trailing_nul_bytes (bool) – If True (the default), removes
\0characters at the end of a string field.debug (bool) – If
True, add information toDeserializeErrorvia theerror_infoattribute.
See also
- final iter_values(packet: _T_NamedTuple) _T_NamedTuple
Returns the named tuple to pack using
struct.Struct.pack().In most case, this method will directly return packet.
If there are string fields and encoding is not
None, this method will return a shallow copy of the named tuple with the encoded strings.Example
The named tuple:
>>> from typing import NamedTuple >>> class Person(NamedTuple): ... name: str ... age: int
In application:
>>> s = NamedTupleStructSerializer(Person, {"name": "10s", "age": "I"}) >>> s.iter_values(Person(name="John", age=20)) Person(name=b'John', age=20)
- Parameters:
packet (_T_NamedTuple) – The namedtuple_cls instance.
- Returns:
a namedtuple_cls instance.
- Return type:
_T_NamedTuple
- final from_tuple(packet_tuple: tuple[Any, ...], /) _T_NamedTuple
Constructs the named tuple from the given tuple.
If there are string fields and encoding is not
None, their values will be decoded.If strip_string_trailing_nul_bytes was set to
True, the"\0"characters at the end of the string fields, added for padding, will be removed.Example
The named tuple:
>>> from typing import NamedTuple >>> class Person(NamedTuple): ... name: str ... age: int
In application:
>>> s = NamedTupleStructSerializer(Person, {"name": "10s", "age": "I"}) >>> t = s.struct.unpack(b'John\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14') >>> t (b'John\x00\x00\x00\x00\x00\x00', 20) >>> s.from_tuple(t) Person(name='John', age=20)
Abstract Structure Interface
- class easynetwork.serializers.struct.AbstractStructSerializer
Bases:
FixedSizePacketSerializer[_T_SentDTOPacket,_T_ReceivedDTOPacket]A base class for structured data.
To use the serializer directly without additional layers, it is possible to create a subclass with the minimal requirements:
>>> class MyStructSerializer(AbstractStructSerializer): ... __slots__ = () ... def iter_values(self, packet): ... return packet ... def from_tuple(self, packet_tuple): ... return packet_tuple ...
And then:
>>> s = MyStructSerializer(">ii") >>> data = s.serialize((10, 20)) >>> data b'\x00\x00\x00\n\x00\x00\x00\x14' >>> s.deserialize(data) (10, 20)
This is an abstract class in order to allow you to include fancy structures like
ctypes.Structuresubclasses.Note
If the endianness is not specified, the network byte-order is used:
>>> s = MyStructSerializer("qq") >>> s.struct.format '!qq'
See also
StructSerializerDefault implementation without additional layers.
NamedTupleStructSerializerSpecialization for named tuple instances.
- __init__(format: str, *, debug: bool = False) None
- Parameters:
format (str) – The
struct.Structformat definition string.debug (bool) – If
True, add information toDeserializeErrorvia theerror_infoattribute.
- abstractmethod iter_values(packet: _T_SentDTOPacket, /) Iterable[Any]
Returns an object suitable for
struct.Struct.pack().See
serialize()for details.
- abstractmethod from_tuple(packet_tuple: tuple[Any, ...], /) _T_ReceivedDTOPacket
Finishes the packet deserialization by parsing the tuple obtained by
struct.Struct.unpack().See
deserialize()for details.
- final serialize(packet: _T_SentDTOPacket) bytes
Returns the structured data representation of the Python object packet.
Roughly equivalent to:
def serialize(self, packet): to_pack = self.iter_values(packet) return self.struct.pack(*to_pack)
- Parameters:
packet (_T_SentDTOPacket) – The Python object to serialize.
- Returns:
a byte sequence.
- Return type:
- final deserialize(data: bytes) _T_ReceivedDTOPacket
Creates a Python object representing the structure from data.
Roughly equivalent to:
def deserialize(self, data): unpacked_data = self.struct.unpack(data) return self.from_tuple(unpacked_data)
- Parameters:
data (bytes) – The byte sequence to deserialize.
- Raises:
DeserializeError – A
struct.errorhave been raised.- Returns:
the deserialized Python object.
- Return type:
_T_ReceivedDTOPacket
- property struct: struct.Struct
The underlying
struct.Structinstance. Read-only attribute.