summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tcl.decls4
-rw-r--r--generic/tclDecls.h5
-rw-r--r--generic/tclStubInit.c1
-rw-r--r--generic/tclZlib.c90
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 */
/*