def read(self, filename): zinfo = self.getinfo(filename) filepos = self.fp.tell() self.fp.seek(zinfo.file_offset, 0) bytes = self.fp.read(intmask(zinfo.compress_size)) self.fp.seek(filepos, 0) if zinfo.compress_type == ZIP_STORED: pass elif zinfo.compress_type == ZIP_DEFLATED and rzlib is not None: stream = rzlib.inflateInit(wbits=-15) try: bytes, _, _ = rzlib.decompress(stream, bytes) # need to feed in unused pad byte so that zlib won't choke ex, _, _ = rzlib.decompress(stream, 'Z') if ex: bytes = bytes + ex finally: rzlib.inflateEnd(stream) elif zinfo.compress_type == ZIP_DEFLATED: raise BadZipfile, \ "Cannot decompress file, zlib not installed" else: raise BadZipfile, \ "Unsupported compression method %d for file %s" % \ (zinfo.compress_type, filename) crc = crc32(bytes) if crc != zinfo.CRC: raise BadZipfile, "Bad CRC-32 for file %s" % filename return bytes
def test_decompression_lots_of_data(): """ Test compression of more data that fits in a single internal output buffer. """ expanded = repr(range(20000)) compressed = zlib.compress(expanded) print len(compressed), '=>', len(expanded) stream = rzlib.inflateInit() bytes, finished, unused = rzlib.decompress(stream, compressed, rzlib.Z_FINISH) rzlib.inflateEnd(stream) assert bytes == expanded assert finished is True assert unused == 0
def test_decompression(): """ Once we have got a inflate stream, rzlib.decompress() should allow us to decompress bytes. """ stream = rzlib.inflateInit() bytes1, finished1, unused1 = rzlib.decompress(stream, compressed) bytes2, finished2, unused2 = rzlib.decompress(stream, "", rzlib.Z_FINISH) rzlib.inflateEnd(stream) assert bytes1 + bytes2 == expanded assert finished1 is True assert finished2 is True assert unused1 == 0 assert unused2 == 0
def decompress(space, string, wbits=rzlib.MAX_WBITS, bufsize=0): """ decompress(string[, wbits[, bufsize]]) -- Return decompressed string. Optional arg wbits is the window buffer size. Optional arg bufsize is only for compatibility with CPython and is ignored. """ try: try: stream = rzlib.inflateInit(wbits) except ValueError: raise zlib_error(space, "Bad window buffer size") try: result, _, _ = rzlib.decompress(stream, string, rzlib.Z_FINISH) finally: rzlib.inflateEnd(stream) except rzlib.RZlibError, e: raise zlib_error(space, e.msg)
def test_decompression_truncated_input(): """ Test that we can accept incomplete input when inflating, but also detect this situation when using Z_FINISH. """ expanded = repr(range(20000)) compressed = zlib.compress(expanded) print len(compressed), '=>', len(expanded) stream = rzlib.inflateInit() data, finished1, unused1 = rzlib.decompress(stream, compressed[:1000]) assert expanded.startswith(data) assert finished1 is False assert unused1 == 0 data2, finished2, unused2 = rzlib.decompress(stream, compressed[1000:2000]) data += data2 assert finished2 is False assert unused2 == 0 assert expanded.startswith(data) py.test.raises(rzlib.RZlibError, rzlib.decompress, stream, compressed[2000:-500], rzlib.Z_FINISH) rzlib.inflateEnd(stream)
def __del__(self): """Automatically free the resources used by the stream.""" if self.stream: rzlib.inflateEnd(self.stream) self.stream = rzlib.null_stream
def test_inflate_init_end(): """ inflateInit() followed by inflateEnd() should work and do nothing. """ stream = rzlib.inflateInit() rzlib.inflateEnd(stream)