diff options
Diffstat (limited to 'generic/tclZlib.c')
| -rw-r--r-- | generic/tclZlib.c | 102 |
1 files changed, 58 insertions, 44 deletions
diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 731176c..0c38602 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -91,7 +91,7 @@ typedef struct { GzipHeader outHeader; /* Header to write to an output stream, when * compressing a gzip stream. */ Tcl_TimerToken timer; /* Timer used for keeping events fresh. */ - Tcl_DString result; /* Buffer for decompression results */ + Tcl_DString result; /* Buffer for decompression results. */ } ZlibChannelData; /* @@ -140,6 +140,10 @@ static void ConvertError(Tcl_Interp *interp, int code); static void ExtractHeader(gz_header *headerPtr, Tcl_Obj *dictObj); static int GenerateHeader(Tcl_Interp *interp, Tcl_Obj *dictObj, GzipHeader *headerPtr, int *extraSizePtr); +static int ResultCopy(Tcl_DString *r, unsigned char *buf, + int toRead); +static int ResultGenerate(ZlibChannelData *cd, int n, int flush, + int *errorCodePtr); static Tcl_Channel ZlibStackChannelTransform(Tcl_Interp *interp, int mode, int format, int level, Tcl_Channel channel, Tcl_Obj *gzipHeaderDictPtr); @@ -148,9 +152,6 @@ static void ZlibTransformTimerKill(ZlibChannelData *cd); static void ZlibTransformTimerRun(ClientData clientData); static void ZlibTransformTimerSetup(ZlibChannelData *cd); -static int ResultCopy(Tcl_DString* r, unsigned char *buf, int toRead); -static int ResultGenerate(ZlibChannelData *cd, int n, int flush, int* errorCodePtr); - /* * Type of zlib-based compressing and decompressing channels. */ @@ -2434,7 +2435,7 @@ ZlibTransformInput( * converted and returned. */ - if (ResultGenerate (cd, 0, Z_SYNC_FLUSH, errorCodePtr) < 0) { + if (ResultGenerate(cd, 0, Z_SYNC_FLUSH, errorCodePtr) < 0) { goto error; } @@ -2461,7 +2462,7 @@ ZlibTransformInput( * iteration will put it into the result. */ - if (ResultGenerate (cd, readBytes, Z_NO_FLUSH, errorCodePtr) < 0) { + if (ResultGenerate(cd, readBytes, Z_NO_FLUSH, errorCodePtr) < 0) { goto error; } } /* while toRead > 0 */ @@ -2914,54 +2915,71 @@ ZlibStackChannelTransform( static int ResultCopy( - Tcl_DString* ds, /* The buffer to read from */ + Tcl_DString *ds, /* The buffer to read from */ unsigned char *buf, /* The buffer to copy into */ int toRead) /* Number of requested bytes */ { - int copied; - int have = Tcl_DStringLength (ds); + int have = Tcl_DStringLength(ds); if (have == 0) { /* * Nothing to copy in the case of an empty buffer. */ - copied = 0; - } else if (have > toRead) { + return 0; + } + if (have > toRead) { /* * The internal buffer contains more than requested. Copy the * requested subset to the caller, shift the remaining bytes down, and * truncate. */ - char* src = Tcl_DStringValue (ds); + char *src = Tcl_DStringValue(ds); memcpy(buf, src, toRead); memmove(src, src + toRead, have - toRead); - Tcl_DStringSetLength (ds, have - toRead); - copied = toRead; + Tcl_DStringSetLength(ds, have - toRead); + return toRead; } else /* have <= toRead */ { /* * There is just or not enough in the buffer to fully satisfy the * caller, so take everything as best effort. */ - memcpy(buf, Tcl_DStringValue (ds), have); - Tcl_DStringSetLength (ds, 0); - copied = have; + memcpy(buf, Tcl_DStringValue(ds), have); + Tcl_DStringSetLength(ds, 0); + return have; } - - /* -- common postwork code ------- */ - - return copied; } +/* + *---------------------------------------------------------------------- + * + * ResultGenerate -- + * + * Extract uncompressed bytes from the compression engine and store them + * in our working buffer. + * + * Result: + * Zero on success, -1 on error (with *errorCodePtr updated with reason). + * + * Side effects: + * See above. + * + *---------------------------------------------------------------------- + */ + static int -ResultGenerate(ZlibChannelData *cd, int n, int flush, int* errorCodePtr) +ResultGenerate( + ZlibChannelData *cd, + int n, + int flush, + int *errorCodePtr) { -#define MAXBUF 1024 - unsigned char buf [MAXBUF]; +#define MAXBUF 1024 + unsigned char buf[MAXBUF]; int e, written; cd->inStream.next_in = (Bytef *) cd->inBuffer; @@ -2974,21 +2992,23 @@ ResultGenerate(ZlibChannelData *cd, int n, int flush, int* errorCodePtr) e = inflate(&cd->inStream, flush); /* - * avail_out is now the left over space in the output. - * Therefore "MAXBUF - avail_out" is the amount of bytes - * generated. + * avail_out is now the left over space in the output. Therefore + * "MAXBUF - avail_out" is the amount of bytes generated. */ written = MAXBUF - cd->inStream.avail_out; - if (written) { - Tcl_DStringAppend (&cd->result, (char*) buf, written); + Tcl_DStringAppend(&cd->result, (char*) buf, written); } - if (((flush == Z_SYNC_FLUSH) && (e == Z_BUF_ERROR)) || - (e == Z_STREAM_END) || - (e==Z_OK && cd->inStream.avail_out==0)) { - break; + /* + * The cases where we're definitely done. + */ + + if (((flush == Z_SYNC_FLUSH) && (e == Z_BUF_ERROR)) + || (e == Z_STREAM_END) + || (e == Z_OK && cd->inStream.avail_out == 0)) { + return 0; } /* @@ -2996,13 +3016,15 @@ ResultGenerate(ZlibChannelData *cd, int n, int flush, int* errorCodePtr) * * Just indicates that the zlib couldn't consume input/produce output, * and is fixed by supplying more input. + * + * Otherwise, we've got errors and need to report to higher-up. */ if ((e != Z_OK) && (e != Z_BUF_ERROR)) { Tcl_Obj *errObj = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(NULL, errObj, - Tcl_NewStringObj(cd->inStream.msg, -1)); + Tcl_NewStringObj(cd->inStream.msg, -1)); Tcl_SetChannelError(cd->parent, errObj); *errorCodePtr = EINVAL; return -1; @@ -3012,18 +3034,10 @@ ResultGenerate(ZlibChannelData *cd, int n, int flush, int* errorCodePtr) * Check if the inflate stopped early. */ - if (cd->inStream.avail_in > 0) { - continue; - } - - if (flush == Z_SYNC_FLUSH) { - continue; + if (cd->inStream.avail_in <= 0 && flush != Z_SYNC_FLUSH) { + return 0; } - - break; } - - return 0; } /* |
