diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2012-08-04 14:17:10 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2012-08-04 14:17:10 (GMT) |
commit | 8aaeb2f4dcb0e0b01ab69b1f28de527b8f579e96 (patch) | |
tree | cdf728170d13a8c2bbf5d1924e7f359c108336e8 | |
parent | 848698727fcbb633246b56ab57080b4d5493c186 (diff) | |
parent | 8280b4ba02db287b1d3fd70cfd63bc6343124ad0 (diff) | |
download | cpython-8aaeb2f4dcb0e0b01ab69b1f28de527b8f579e96.zip cpython-8aaeb2f4dcb0e0b01ab69b1f28de527b8f579e96.tar.gz cpython-8aaeb2f4dcb0e0b01ab69b1f28de527b8f579e96.tar.bz2 |
Merge
-rw-r--r-- | Lib/asynchat.py | 14 | ||||
-rw-r--r-- | Lib/bz2.py | 51 |
2 files changed, 29 insertions, 36 deletions
diff --git a/Lib/asynchat.py b/Lib/asynchat.py index 2199d1b..4e26bb5 100644 --- a/Lib/asynchat.py +++ b/Lib/asynchat.py @@ -49,18 +49,6 @@ import socket import asyncore from collections import deque -def buffer(obj, start=None, stop=None): - # if memoryview objects gain slicing semantics, - # this function will change for the better - # memoryview used for the TypeError - memoryview(obj) - if start == None: - start = 0 - if stop == None: - stop = len(obj) - x = obj[start:stop] - ## print("buffer type is: %s"%(type(x),)) - return x class async_chat (asyncore.dispatcher): """This is an abstract class. You must derive from this class, and add @@ -240,7 +228,7 @@ class async_chat (asyncore.dispatcher): # handle classic producer behavior obs = self.ac_out_buffer_size try: - data = buffer(first, 0, obs) + data = first[:obs] except TypeError: data = first.more() if data: @@ -174,29 +174,31 @@ class BZ2File(io.BufferedIOBase): # Fill the readahead buffer if it is empty. Returns False on EOF. def _fill_buffer(self): - if self._buffer: - return True - - if self._decompressor.unused_data: - rawblock = self._decompressor.unused_data - else: - rawblock = self._fp.read(_BUFFER_SIZE) - - if not rawblock: - if self._decompressor.eof: - self._mode = _MODE_READ_EOF - self._size = self._pos - return False + # Depending on the input data, our call to the decompressor may not + # return any data. In this case, try again after reading another block. + while True: + if self._buffer: + return True + + if self._decompressor.unused_data: + rawblock = self._decompressor.unused_data 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() + rawblock = self._fp.read(_BUFFER_SIZE) + + if not rawblock: + 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 + self._buffer = self._decompressor.decompress(rawblock) # Read data until EOF. # If return_data is false, consume the data without returning it. @@ -256,11 +258,14 @@ class BZ2File(io.BufferedIOBase): return self._read_block(size) 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"". with self._lock: self._check_can_read() if (size == 0 or self._mode == _MODE_READ_EOF or |