Source code for runtimepy.primitives.string

"""
A module implementing integer-prefixed string reading and writing.
"""

# built-in
from typing import BinaryIO as _BinaryIO

# internal
from runtimepy.primitives.base import Primitive as _Primitive
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.int import Uint16 as _Uint16


[docs] class StringPrimitive: """A class implementing a string-primitive interface.""" def __init__( self, value: str = "", kind: type[_Primitive[int]] = _Uint16, byte_order: _ByteOrder = _DEFAULT_BYTE_ORDER, ) -> None: """Initialize this string primitive.""" assert kind.kind.is_integer self._value = value self._size = kind(value=len(self._value)) self.byte_order = byte_order def __str__(self) -> str: """Get this instance as a string.""" return self._value def __hash__(self) -> int: """Get a hash for this instance.""" return hash(self._value) def __eq__(self, other) -> bool: """Determine if this instance is equivalent to another.""" return self._value == str(other)
[docs] @staticmethod def from_stream( stream: _BinaryIO, kind: type[_Primitive[int]] = _Uint16, byte_order: _ByteOrder = _DEFAULT_BYTE_ORDER, ) -> "StringPrimitive": """Create a new string primitive from a stream.""" result = StringPrimitive(kind=kind, byte_order=byte_order) result.read(stream) return result
@property def value(self) -> str: """Get the value of this string.""" return self._value
[docs] def set(self, value: str) -> None: """Set a new value for the underlying string.""" self._value = value self._size.value = len(self._value)
@property def size(self) -> int: """Get the overall size of this string primitive.""" return self._size.value + self._size.size
[docs] def write(self, stream: _BinaryIO) -> int: """Write this string's size and value to the stream.""" size = self._size.to_stream(stream, byte_order=self.byte_order) return size + stream.write(self._value.encode())
[docs] def read(self, stream: _BinaryIO) -> str: """Read a string from the stream.""" self._value = stream.read( self._size.from_stream(stream, byte_order=self.byte_order) ).decode() return self._value