예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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