jam.utils.codec.composite package
Submodules
Module Contents
Composite type codecs for JAM protocol.
This module provides codecs for composite types including: - Arrays (fixed length) - Options (nullable values) - Vectors (dynamic length) - Dictionaries (key-value pairs) - Bit sequences (sequences of bits) - Dataclasses (structured data)
- class jam.utils.codec.composite.ArrayCodec(length: int)[source]
Bases:
Codec[Sequence[Codable]]Codec for fixed-length arrays/sequences.
Arrays are encoded by concatenating their encoded elements in order. The length is fixed and known at encoding/decoding time.
- MAX_SIZE = 1000
- encode_size(value: Sequence[Codable]) int[source]
Calculate the number of bytes needed to encode the value.
- class jam.utils.codec.composite.ChoiceCodec(choices: ~typing.Dict[str, ~typing.Type[~jam.utils.codec.codable.Codable[~jam.utils.codec.composite.choices.T]]], _ChoiceCodec__tag_codec: ~jam.utils.codec.codec.Codec[int] = <jam.utils.codec.primitives.integers.GeneralCodec object>)[source]
-
Codec for choice/union values.
Choice values are encoded with a tag byte indicating the selected type, followed by the encoded value of that type.
The tag is encoded as a general integer, followed by the encoded value of the selected type. The tag value corresponds to the index of the type in the choices list.
- Parameters:
choices – A list of types that are allowed for this choice. Their index will be used as the tag.
tag_codec – A codec for the tag. Defaults to GeneralCodec() [Best for most cases]. Alternatively we can use FixedInt(U8) for a fixed size tag if choices > 128.
- Raises:
ValueError – If choices list is empty
- __init__(choices: ~typing.Dict[str, ~typing.Type[~jam.utils.codec.codable.Codable[~jam.utils.codec.composite.choices.T]]], _ChoiceCodec__tag_codec: ~jam.utils.codec.codec.Codec[int] = <jam.utils.codec.primitives.integers.GeneralCodec object>)[source]
Initialize ChoiceCodec.
- Parameters:
choices – A list of types that are allowed for this choice. Their index will be used as the tag.
- Raises:
ValueError – If choices list is empty
- encode_size(_value: Dict[str, Codable[T]]) int[source]
Calculate encoded size for value.
- Parameters:
value – Value to encode
- Returns:
Number of bytes needed for encoding
- Raises:
EncodeError – If value type is not in choices list
- encode_into(_value: Dict[str, Codable[T]], buffer: bytearray, offset: int = 0) int[source]
Encode value into buffer.
- Parameters:
value – Value to encode
buffer – Target buffer
offset – Starting offset
- Returns:
Number of bytes written
- Raises:
EncodeError – If value type is not in choices list or buffer is too small
- static decode_from(choices: Dict[str, Type[Codable[T]]], buffer: bytes | bytearray | memoryview, offset: int = 0) Tuple[Dict[str, Codable[T]], int][source]
Decode choice value from buffer.
- Parameters:
choices – List of possible types
buffer – Source buffer
offset – Starting offset
- Returns:
Tuple of (decoded value, bytes read)
- Raises:
DecodeError – If buffer is invalid/too short or tag is invalid
ValueError – If choices list is empty
- class jam.utils.codec.composite.VectorCodec[source]
Bases:
Codec[Sequence[Codable[T]]],Generic[T]Codec for dynamic-length sequences (vectors).
Vectors are encoded with a variable-length prefix indicating size, followed by the concatenated encoded elements.
- encode_size(value: Sequence[Codable[T]]) int[source]
Calculate number of bytes needed to encode vector.
- Parameters:
value – Sequence to encode
- Returns:
Number of bytes needed
- Raises:
EncodeError – If sequence is invalid type or too long
- encode_into(value: Sequence[Codable[T]], buffer: bytearray, offset: int = 0) int[source]
Encode vector into buffer.
- Parameters:
value – Sequence to encode
buffer – Target buffer
offset – Starting position in buffer
- Returns:
Number of bytes written
- Raises:
EncodeError – If sequence invalid or buffer too small
- static decode_from(codable_class: Type[Codable[T]], buffer: bytes | bytearray | memoryview, offset: int = 0, max_length: int = 9223372036854775807) tuple[List[T], int][source]
Decode vector from buffer.
- Parameters:
buffer – Source buffer
offset – Starting position in buffer
- Returns:
Tuple of (decoded list, bytes read)
- Raises:
DecodeError – If buffer too small or invalid encoding
- class jam.utils.codec.composite.DictionaryCodec[source]
Bases:
Codec[Mapping[K,V]],Generic[K,V]Codec for key-value mappings.
Dictionaries are encoded as length-prefixed sequences of key-value pairs, sorted by encoded key bytes for deterministic encoding.
- _encode_pair(key: Codable[K], value: Codable[V], buffer: bytearray, offset: int) Tuple[bytes, int][source]
Encode a single key-value pair into buffer.
- Parameters:
key – Key to encode
value – Value to encode
buffer – Target buffer
offset – Starting position in buffer
- Returns:
Tuple of (key_bytes for sorting, bytes written)
- Raises:
EncodeError – If key/value invalid or buffer too small
- encode_size(value: Mapping[Codable[K], Codable[V]]) int[source]
Calculate number of bytes needed to encode dictionary.
- Parameters:
value – Dictionary to encode
- Returns:
Number of bytes needed
- Raises:
EncodeError – If dictionary contains invalid types
- encode_into(value: Mapping[Codable[K], Codable[V]], buffer: bytearray, offset: int = 0) int[source]
Encode dictionary into buffer.
- Parameters:
value – Dictionary to encode
buffer – Target buffer
offset – Starting position in buffer
- Returns:
Number of bytes written
- Raises:
EncodeError – If dictionary invalid or buffer too small
- static decode_from(key_codable_class: Type[Codable[K]], value_codable_class: Type[Codable[V]], buffer: bytes | bytearray | memoryview, offset: int = 0) Tuple[Dict[K, V], int][source]
Decode dictionary from buffer.
- Parameters:
buffer – Source buffer
offset – Starting position in buffer
- Returns:
Tuple of (decoded dict, bytes read)
- Raises:
DecodeError – If buffer too small or invalid encoding
- class jam.utils.codec.composite.BitSequenceCodec(bit_length: int | None = None, bit_order: Literal['msb', 'lsb'] = 'msb')[source]
-
Codec for encoding and decoding sequences of bits.
Bits are packed into octets (bytes) from least significant to most significant. IMP: It adds bit length encoded as a single byte at the beginning of the sequence ONLY if the bit length is not provided.
- If dynamic length sequence:
Initialise with None
No need to pass bit length to decode_from
- If fixed length sequence:
Initialise with bit length
Pass bit length to decode_from
- encode_size(value: Sequence[bool]) int[source]
Calculate the number of bytes needed to encode the value.
- encode_into(value: Sequence[bool], buffer: bytearray, offset: int = 0) int[source]
Encode the value into the provided buffer at the specified offset.
- static decode_from(buffer: bytes | bytearray | memoryview, offset: int = 0, bit_length: int | None = None, bit_order: Literal['msb', 'lsb'] = 'msb') Tuple[Sequence[bool], int][source]
Decode bit sequence from buffer.
- Parameters:
buffer – Source buffer
offset – Starting offset
bit_length – Expected number of bits (required)
- Returns:
Tuple of (decoded bit list, bytes read)
- Raises:
DecodeError – If buffer too small or bit_length not specified