Index: zlib.py =================================================================== RCS file: /cvsroot/jython/jython/Lib/zlib.py,v retrieving revision 1.2 diff -u -r1.2 zlib.py --- zlib.py 6 Oct 2001 20:36:45 -0000 1.2 +++ zlib.py 27 Feb 2004 21:08:49 -0000 @@ -24,6 +24,7 @@ # Z_SYNC_FLUSH = 2 # Z_FULL_FLUSH = 3 Z_FINISH = 4 +_valid_flush_modes = (Z_FINISH,) def adler32(string, value=1): if value != 1: @@ -51,6 +52,7 @@ class compressobj: + # all jython uses wbits for is deciding whether to skip the header if it's negative def __init__(self, level=6, method=DEFLATED, wbits=MAX_WBITS, memLevel=0, strategy=0): if abs(wbits) > MAX_WBITS or abs(wbits) < 8: @@ -59,34 +61,68 @@ self.deflater.setStrategy(strategy) if wbits < 0: _get_deflate_data(self.deflater) + self._ended = False def compress(self, string): + if self._ended: + raise error("compressobj may not be used after flush(Z_FINISH)") self.deflater.setInput(string, 0, len(string)) return _get_deflate_data(self.deflater) def flush(self, mode=Z_FINISH): - if mode != Z_FINISH: + if self._ended: + raise error("compressobj may not be used after flush(Z_FINISH)") + if mode not in _valid_flush_modes: raise ValueError, "Invalid flush option" self.deflater.finish() - return _get_deflate_data(self.deflater) + last = _get_deflate_data(self.deflater) + if mode == Z_FINISH: + self.deflater.end() + self._ended = True + return last class decompressobj: - def __init__(self, wbits=0): + # all jython uses wbits for is deciding whether to skip the header if it's negative + def __init__(self, wbits=MAX_WBITS): if abs(wbits) > MAX_WBITS or abs(wbits) < 8: raise ValueError, "Invalid initialization option" self.inflater = util.zip.Inflater(wbits < 0) self.unused_data = "" + self._ended = False + + def decompress(self, string, max_length=0): + if self._ended: + raise error("decompressobj may not be used after flush()") + + # unused_data is always "" until inflation is finished; then it is + # the unused bytes of the input; + # unconsumed_tail is whatever input was not used because max_length + # was exceeded before inflation finished. + # Thus, at most one of {unused_data, unconsumed_tail} may be non-empty. + self.unused_data = "" + self.unconsumed_tail = "" + + if max_length < 0: + raise ValueError("max_length must be a positive integer") - def decompress(self, string): self.inflater.setInput(string) - r = _get_inflate_data(self.inflater) - # Arrgh. This suck. - self.unused_data = " " * self.inflater.getRemaining() - return r + inflated = _get_inflate_data(self.inflater, max_length) + + r = self.inflater.getRemaining() + if r: + if max_length: + self.unconsumed_tail = string[-r:] + else: + self.unused_data = string[-r:] + + return inflated def flush(self): - #self.inflater.finish() - return _get_inflate_data(self.inflater) + if self._ended: + raise error("decompressobj may not be used after flush()") + last = _get_inflate_data(self.inflater) + self.inflater.end() + return last def _get_deflate_data(deflater): @@ -100,13 +136,20 @@ return sb.toString() -def _get_inflate_data(inflater): +def _get_inflate_data(inflater, max_length=0): buf = jarray.zeros(1024, 'b') sb = lang.StringBuffer() + total = 0 while not inflater.finished(): - l = inflater.inflate(buf) + if max_length: + l = inflater.inflate(buf, 0, min(1024, max_length - total)) + else: + l = inflater.inflate(buf) if l == 0: break + + total += l sb.append(lang.String(buf, 0, 0, l)) + if max_length and total == max_length: + break return sb.toString() -