Source code for hbutils.binary.buffer

"""
This module provides functionality for reading and writing fixed-size binary buffers.

It defines a custom binary I/O type that handles byte buffers of a specified size,
with automatic padding when writing data shorter than the buffer size.
"""

from typing import BinaryIO, Union

from .base import CIOType

__all__ = [
    'CBufferType',
    'c_buffer',
]


[docs] class CBufferType(CIOType): """ A binary I/O type for handling fixed-size byte buffers. This class provides methods to read and write byte data with a predetermined size. When writing data shorter than the buffer size, it automatically pads with null bytes. """
[docs] def __init__(self, size: int): """ Constructor of :class:`CBufferType`. :param size: Size of the buffer in bytes. :type size: int """ self.__size = size
@property def size(self) -> int: """ Get the size of the buffer. :return: Size of the buffer in bytes. :rtype: int """ return self.__size
[docs] def read(self, file: BinaryIO) -> bytes: """ Read bytes value from a binary file. :param file: Binary file object to read from. ``io.BytesIO`` is supported as well. :type file: BinaryIO :return: Bytes value read from the file with the specified buffer size. :rtype: bytes """ return file.read(self.__size)
[docs] def write(self, file: BinaryIO, val: Union[bytearray, bytes]): """ Write bytes value to binary IO object. If the length of the provided value is less than the buffer size, null bytes (``\\x00``) will be appended to reach the specified size. :param file: Binary file object to write to. ``io.BytesIO`` is supported as well. :type file: BinaryIO :param val: Bytes value to write. Must be of type bytearray or bytes. :type val: Union[bytearray, bytes] :raises TypeError: If val is not a bytearray or bytes object. :raises ValueError: If the length of val exceeds the buffer size. """ if not isinstance(val, (bytearray, bytes)): raise TypeError(f'Bytearray or bytes expected, but {repr(val)}.') if not (0 <= len(val) <= self.__size): raise ValueError(f'Size is expected to be no more than {self.__size}, but actual length is {len(val)}.') fval = val[:self.__size] fval = fval + b'\x00' * (self.__size - len(fval)) file.write(fval)
[docs] def c_buffer(size: int) -> CBufferType: """ Create a buffer type for reading and writing bytes with a given size. This function returns a :class:`CBufferType` object that can be used to read and write fixed-size byte buffers. When writing, if the data is shorter than the specified size, it will be padded with null bytes. :param size: Size of the buffer in bytes. :type size: int :return: A :class:`CBufferType` object configured with the specified size. :rtype: CBufferType Examples:: >>> import io >>> from hbutils.binary import c_buffer >>> >>> # Reading example >>> with io.BytesIO(b'\\xde\\xad\\xbe\\xef\\x00\\x12\\x34\\x56\\x78\\x00') as file: ... print(c_buffer(1).read(file)) ... print(c_buffer(2).read(file)) ... print(c_buffer(3).read(file)) ... print(c_buffer(4).read(file)) b'\\xde' b'\\xad\\xbe' b'\\xef\\x00\\x12' b'4Vx\\x00' >>> >>> # Writing example >>> with io.BytesIO() as file: ... c_buffer(1).write(file, b'\\xde') ... c_buffer(2).write(file, b'\\xad\\xbe') ... c_buffer(3).write(file, b'\\xef\\x00\\x12') ... c_buffer(4).write(file, b'4Vx') # length is 3, will be padded to 4 ... print(file.getvalue()) b'\\xde\\xad\\xbe\\xef\\x00\\x124Vx\\x00' """ return CBufferType(size)