--- a/mercurial/util.py Wed Aug 04 13:21:11 2010 -0500
+++ b/mercurial/util.py Fri Aug 06 12:59:13 2010 -0500
@@ -925,30 +925,36 @@
else:
yield chunk
self.iter = splitbig(in_iter)
- self.buf = ''
+ self._queue = []
def read(self, l):
"""Read L bytes of data from the iterator of chunks of data.
Returns less than L bytes if the iterator runs dry."""
- if l > len(self.buf) and self.iter:
- # Clamp to a multiple of 2**16
- targetsize = max(l, 2**16)
- collector = [str(self.buf)]
- collected = len(self.buf)
- for chunk in self.iter:
- collector.append(chunk)
- collected += len(chunk)
- if collected >= targetsize:
+ left = l
+ buf = ''
+ queue = self._queue
+ while left > 0:
+ # refill the queue
+ if not queue:
+ target = 2**18
+ for chunk in self.iter:
+ queue.append(chunk)
+ target -= len(chunk)
+ if target <= 0:
+ break
+ if not queue:
break
+
+ chunk = queue.pop(0)
+ left -= len(chunk)
+ if left < 0:
+ queue.insert(0, chunk[left:])
+ buf += chunk[:left]
else:
- self.iter = False
- self.buf = ''.join(collector)
- if len(self.buf) == l:
- s, self.buf = str(self.buf), ''
- else:
- s, self.buf = self.buf[:l], buffer(self.buf, l)
- return s
+ buf += chunk
+ return buf
+
def filechunkiter(f, size=65536, limit=None):
"""Create a generator that produces the data in the file size
(default 65536) bytes at a time, up to optional limit (default is