Source code for runtimepy.primitives.serializable.prefixed

"""
A module implementing a variable-size bytes serializable, using an integer
primitive prefix to determine the size of the chunk portion.
"""

# built-in
from typing import BinaryIO as _BinaryIO
from typing import TypeVar

# third-party
from vcorelib.io import BinaryMessage

# internal
from runtimepy.primitives import Primitivelike, UnsignedInt, create
from runtimepy.primitives.byte_order import (
    DEFAULT_BYTE_ORDER as _DEFAULT_BYTE_ORDER,
)
from runtimepy.primitives.byte_order import ByteOrder as _ByteOrder
from runtimepy.primitives.serializable.base import Serializable
from runtimepy.primitives.serializable.fixed import FixedChunk

T = TypeVar("T", bound="PrefixedChunk")


[docs] class PrefixedChunk(Serializable): """A simple integer-prefixed chunk serializable.""" def __init__( self, prefix: UnsignedInt, byte_order: _ByteOrder = _DEFAULT_BYTE_ORDER, chain: Serializable = None, ) -> None: """Initialize this instance.""" super().__init__(byte_order=byte_order, chain=chain) # Validate prefix. assert prefix.kind.is_integer, prefix assert not prefix.kind.signed, prefix self.prefix = prefix self.chunk = FixedChunk(bytes(self.prefix.value)) self._update_size() def __str__(self) -> str: """Get this chunk as a string.""" return str(self.chunk)
[docs] def update(self, data: BinaryMessage, timestamp_ns: int = None) -> int: """Update this serializable from a bytes instance.""" size = self.chunk.update(data, timestamp_ns=timestamp_ns) self.prefix.value = size return self._update_size()
def _update_size(self) -> int: """Update this instance's size.""" assert self.prefix.value == self.chunk.size self.size = self.prefix.kind.size + self.prefix.value return self.size def _copy_impl(self) -> "PrefixedChunk": """Make a copy of this instance.""" result = PrefixedChunk(self.prefix.copy()) # type: ignore result.chunk = self.chunk.copy() return result def __bytes__(self) -> bytes: """Get this serializable as a bytes instance.""" return self.prefix.binary(byte_order=self.byte_order) + bytes( self.chunk ) def _from_stream(self, stream: _BinaryIO, timestamp_ns: int = None) -> int: """Update just this instance from a stream.""" self.chunk.update( stream.read( self.prefix.from_stream(stream, byte_order=self.byte_order) ), timestamp_ns=timestamp_ns, ) return self._update_size()
[docs] @classmethod def create( cls: type[T], prefix: Primitivelike = "uint16", chain: Serializable = None, ) -> T: """Create a prefixed chunk.""" return cls(create(prefix), chain=chain) # type: ignore