def _read_unpack(self, size=1, *, signed=False, lilendian=False, quiet=False): """Read bytes and unpack for integers. Positional arguments: * size -- int, buffer size (default is 1) Keyword arguments: * signed -- bool, signed flag (default is False) <keyword> True / False * lilendian -- bool, little-endian flag (default is False) <keyword> True / False * quiet -- bool, quiet (no exception) flag (default is False) <keyword> True / False Returns: * int -- unpacked data upon success """ endian = '<' if lilendian else '>' if size == 8: # unpack to 8-byte integer (long long) kind = 'q' if signed else 'Q' elif size == 4: # unpack to 4-byte integer (int / long) kind = 'i' if signed else 'I' elif size == 2: # unpack to 2-byte integer (short) kind = 'h' if signed else 'H' elif size == 1: # unpack to 1-byte integer (char) kind = 'b' if signed else 'B' else: # do not unpack kind = None if kind is None: mem = self._file.read(size) end = 'little' if lilendian else 'big' buf = int.from_bytes(mem, end, signed=signed) else: try: fmt = f'{endian}{kind}' mem = self._file.read(size) buf = struct.unpack(fmt, mem)[0] except struct.error: if quiet: return None else: raise StructError( f'{self.__class__.__name__}: unpack failed') from None return buf
def _read_unpack(self, size=1, *, signed=False, lilendian=False, quiet=False): """Read bytes and unpack for integers. Arguments: size (int): buffer size Keyword Arguments: signed (bool): signed flag lilendian (bool): little-endian flag quiet (bool): quiet (no exception) flag Returns: Optional[int]: unpacked data upon success Raises: StructError: If unpack (:func:`struct.pack`) failed, and :exc:`struct.error` raised. """ endian = '<' if lilendian else '>' if size == 8: # unpack to 8-byte integer (long long) kind = 'q' if signed else 'Q' elif size == 4: # unpack to 4-byte integer (int / long) kind = 'i' if signed else 'I' elif size == 2: # unpack to 2-byte integer (short) kind = 'h' if signed else 'H' elif size == 1: # unpack to 1-byte integer (char) kind = 'b' if signed else 'B' else: # do not unpack kind = None if kind is None: mem = self._file.read(size) end = 'little' if lilendian else 'big' buf = int.from_bytes(mem, end, signed=signed) else: try: fmt = f'{endian}{kind}' mem = self._file.read(size) buf = struct.unpack(fmt, mem)[0] except struct.error: if quiet: return None raise StructError(f'{self.__class__.__name__}: unpack failed') return buf
def _make_pack(cls, integer, *, size=1, signed=False, lilendian=False): """Pack integers to bytes. Arguments: integer (int) integer to be packed Keyword arguments: size (int): buffer size signed (bool): signed flag lilendian (bool): little-endian flag Returns: bytes: Packed data upon success. Raises: StructError: If failed to pack the integer. """ endian = '<' if lilendian else '>' if size == 8: # unpack to 8-byte integer (long long) kind = 'q' if signed else 'Q' elif size == 4: # unpack to 4-byte integer (int / long) kind = 'i' if signed else 'I' elif size == 2: # unpack to 2-byte integer (short) kind = 'h' if signed else 'H' elif size == 1: # unpack to 1-byte integer (char) kind = 'b' if signed else 'B' else: # do not unpack kind = None if kind is None: end = 'little' if lilendian else 'big' buf = integer.to_bytes(size, end, signed=signed) else: try: fmt = f'{endian}{kind}' buf = struct.pack(fmt, integer) except struct.error: raise StructError(f'{cls.__name__}: pack failed') from None return buf
def pack(cls, integer, *, size=1, signed=False, lilendian=False): """Pack integers to bytes. Positional arguments: * integer -- int, integer to be packed Keyword arguments: * size -- int, buffer size (default is 1) * signed -- bool, signed flag (default is False) <keyword> True / False * lilendian -- bool, little-endian flag (default is False) <keyword> True / False Returns: * bytes -- packed data upon success """ endian = '<' if lilendian else '>' if size == 8: # unpack to 8-byte integer (long long) kind = 'q' if signed else 'Q' elif size == 4: # unpack to 4-byte integer (int / long) kind = 'i' if signed else 'I' elif size == 2: # unpack to 2-byte integer (short) kind = 'h' if signed else 'H' elif size == 1: # unpack to 1-byte integer (char) kind = 'b' if signed else 'B' else: # do not unpack kind = None if kind is None: end = 'little' if lilendian else 'big' buf = integer.to_bytes(size, end, signed=signed) else: try: fmt = f'{endian}{kind}' buf = struct.pack(fmt, integer) except struct.error: raise StructError(f'{cls.__name__}: pack failed') from None return buf