[pypy-commit] pypy zlib-copying: Teach rzlib to copy decompression streams.
Julian Berman
pypy.commits at gmail.com
Tue Feb 5 08:55:55 EST 2019
Author: Julian Berman <Julian+Hg at GrayVines.com>
Branch: zlib-copying
Changeset: r95833:6237bdf72bdb
Date: 2019-02-04 17:13 +0100
http://bitbucket.org/pypy/pypy/changeset/6237bdf72bdb/
Log: Teach rzlib to copy decompression streams.
diff --git a/rpython/rlib/rzlib.py b/rpython/rlib/rzlib.py
--- a/rpython/rlib/rzlib.py
+++ b/rpython/rlib/rzlib.py
@@ -35,6 +35,7 @@
MAX_WBITS MAX_MEM_LEVEL
Z_BEST_SPEED Z_BEST_COMPRESSION Z_DEFAULT_COMPRESSION
Z_FILTERED Z_HUFFMAN_ONLY Z_DEFAULT_STRATEGY Z_NEED_DICT
+ Z_NULL
'''.split()
class SimpleCConfig:
@@ -160,6 +161,7 @@
rffi.INT)
_inflate = zlib_external('inflate', [z_stream_p, rffi.INT], rffi.INT)
+_inflateCopy = zlib_external('inflateCopy', [z_stream_p, z_stream_p], rffi.INT)
_inflateEnd = zlib_external('inflateEnd', [z_stream_p], rffi.INT,
releasegil=False)
@@ -330,6 +332,19 @@
lltype.free(stream, flavor='raw')
+def inflateCopy(source):
+ """
+ Allocate and return an independent copy of the provided stream object.
+ """
+ dest = inflateInit()
+ err = _inflateCopy(dest, source)
+ if err != Z_OK:
+ inflateEnd(dest)
+ raise RZlibError.fromstream(source, err,
+ "while copying decompression object")
+ return dest
+
+
def inflateEnd(stream):
"""
Free the resources associated with the inflate stream.
diff --git a/rpython/rlib/test/test_rzlib.py b/rpython/rlib/test/test_rzlib.py
--- a/rpython/rlib/test/test_rzlib.py
+++ b/rpython/rlib/test/test_rzlib.py
@@ -246,6 +246,60 @@
rzlib.deflateEnd(stream)
+def test_decompress_copy():
+ """
+ inflateCopy produces an independent copy of a stream.
+ """
+
+ stream = rzlib.inflateInit()
+
+ bytes1, finished1, unused1 = rzlib.decompress(stream, compressed[:10])
+ assert bytes1
+ assert finished1 is False
+
+ copied = rzlib.inflateCopy(stream)
+
+ bytes_stream, finished_stream, unused_stream = rzlib.decompress(
+ stream,
+ compressed[10:],
+ rzlib.Z_FINISH,
+ )
+ assert bytes1 + bytes_stream == expanded
+ assert finished_stream is True
+ assert unused1 == 0
+ assert unused_stream == 0
+ rzlib.inflateEnd(stream)
+
+ bytes_copy, finished_copy, unused_copy = rzlib.decompress(
+ copied,
+ compressed[10:],
+ rzlib.Z_FINISH,
+ )
+ rzlib.inflateEnd(copied)
+ assert bytes1 + bytes_copy == expanded
+ assert finished_copy is True
+ assert unused_copy == 0
+
+
+def test_unsuccessful_decompress_copy():
+ """
+ Errors during unsuccesful inflateCopy operations raise RZlibErrors.
+ """
+ stream = rzlib.inflateInit()
+
+ # From zlib.h:
+ #
+ # "inflateCopy returns [...] Z_STREAM_ERROR if the source stream
+ # state was inconsistent (such as zalloc being Z_NULL)"
+ from rpython.rtyper.lltypesystem import rffi, lltype
+ stream.c_zalloc = rffi.cast(lltype.typeOf(stream.c_zalloc), rzlib.Z_NULL)
+
+ exc = py.test.raises(rzlib.RZlibError, rzlib.inflateCopy, stream)
+ msg = "Error -2 while copying decompression object: inconsistent stream state"
+ assert str(exc.value) == msg
+ rzlib.inflateEnd(stream)
+
+
def test_cornercases():
"""
Test degenerate arguments.
More information about the pypy-commit
mailing list