diff options
author | Helmut Grohne <helmut@subdivi.de> | 2016-05-22 23:18:54 +0200 |
---|---|---|
committer | Helmut Grohne <helmut@subdivi.de> | 2016-05-22 23:18:54 +0200 |
commit | d7fd1020648d9b95b59bc4cc053f8dfa4e4b9032 (patch) | |
tree | f435e4c26121a7d0ff6d8c58844a23e6634f0d7b | |
parent | 4789c77936a634dc717f61309503f99a44b610ed (diff) | |
download | debian-dedup-d7fd1020648d9b95b59bc4cc053f8dfa4e4b9032.tar.gz |
DecompressedStream: implement readline
Iteration over file-like is required by deb822.Packages.iter_paragraphs.
-rw-r--r-- | dedup/compression.py | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/dedup/compression.py b/dedup/compression.py index 7f6dc99..ea431cc 100644 --- a/dedup/compression.py +++ b/dedup/compression.py @@ -108,26 +108,43 @@ class DecompressedStream(object): self.pos = 0 self.closed = False - def read(self, length=None): + def _fill_buff_until(self, predicate): assert not self.closed data = True while True: - if length is not None and len(self.buff) >= length: - ret = self.buff[:length] - self.buff = self.buff[length:] - break - elif not data: # read EOF in last iteration - ret = self.buff - self.buff = b"" - break + if predicate(self.buff) or not data: + return data = self.fileobj.read(self.blocksize) if data: self.buff += self.decompressor.decompress(data) else: self.buff += self.decompressor.flush() - self.pos += len(ret) + + def _read_from_buff(self, length): + ret = self.buff[:length] + self.buff = self.buff[length:] + self.pos += length return ret + def read(self, length=None): + if length is None: + self._fill_buff_until(lambda _: False) + length = len(self.buff) + else: + self._fill_buff_until(lambda b, l=length: len(b) >= l) + return self._read_from_buff(length) + + def readline(self): + self._fill_buff_until(lambda b: b'\n' in b) + try: + length = self.buff.index(b'\n') + 1 + except ValueError: + length = len(self.buff) + return self._read_from_buff(length) + + def __iter__(self): + return iter(self.readline, b'') + def tell(self): assert not self.closed return self.pos |