summaryrefslogtreecommitdiffstats
path: root/Lib/bz2.py
diff options
context:
space:
mode:
authorNadeem Vawda <nadeem.vawda@gmail.com>2011-05-26 23:52:15 (GMT)
committerNadeem Vawda <nadeem.vawda@gmail.com>2011-05-26 23:52:15 (GMT)
commit55b4338874ede31619a097c0b4a271b90e980472 (patch)
tree43120769e11327e0b9c4bb97d9711ba47167f731 /Lib/bz2.py
parentc556e10b94541d7bf20e908f8eca78e7f63fc28c (diff)
downloadcpython-55b4338874ede31619a097c0b4a271b90e980472.zip
cpython-55b4338874ede31619a097c0b4a271b90e980472.tar.gz
cpython-55b4338874ede31619a097c0b4a271b90e980472.tar.bz2
Issue #1625: BZ2File and bz2.decompress() now support multi-stream files.
Initial patch by Nir Aides.
Diffstat (limited to 'Lib/bz2.py')
-rw-r--r--Lib/bz2.py47
1 files changed, 34 insertions, 13 deletions
diff --git a/Lib/bz2.py b/Lib/bz2.py
index 8ffeaac..4b25f5d 100644
--- a/Lib/bz2.py
+++ b/Lib/bz2.py
@@ -76,6 +76,10 @@ class BZ2File(io.BufferedIOBase):
mode = "wb"
mode_code = _MODE_WRITE
self._compressor = BZ2Compressor()
+ elif mode in ("a", "ab"):
+ mode = "ab"
+ mode_code = _MODE_WRITE
+ self._compressor = BZ2Compressor()
else:
raise ValueError("Invalid mode: {!r}".format(mode))
@@ -161,14 +165,25 @@ class BZ2File(io.BufferedIOBase):
def _fill_buffer(self):
if self._buffer:
return True
- if self._decompressor.eof:
- self._mode = _MODE_READ_EOF
- self._size = self._pos
- return False
- rawblock = self._fp.read(_BUFFER_SIZE)
+
+ if self._decompressor.unused_data:
+ rawblock = self._decompressor.unused_data
+ else:
+ rawblock = self._fp.read(_BUFFER_SIZE)
+
if not rawblock:
- raise EOFError("Compressed file ended before the "
- "end-of-stream marker was reached")
+ if self._decompressor.eof:
+ self._mode = _MODE_READ_EOF
+ self._size = self._pos
+ return False
+ else:
+ raise EOFError("Compressed file ended before the "
+ "end-of-stream marker was reached")
+
+ # Continue to next stream.
+ if self._decompressor.eof:
+ self._decompressor = BZ2Decompressor()
+
self._buffer = self._decompressor.decompress(rawblock)
return True
@@ -384,9 +399,15 @@ def decompress(data):
"""
if len(data) == 0:
return b""
- decomp = BZ2Decompressor()
- result = decomp.decompress(data)
- if not decomp.eof:
- raise ValueError("Compressed data ended before the "
- "end-of-stream marker was reached")
- return result
+
+ result = b""
+ while True:
+ decomp = BZ2Decompressor()
+ result += decomp.decompress(data)
+ if not decomp.eof:
+ raise ValueError("Compressed data ended before the "
+ "end-of-stream marker was reached")
+ if not decomp.unused_data:
+ return result
+ # There is unused data left over. Proceed to next stream.
+ data = decomp.unused_data