diff options
Diffstat (limited to 'generic/tclZlib.c')
-rw-r--r-- | generic/tclZlib.c | 65 |
1 files changed, 26 insertions, 39 deletions
diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 8f70c30..dac47cf 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -1189,40 +1189,33 @@ Tcl_ZlibStreamPut( */ outSize = deflateBound(&zshPtr->stream, zshPtr->stream.avail_in)+100; - if (outSize < 4096) { - outSize = 4096; - } zshPtr->stream.avail_out = outSize; dataTmp = ckalloc(zshPtr->stream.avail_out); zshPtr->stream.next_out = (Bytef *) dataTmp; e = deflate(&zshPtr->stream, flush); - if ((e==Z_OK || e==Z_BUF_ERROR) && (zshPtr->stream.avail_out == 0)) { - if (outSize - zshPtr->stream.avail_out > 0) { - /* - * Output buffer too small. - */ - - obj = Tcl_NewByteArrayObj((unsigned char *) dataTmp, - outSize - zshPtr->stream.avail_out); + while (e == Z_BUF_ERROR || (flush == Z_FINISH && e == Z_OK)) { + /* + * Output buffer too small to hold the data being generated or we + * are doing the end-of-stream flush (which can spit out masses of + * data). This means we need to put a new buffer into place after + * saving the old generated data to the outData list. + */ - /* - * Now append the compressed data to the outData list. - */ + obj = Tcl_NewByteArrayObj((unsigned char *) dataTmp, outSize); + Tcl_ListObjAppendElement(NULL, zshPtr->outData, obj); - Tcl_ListObjAppendElement(NULL, zshPtr->outData, obj); - } if (outSize < 0xFFFF) { outSize = 0xFFFF; /* There may be *lots* of data left to * output... */ - ckfree(dataTmp); - dataTmp = ckalloc(outSize); + dataTmp = ckrealloc(dataTmp, outSize); } zshPtr->stream.avail_out = outSize; zshPtr->stream.next_out = (Bytef *) dataTmp; e = deflate(&zshPtr->stream, flush); } + if (e != Z_OK && !(flush==Z_FINISH && e==Z_STREAM_END)) { if (zshPtr->interp) { ConvertError(zshPtr->interp, e, zshPtr->stream.adler); @@ -2913,9 +2906,9 @@ ZlibTransformClose( } } } while (e != Z_STREAM_END); - e = deflateEnd(&cd->outStream); + (void) deflateEnd(&cd->outStream); } else { - e = inflateEnd(&cd->inStream); + (void) inflateEnd(&cd->inStream); } /* @@ -3351,10 +3344,13 @@ ZlibTransformGetOption( Tcl_DStringAppendElement(dsPtr, ""); } } else { - int len; - const char *str = Tcl_GetStringFromObj(cd->compDictObj, &len); + if (cd->compDictObj) { + int len; + const char *str = Tcl_GetStringFromObj(cd->compDictObj, &len); - Tcl_DStringAppend(dsPtr, str, len); + Tcl_DStringAppend(dsPtr, str, len); + } + return TCL_OK; } } @@ -3556,7 +3552,6 @@ ZlibStackChannelTransform( ZlibChannelData *cd = ckalloc(sizeof(ZlibChannelData)); Tcl_Channel chan; int wbits = 0; - int e; if (mode != TCL_ZLIB_STREAM_DEFLATE && mode != TCL_ZLIB_STREAM_INFLATE) { Tcl_Panic("unknown mode: %d", mode); @@ -3610,43 +3605,35 @@ ZlibStackChannelTransform( */ if (mode == TCL_ZLIB_STREAM_INFLATE) { - e = inflateInit2(&cd->inStream, wbits); - if (e != Z_OK) { + if (inflateInit2(&cd->inStream, wbits) != Z_OK) { goto error; } cd->inAllocated = DEFAULT_BUFFER_SIZE; cd->inBuffer = ckalloc(cd->inAllocated); if (cd->flags & IN_HEADER) { - e = inflateGetHeader(&cd->inStream, &cd->inHeader.header); - if (e != Z_OK) { + if (inflateGetHeader(&cd->inStream, &cd->inHeader.header) != Z_OK) { goto error; } } if (cd->format == TCL_ZLIB_FORMAT_RAW && cd->compDictObj) { - e = SetInflateDictionary(&cd->inStream, cd->compDictObj); - if (e != Z_OK) { + if (SetInflateDictionary(&cd->inStream, cd->compDictObj) != Z_OK) { goto error; } - TclDecrRefCount(cd->compDictObj); - cd->compDictObj = NULL; } } else { - e = deflateInit2(&cd->outStream, level, Z_DEFLATED, wbits, - MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); - if (e != Z_OK) { + if (deflateInit2(&cd->outStream, level, Z_DEFLATED, wbits, + MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK) { goto error; } cd->outAllocated = DEFAULT_BUFFER_SIZE; cd->outBuffer = ckalloc(cd->outAllocated); if (cd->flags & OUT_HEADER) { - e = deflateSetHeader(&cd->outStream, &cd->outHeader.header); - if (e != Z_OK) { + if (deflateSetHeader(&cd->outStream, &cd->outHeader.header) != Z_OK) { goto error; } } if (cd->compDictObj) { - e = SetDeflateDictionary(&cd->outStream, cd->compDictObj); - if (e != Z_OK) { + if (SetDeflateDictionary(&cd->outStream, cd->compDictObj) != Z_OK) { goto error; } } |