# -*- coding: utf-8 -*-
"""
Utilities for low-level binary stream and byte manipulation.
"""
__author__ = "Yeremia Gunawan Adhisantoso"
__email__ = "adhisant@tnt.uni-hannover.de"
__license__ = "Clear BSD"
__version__ = "1.0.0"
import typing as t
[docs]
def read_str(
reader: t.BinaryIO,
encoding: str = 'utf-8'
) -> str:
"""
Reads a null-terminated string from a binary reader.
This function reads bytes from the reader until a null byte (b'\\x00') is encountered.
The read bytes are then decoded using the specified encoding.
Parameters
----------
reader : t.BinaryIO
The binary reader to read from.
encoding : str, optional
The encoding to use for decoding the read bytes. Defaults to 'utf-8'.
Returns
-------
str
The decoded string.
"""
string = bytearray()
while True:
c = reader.read(1)
if not c:
break
if c == b'\x00':
break
string += c
return string.decode(encoding)
[docs]
def int2bstr(
val: int,
len_in_byte: int,
order: t.Literal['big', 'little'] = 'big'
) -> bytes:
"""
Converts an integer to a byte string.
Converts an integer to a byte string of a specified length and byte order.
Parameters
----------
val : int
The integer to convert.
len_in_byte : int
The length of the resulting byte string in bytes.
order : {'big', 'little'}, optional
The byte order to use. Defaults to 'big'.
Returns
-------
bytes
The byte string representation of the integer.
Raises
------
ValueError
If the order is not recognized.
TypeError
If val is not an integer.
"""
if order not in ['big', 'little']:
raise ValueError('order not recognized; should be one of (\'big\', \'little\')')
if not isinstance(val, int):
raise TypeError("Type is not python int!")
return val.to_bytes(len_in_byte, order)
[docs]
def bstr2int(
payload: bytes,
order: t.Optional[str] = 'big'
) -> int:
"""
Converts a byte string to an integer.
Parameters
----------
payload : bytes
The byte string to convert.
order : str, optional
The byte order to use (e.g., 'big' or 'little'). Defaults to 'big'.
Returns
-------
int
The integer representation of the byte string.
Raises
------
ValueError
If the order is not recognized or the payload is empty.
"""
if order not in ['big', 'little']:
raise ValueError('order not recognized; should be one of (\'big\', \'little\')')
if len(payload) == 0:
raise ValueError("Invalid data")
return int.from_bytes(payload, order)