class Reader(object): ''' Structure stream reader. ''' def __init__(self, string = None, file = None): ''' Wrap a string or file stream in a structure reader. Either string or file must be given. ''' if string is not None: self.stream = StringIO(string) elif file is not None: self.stream = file else: raise "string or file must be non-None" # Bit reader buffer self.bitter = BitReader(self.readByte) def read(self, size): ''' read(size) -> string Read bytes into a raw string. ''' return self.stream.read(size) def readStruct(self, format): ''' readStruct(format) -> tuple Read a structure from the stream. Raises FormatError() if bytes were unavailable. ''' size = struct.calcsize(format) bytes = self.read(size) if len(bytes) != size: raise FormatError() return struct.unpack(format, bytes) def readString(self): ''' readString() -> string Read a UTF8-encoded string from the stream. Raises FormatError() if bytes were unavailable. ''' size = self.readStruct("!I")[0] bytes = self.read(size) if len(bytes) != size: raise FormatError() return bytes.decode("utf-8") def readByte(self): ''' readByte() -> int Read a single byte. ''' return ord(self.read(1)) def readBits(self, bits): ''' Read bits (see ppk.bitio.BitReader). ''' return self.bitter(bits) def skipBits(self): ''' Skip buffered bits (see ppk.bitio.BitReader). ''' self.bitter.skip()