35 lines
902 B
Python
35 lines
902 B
Python
from io import BytesIO
|
|
from struct import calcsize, unpack
|
|
from typing import BinaryIO, Dict
|
|
|
|
|
|
class Unpacker:
|
|
@staticmethod
|
|
def from_bytes(data: bytes):
|
|
return Unpacker({}, BytesIO(data))
|
|
|
|
def __init__(self, formats: Dict[str, str], stream: BinaryIO, endianness: str = '>'):
|
|
self.formats = formats
|
|
self.stream = stream
|
|
self.endianness = endianness
|
|
|
|
def __getattribute__(self, item):
|
|
try:
|
|
return super(Unpacker, self).__getattribute__(item)
|
|
except AttributeError:
|
|
return self.unpack(item)
|
|
|
|
def __getitem__(self, item):
|
|
return self.unpack(item)
|
|
|
|
def unpack(self, item):
|
|
if item in self.formats:
|
|
fmt = self.formats.get(item)
|
|
else:
|
|
fmt = item
|
|
|
|
fmt = self.endianness + fmt
|
|
|
|
size = calcsize(fmt)
|
|
return unpack(fmt, self.stream.read(size))
|