diff options
-rw-r--r-- | generic/tcl.decls | 4 | ||||
-rw-r--r-- | generic/tclDecls.h | 5 | ||||
-rw-r--r-- | generic/tclStubInit.c | 1 | ||||
-rw-r--r-- | generic/tclZlib.c | 90 |
4 files changed, 98 insertions, 2 deletions
diff --git a/generic/tcl.decls b/generic/tcl.decls index 70e848f..c6cbe96 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2318,6 +2318,10 @@ declare 629 { int Tcl_FSUnloadFile(Tcl_Interp *interp, Tcl_LoadHandle handlePtr) } +declare 630 { + void* Tcl_ZlibStreamGetZstreamp(Tcl_ZlibStream zshandle) +} + # ----- BASELINE -- FOR -- 8.6.0 ----- # ############################################################################## diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 75dbd9a..0c1dedf 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1807,6 +1807,8 @@ EXTERN void * Tcl_FindSymbol(Tcl_Interp *interp, /* 629 */ EXTERN int Tcl_FSUnloadFile(Tcl_Interp *interp, Tcl_LoadHandle handlePtr); +/* 630 */ +EXTERN void* Tcl_ZlibStreamGetZstreamp(Tcl_ZlibStream zshandle); typedef struct TclStubHooks { const struct TclPlatStubs *tclPlatStubs; @@ -2472,6 +2474,7 @@ typedef struct TclStubs { int (*tcl_LoadFile) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *const symv[], int flags, void *procPtrs, Tcl_LoadHandle *handlePtr); /* 627 */ void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */ int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ + void* (*tcl_ZlibStreamGetZstreamp) (Tcl_ZlibStream zshandle); /* 630 */ } TclStubs; #ifdef __cplusplus @@ -3764,6 +3767,8 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tcl_FindSymbol) /* 628 */ #define Tcl_FSUnloadFile \ (tclStubsPtr->tcl_FSUnloadFile) /* 629 */ +#define Tcl_ZlibStreamGetZstreamp \ + (tclStubsPtr->tcl_ZlibStreamGetZstreamp) /* 630 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 0fe2ccc..3f2f929 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -1306,6 +1306,7 @@ const TclStubs tclStubs = { Tcl_LoadFile, /* 627 */ Tcl_FindSymbol, /* 628 */ Tcl_FSUnloadFile, /* 629 */ + Tcl_ZlibStreamGetZstreamp, /* 630 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 81012dc..85c6655 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -64,6 +64,9 @@ typedef struct { int wbits; /* The encoded compression mode, so we can * restart the stream if necessary. */ Tcl_Command cmd; /* Token for the associated Tcl command. */ + Tcl_Obj *compDictObj; /* Byte-array object containing compression + * dictionary (not dictObj!) to use if + * necessary. */ } ZlibStreamHandle; /* @@ -209,6 +212,7 @@ ConvertError( case Z_MEM_ERROR: codeStr = "MEM"; break; case Z_BUF_ERROR: codeStr = "BUF"; break; case Z_VERSION_ERROR: codeStr = "VERSION"; break; + case Z_NEED_DICT: codeStr = "NEED_DICT"; break; default: codeStr = "unknown"; codeStr2 = codeStrBuf; @@ -542,6 +546,7 @@ Tcl_ZlibStreamInit( zshPtr->wbits = wbits; zshPtr->currentInput = NULL; zshPtr->streamEnd = 0; + zshPtr->compDictObj = NULL; memset(&zshPtr->stream, 0, sizeof(z_stream)); /* @@ -551,6 +556,14 @@ Tcl_ZlibStreamInit( if (mode == TCL_ZLIB_STREAM_DEFLATE) { e = deflateInit2(&zshPtr->stream, level, Z_DEFLATED, wbits, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); + if (e == Z_OK && zshPtr->compDictObj) { + int dictLen; + unsigned char *dictBytes = + Tcl_GetByteArrayFromObj(zshPtr->compDictObj, &dictLen); + + e = deflateSetDictionary(&zshPtr->stream, dictBytes, + (unsigned) dictLen); + } } else { e = inflateInit2(&zshPtr->stream, wbits); } @@ -618,6 +631,9 @@ Tcl_ZlibStreamInit( return TCL_OK; error: + if (zshPtr->compDictObj) { + Tcl_DecrRefCount(zshPtr->compDictObj); + } ckfree(zshPtr); return TCL_ERROR; } @@ -725,6 +741,9 @@ ZlibStreamCleanup( if (zshPtr->currentInput) { Tcl_DecrRefCount(zshPtr->currentInput); } + if (zshPtr->compDictObj) { + Tcl_DecrRefCount(zshPtr->compDictObj); + } ckfree(zshPtr); } @@ -777,6 +796,14 @@ Tcl_ZlibStreamReset( if (zshPtr->mode == TCL_ZLIB_STREAM_DEFLATE) { e = deflateInit2(&zshPtr->stream, zshPtr->level, Z_DEFLATED, zshPtr->wbits, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); + if (e == Z_OK && zshPtr->compDictObj) { + int dictLen; + unsigned char *dictBytes = + Tcl_GetByteArrayFromObj(zshPtr->compDictObj, &dictLen); + + e = deflateSetDictionary(&zshPtr->stream, dictBytes, + (unsigned) dictLen); + } } else { e = inflateInit2(&zshPtr->stream, zshPtr->wbits); } @@ -875,6 +902,27 @@ Tcl_ZlibStreamChecksum( /* *---------------------------------------------------------------------- * + * Tcl_ZlibStreamGetZstreamp -- + * + * Return the z_streamp for the stream (though not typed as such, so as + * to avoid type interface poisoning). Shouldn't be used to poke around + * excessively. + * + *---------------------------------------------------------------------- + */ + +void * +Tcl_ZlibStreamGetZstreamp( + Tcl_ZlibStream zshandle) +{ + ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle; + + return &zshPtr->stream; +} + +/* + *---------------------------------------------------------------------- + * * Tcl_ZlibStreamPut -- * * Add data to the stream for compression or decompression from a @@ -1070,7 +1118,22 @@ Tcl_ZlibStreamGet( } } - e = inflate(&zshPtr->stream, zshPtr->flush); + while (1) { + e = inflate(&zshPtr->stream, zshPtr->flush); + if (e != Z_NEED_DICT || zshPtr->compDictObj == NULL) { + break; + } else { + int dictLen; + unsigned char *dictBytes = + Tcl_GetByteArrayFromObj(zshPtr->compDictObj,&dictLen); + + e = inflateSetDictionary(&zshPtr->stream, dictBytes, + (unsigned) dictLen); + if (e != Z_OK) { + break; + } + } + } Tcl_ListObjLength(NULL, zshPtr->inData, &listLen); while ((zshPtr->stream.avail_out > 0) @@ -1124,7 +1187,23 @@ Tcl_ZlibStreamGet( * And call inflate again. */ - e = inflate(&zshPtr->stream, zshPtr->flush); + while (1) { + e = inflate(&zshPtr->stream, zshPtr->flush); + if (e != Z_NEED_DICT || zshPtr->compDictObj == NULL) { + break; + } else { + int dictLen; + unsigned char *dictBytes = + Tcl_GetByteArrayFromObj(zshPtr->compDictObj, + &dictLen); + + e = inflateSetDictionary(&zshPtr->stream, dictBytes, + (unsigned) dictLen); + if (e != Z_OK) { + break; + } + } + } } if (zshPtr->stream.avail_out > 0) { Tcl_SetByteArrayLength(data, @@ -2973,6 +3052,13 @@ Tcl_ZlibAdler32( { return 0; } + +void * +Tcl_ZlibStreamGetZstreamp( + Tcl_ZlibStream zshandle) +{ + return NULL; +} #endif /* HAVE_ZLIB */ /* |