48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
import zlib
|
|
import io
|
|
|
|
class ZlibDecompressBuffer(object):
|
|
def __init__(self, _fs: io.BufferedReader, _len: int, _is_compressed: bool):
|
|
self.__fs: io.BufferedReader = _fs
|
|
self.__len: int = _len
|
|
self.__compressed: bool = _is_compressed
|
|
|
|
self.__pos: int = 0
|
|
self.__parser: zlib._Decompress = zlib.decompressobj()
|
|
self.__cache: bytes = b''
|
|
self.__cachelen: int = 0
|
|
|
|
def __ParseOnce(self) -> bytes:
|
|
# check remain
|
|
remain: int = self.__len - self.__pos
|
|
if remain <= 0:
|
|
return None
|
|
|
|
# read it and increase pos
|
|
read_count: int = min(remain, 1024)
|
|
gotten_uncompressed: bytes = self.__parser.decompress(self.__fs.read(read_count))
|
|
self.__pos += read_count
|
|
|
|
# everything has done, no more data, flush it and get it remained data
|
|
if self.__pos >= self.__len:
|
|
gotten_uncompressed += self.__parser.flush()
|
|
|
|
return gotten_uncompressed
|
|
|
|
def Read(self, expected: int):
|
|
# try enrich cache
|
|
while self.__cachelen < expected:
|
|
new_data = self.__ParseOnce()
|
|
if new_data is None:
|
|
# no more data
|
|
raise Exception("No more data.")
|
|
else:
|
|
self.__cache += new_data
|
|
self.__cachelen += len(new_data)
|
|
|
|
# change data
|
|
returned_data = self.__cache[:expected]
|
|
self.__cache = self.__cache[expected:]
|
|
self.__cachelen -= expected
|
|
|
|
return returned_data |