Source code for hbutils.binary.uint

import ctypes
from typing import Dict, BinaryIO, List

from .base import CRangedIntType

__all__ = [
    'CUnsignedIntType',
    'c_uint8', 'c_uint16', 'c_uint32', 'c_uint64',
    'c_ubyte', 'c_ushort', 'c_uint', 'c_ulong', 'c_ulonglong',
]


[docs]class CUnsignedIntType(CRangedIntType): """ Overview: Unsigned int type. """
[docs] def __init__(self, size: int): """ Constructor of :class:`CUnsignedIntType`. :param size: Size of the type. """ self.__size = size CRangedIntType.__init__( self, self.__size, 0, (1 << (8 * self.__size)) - 1, )
[docs] def read(self, file: BinaryIO) -> int: """ Read unsigned int value. :param file: Binary file, ``io.BytesIO`` is supported as well. :return: Unsigned int value. """ result = 0 for i, byte_ in enumerate(file.read(self.__size)): result |= byte_ << (8 * i) return result
[docs] def write(self, file: BinaryIO, val: int): """ Write unsigned int value to binary IO object. :param file: Binary file, ``io.BytesIO`` is supported as well. :param val: Unsigned int value to write. """ if not isinstance(val, int): raise TypeError(f'Int value expected, but {repr(val)} found.') elif not (self.minimum <= val <= self.maximum): raise ValueError(f'Signed int value within ' f'[{self.minimum}, {self.maximum}] expected, but {repr(val)} found.') _bytes = [] for _ in range(self.__size): _bytes.append(val & 0xff) val >>= 8 file.write(bytes(_bytes))
c_uint8 = CUnsignedIntType(ctypes.sizeof(ctypes.c_uint8)) """ Overview: Reading and writing unsigned integer with 8-bits. Examples:: >>> import io >>> from hbutils.binary import c_uint8 >>> >>> with io.BytesIO(b'\xde\xad\xbe\xef') as file: ... print(c_uint8.read(file)) ... print(c_uint8.read(file)) ... print(c_uint8.read(file)) ... print(c_uint8.read(file)) 222 173 190 239 >>> with io.BytesIO() as file: ... c_uint8.write(file, 222) ... c_uint8.write(file, 173) ... c_uint8.write(file, 190) ... c_uint8.write(file, 239) ... print(file.getvalue()) b'\xde\xad\xbe\xef' """ c_uint16 = CUnsignedIntType(ctypes.sizeof(ctypes.c_uint16)) """ Overview: Reading and writing unsigned integer with 16-bits. Examples:: >>> import io >>> from hbutils.binary import c_uint16 >>> >>> with io.BytesIO(b'\xde\xad\xbe\xef\x12\x34\x56\x78') as file: ... print(c_uint16.read(file)) ... print(c_uint16.read(file)) ... print(c_uint16.read(file)) ... print(c_uint16.read(file)) 44510 61374 13330 30806 >>> with io.BytesIO() as file: ... c_uint16.write(file, 44510) ... c_uint16.write(file, 61374) ... c_uint16.write(file, 13330) ... c_uint16.write(file, 30806) ... print(file.getvalue()) b'\xde\xad\xbe\xef\x124Vx' """ c_uint32 = CUnsignedIntType(ctypes.sizeof(ctypes.c_uint32)) """ Overview: Reading and writing unsigned integer with 32-bits. Examples:: >>> import io >>> from hbutils.binary import c_uint32 >>> >>> with io.BytesIO(b'\xde\xad\xbe\xef\x12\x34\x56\x78') as file: ... print(c_uint32.read(file)) ... print(c_uint32.read(file)) 4022250974 2018915346 >>> with io.BytesIO() as file: ... c_uint32.write(file, 4022250974) ... c_uint32.write(file, 2018915346) ... print(file.getvalue()) b'\xde\xad\xbe\xef\x124Vx' """ c_uint64 = CUnsignedIntType(ctypes.sizeof(ctypes.c_uint64)) """ Overview: Reading and writing unsigned integer with 64-bits. Examples:: >>> import io >>> from hbutils.binary import c_uint64 >>> >>> with io.BytesIO(b'\xde\xad\xbe\xef\x12\x34\x56\x78') as file: ... print(c_uint64.read(file)) 8671175388484775390 >>> with io.BytesIO() as file: ... c_uint64.write(file, 0x78563412efbeadde) ... print(file.getvalue()) b'\xde\xad\xbe\xef\x124Vx' """ _EXIST_TYPES: List[CUnsignedIntType] = [ c_uint8, c_uint16, c_uint32, c_uint64, ] _SIZE_TO_INT_TYPE: Dict[int, CUnsignedIntType] = { item.size: item for item in _EXIST_TYPES } def _get_from_raw(tp) -> CUnsignedIntType: return _SIZE_TO_INT_TYPE[ctypes.sizeof(tp)] c_ubyte = _get_from_raw(ctypes.c_ubyte) """ Alias for :data:`c_uint8`. """ c_ushort = _get_from_raw(ctypes.c_ushort) """ Alias for :data:`c_uint16`. """ c_uint = _get_from_raw(ctypes.c_uint) """ Alias for :data:`c_uint32` (in 64-bits OS). .. note:: Size of :data:`c_uint` is the same as that in C language, which mainly depends on CPU and OS. """ c_ulong = _get_from_raw(ctypes.c_ulong) """ Alias for :data:`c_uint64` (in 64-bits OS). .. note:: Size of :data:`c_ulong` is the same as that in C language, which mainly depends on CPU and OS. """ c_ulonglong = _get_from_raw(ctypes.c_ulonglong) """ Alias for :data:`c_uint64` (in 64-bits OS). .. note:: Size of :data:`c_ulonglong` is the same as that in C language, which mainly depends on CPU and OS. """