class Decompress(object): STATE_MAGIC = 0 STATE_BLOCK_HEADER = 1 STATE_BLOCK = 2 def __init__(self): self.__buff = lzo_buffer(MAX_BLOCK) self.__fifo = Fifo() self.__output = [] self.state = self.STATE_MAGIC def __yield_output(self): output = ''.join(self.__output) self.__output = [] return output def decompress(self, data): self.__fifo.write(data) while True: # magic if self.state == self.STATE_MAGIC: magic = self.__fifo.readblock(len(LZO_MAGIC)) if not magic: break if magic != LZO_MAGIC: raise Exception('Bad magic: %s' % magic) self.state = self.STATE_BLOCK_HEADER # block header if self.state == self.STATE_BLOCK_HEADER: header = self.__fifo.readblock(_BLOCK_HEADER_LENGTH) if not header: break self.__block_length = unpack(_BLOCK_HEADER_FORMAT, header)[0] self.__block_compressed = self.__block_length & 0x8000 self.__block_length ^= self.__block_compressed if self.__block_length: self.state = self.STATE_BLOCK # block if self.state == self.STATE_BLOCK: block = self.__fifo.readblock(self.__block_length) if not block: break if self.__block_compressed: decomp = lzo1x_decompress(block, self.__buff) self.__output.append(decomp) else: self.__output.append(block) self.state = self.STATE_BLOCK_HEADER return self.__yield_output()