# Fill the readahead buffer if it is empty. Returns False on EOF.
+ # Depending on the input data, our call to the decompressor may not
+ # return any data. In this case, try again after reading another block.
- if self._decompressor.unused_data:
- rawblock = self._decompressor.unused_data
- rawblock = self._fp.read(_BUFFER_SIZE)
+ if self._decompressor.unused_data:
+ rawblock = self._decompressor.unused_data
+ rawblock = self._fp.read(_BUFFER_SIZE)
+ if self._decompressor.eof:
+ self._mode = _MODE_READ_EOF
+ raise EOFError("Compressed file ended before the "
+ "end-of-stream marker was reached")
+ # Continue to next stream.
- self._mode = _MODE_READ_EOF
- raise EOFError("Compressed file ended before the "
- "end-of-stream marker was reached")
+ self._decompressor = LZMADecompressor(**self._init_args)
- # Continue to next stream.
- if self._decompressor.eof:
- self._decompressor = LZMADecompressor(**self._init_args)
- self._buffer = self._decompressor.decompress(rawblock)
+ self._buffer = self._decompressor.decompress(rawblock)
# If return_data is false, consume the data without returning it.
def read1(self, size=-1):
- """Read up to size uncompressed bytes with at most one read
- from the underlying stream.
+ """Read up to size uncompressed bytes, while trying to avoid
+ making multiple reads from the underlying stream.
Returns b"" if the file is at EOF.
+ # Usually, read1() calls _fp.read() at most once. However, sometimes
+ # this does not give enough data for the decompressor to make progress.
+ # In this case we make multiple reads, to avoid returning b"".
if (size == 0 or self._mode == _MODE_READ_EOF or