summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2008-12-27 00:04:17 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2008-12-27 00:04:17 (GMT)
commit1ea51e1fb6fb072c84c166e0831423b0c323558b (patch)
tree57f18763c75d42d79883e11d7b17d1f4777758a1
parentb6fef736bd2db96d477934cb11d401e2fe85abbc (diff)
downloadtcl-1ea51e1fb6fb072c84c166e0831423b0c323558b.zip
tcl-1ea51e1fb6fb072c84c166e0831423b0c323558b.tar.gz
tcl-1ea51e1fb6fb072c84c166e0831423b0c323558b.tar.bz2
Assorted minor corrections to the Zlib C API to make it work with the PNG
implementation better.
-rw-r--r--ChangeLog13
-rw-r--r--doc/TclZlib.339
-rw-r--r--generic/tcl.decls4
-rw-r--r--generic/tclDecls.h16
-rw-r--r--generic/tclStubInit.c4
-rw-r--r--generic/tclZlib.c85
6 files changed, 91 insertions, 70 deletions
diff --git a/ChangeLog b/ChangeLog
index 03aa530..9daefa6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2008-12-27 Donal K. Fellows <dkf@users.sf.net>
+
+ * generic/tclZlib.c (Tcl_ZlibStreamGet): Corrected the semantics of
+ this function to be useful to the PNG implementation. If the argument
+ object is empty, this gives the previous semantics.
+ (Tcl_ZlibStreamChecksum): Corrected name to be less misleading; it
+ only produced Adler-32 checksums when the stream was processing the
+ right type of compressed data format.
+ (Tcl_ZlibAdler32, Tcl_ZlibCRC32): Corrected types so that they work
+ naturally with the results of Tcl_GetByteArrayFromObj().
+ *** POTENTIAL INCOMPATIBILITY *** for all above changes, but very
+ unlikely to be difficult for anyone to deal with.
+
2008-12-26 Donal K. Fellows <dkf@users.sf.net>
* generic/tcl.decls: Tidy up the commenting style, adding markers for
diff --git a/doc/TclZlib.3 b/doc/TclZlib.3
index 1b2bb44..42d82b5 100644
--- a/doc/TclZlib.3
+++ b/doc/TclZlib.3
@@ -4,14 +4,14 @@
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
-'\" RCS: @(#) $Id: TclZlib.3,v 1.3 2008/12/21 08:17:37 dkf Exp $
+'\" RCS: @(#) $Id: TclZlib.3,v 1.4 2008/12/27 00:04:17 dkf Exp $
'\"
.so man.macros
.TH TclZlib 3 8.6 Tcl "Tcl Library Procedures"
.BS
'\" Note: do not modify the .SH NAME line immediately below!
.SH NAME
-Tcl_ZlibAdler32, Tcl_ZlibCRC32, Tcl_ZlibDeflate, Tcl_ZlibInflate, Tcl_ZlibStreamAdler32, Tcl_ZlibStreamClose, Tcl_ZlibStreamEof, Tcl_ZlibStreamGet, Tcl_ZlibStreamGetCommandName, Tcl_ZlibStreamInit, Tcl_ZlibStreamPut \- compression and decompression functions
+Tcl_ZlibAdler32, Tcl_ZlibCRC32, Tcl_ZlibDeflate, Tcl_ZlibInflate, Tcl_ZlibStreamChecksum, Tcl_ZlibStreamClose, Tcl_ZlibStreamEof, Tcl_ZlibStreamGet, Tcl_ZlibStreamGetCommandName, Tcl_ZlibStreamInit, Tcl_ZlibStreamPut \- compression and decompression functions
.SH SYNOPSIS
.nf
#include <tcl.h>
@@ -41,7 +41,7 @@ int
\fBTcl_ZlibStreamClose\fR(\fIzshandle\fR)
.sp
int
-\fBTcl_ZlibStreamAdler32\fR(\fIzshandle\fR)
+\fBTcl_ZlibStreamChecksum\fR(\fIzshandle\fR)
.sp
int
\fBTcl_ZlibStreamPut\fR(\fIzshandle, dataObj, flush\fR)
@@ -53,7 +53,8 @@ int
.AS Tcl_ZlibStream *zshandlePtr out
.AP Tcl_Interp *interp in
The interpreter to store resulting compressed or uncompressed data in. Also
-where any error messages are written.
+where any error messages are written. For \fBTcl_ZlibStreamInit\fR, this can
+be NULL to create a stream that is not bound to a command.
.AP int format in
What format of compressed data to work with. Must be one of
\fBTCL_ZLIB_FORMAT_ZLIB\fR for zlib-format data, \fBTCL_ZLIB_FORMAT_GZIP\fR
@@ -63,7 +64,7 @@ chosen which can automatically detect whether the compressed data was in zlib
or gzip format.
.AP Tcl_Obj *dataObj in/out
A byte-array object containing the data to be compressed or decompressed, or
-which is set to the data extracted from the stream when passed to
+to which the data extracted from the stream is appended when passed to
\fBTcl_ZlibStreamGet\fR.
.AP int level in
What level of compression to use. Should be a number from 0 to 9 or one of the
@@ -122,18 +123,28 @@ bytes. Typical usage is:
.CS
checksum = \fBTcl_ZlibCRC32\fR(\fBTcl_ZlibCRC32\fR(0,NULL,0), data, length);
.CE
+.SS "ZLIB STREAMS"
.PP
\fBTcl_ZlibStreamInit\fR creates a compressing or decompressing stream that is
linked to a Tcl command, according to its arguments, and provides an abstract
-token for the stream; \fBTcl_ZlibStreamGetCommandName\fR returns the name of
-that command given the stream token. Once a stream has been constructed,
-\fBTcl_ZlibStreamPut\fR is used to add data to the stream and
-\fBTcl_ZlibStreamGet\fR is used to retrieve data from the stream after
-processing. \fBTcl_ZlibStreamAdler32\fR returns the checksum computed over the
-uncompressed data, and \fBTcl_ZlibStreamEof\fR returns whether the end of the
-uncompressed data has been reached. Finally, \fBTcl_ZlibStreamClose\fR will
-clean up the stream and delete the associated command: using
-\fBTcl_DeleteCommand\fR on the stream's command is equivalent.
+token for the stream and returns a normal Tcl result code;
+\fBTcl_ZlibStreamGetCommandName\fR returns the name of that command given the
+stream token, or NULL if the stream has no command.
+.PP
+Once a stream has been constructed, \fBTcl_ZlibStreamPut\fR is used to add
+data to the stream and \fBTcl_ZlibStreamGet\fR is used to retrieve data from
+the stream after processing. Both return normal Tcl result codes. With
+\fBTcl_ZlibStreamPut\fR, the data buffer object passed to it should not be
+modified afterwards. With \fBTcl_ZlibStreamGet\fR, the data buffer object
+passed to it will have the data bytes appended to it.
+.PP
+\fBTcl_ZlibStreamChecksum\fR returns the checksum computed over the
+uncompressed data according to the format, and \fBTcl_ZlibStreamEof\fR returns
+whether the end of the uncompressed data has been reached.
+.PP
+Finally, \fBTcl_ZlibStreamClose\fR will clean up the stream and delete the
+associated command: using \fBTcl_DeleteCommand\fR on the stream's command is
+equivalent.
.SH "PORTABILITY NOTES"
These functions will fail gracefully if Tcl is not linked with the zlib
library.
diff --git a/generic/tcl.decls b/generic/tcl.decls
index 5a4b322..dff3242 100644
--- a/generic/tcl.decls
+++ b/generic/tcl.decls
@@ -12,7 +12,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: tcl.decls,v 1.165 2008/12/26 09:51:11 dkf Exp $
+# RCS: @(#) $Id: tcl.decls,v 1.166 2008/12/27 00:04:17 dkf Exp $
library tcl
@@ -2265,7 +2265,7 @@ declare 616 generic {
int Tcl_ZlibStreamEof(Tcl_ZlibStream zshandle)
}
declare 617 generic {
- int Tcl_ZlibStreamAdler32(Tcl_ZlibStream zshandle)
+ int Tcl_ZlibStreamChecksum(Tcl_ZlibStream zshandle)
}
declare 618 generic {
int Tcl_ZlibStreamPut(Tcl_ZlibStream zshandle, Tcl_Obj *data, int flush)
diff --git a/generic/tclDecls.h b/generic/tclDecls.h
index e2e4366..74284ed 100644
--- a/generic/tclDecls.h
+++ b/generic/tclDecls.h
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclDecls.h,v 1.166 2008/12/18 06:40:02 nijtmans Exp $
+ * RCS: @(#) $Id: tclDecls.h,v 1.167 2008/12/27 00:04:17 dkf Exp $
*/
#ifndef _TCLDECLS
@@ -3731,10 +3731,10 @@ EXTERN Tcl_Obj * Tcl_ZlibStreamGetCommandName (
/* 616 */
EXTERN int Tcl_ZlibStreamEof (Tcl_ZlibStream zshandle);
#endif
-#ifndef Tcl_ZlibStreamAdler32_TCL_DECLARED
-#define Tcl_ZlibStreamAdler32_TCL_DECLARED
+#ifndef Tcl_ZlibStreamChecksum_TCL_DECLARED
+#define Tcl_ZlibStreamChecksum_TCL_DECLARED
/* 617 */
-EXTERN int Tcl_ZlibStreamAdler32 (Tcl_ZlibStream zshandle);
+EXTERN int Tcl_ZlibStreamChecksum (Tcl_ZlibStream zshandle);
#endif
#ifndef Tcl_ZlibStreamPut_TCL_DECLARED
#define Tcl_ZlibStreamPut_TCL_DECLARED
@@ -4451,7 +4451,7 @@ typedef struct TclStubs {
int (*tcl_ZlibStreamInit) (Tcl_Interp * interp, int mode, int format, int level, Tcl_Obj * dictObj, Tcl_ZlibStream * zshandle); /* 614 */
Tcl_Obj * (*tcl_ZlibStreamGetCommandName) (Tcl_ZlibStream zshandle); /* 615 */
int (*tcl_ZlibStreamEof) (Tcl_ZlibStream zshandle); /* 616 */
- int (*tcl_ZlibStreamAdler32) (Tcl_ZlibStream zshandle); /* 617 */
+ int (*tcl_ZlibStreamChecksum) (Tcl_ZlibStream zshandle); /* 617 */
int (*tcl_ZlibStreamPut) (Tcl_ZlibStream zshandle, Tcl_Obj * data, int flush); /* 618 */
int (*tcl_ZlibStreamGet) (Tcl_ZlibStream zshandle, Tcl_Obj * data, int count); /* 619 */
int (*tcl_ZlibStreamClose) (Tcl_ZlibStream zshandle); /* 620 */
@@ -6999,9 +6999,9 @@ extern const TclStubs *tclStubsPtr;
#define Tcl_ZlibStreamEof \
(tclStubsPtr->tcl_ZlibStreamEof) /* 616 */
#endif
-#ifndef Tcl_ZlibStreamAdler32
-#define Tcl_ZlibStreamAdler32 \
- (tclStubsPtr->tcl_ZlibStreamAdler32) /* 617 */
+#ifndef Tcl_ZlibStreamChecksum
+#define Tcl_ZlibStreamChecksum \
+ (tclStubsPtr->tcl_ZlibStreamChecksum) /* 617 */
#endif
#ifndef Tcl_ZlibStreamPut
#define Tcl_ZlibStreamPut \
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index 926a45d..818abf1 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclStubInit.c,v 1.177 2008/12/18 04:38:01 dgp Exp $
+ * RCS: @(#) $Id: tclStubInit.c,v 1.178 2008/12/27 00:04:17 dkf Exp $
*/
#include "tclInt.h"
@@ -1142,7 +1142,7 @@ static const TclStubs tclStubs = {
Tcl_ZlibStreamInit, /* 614 */
Tcl_ZlibStreamGetCommandName, /* 615 */
Tcl_ZlibStreamEof, /* 616 */
- Tcl_ZlibStreamAdler32, /* 617 */
+ Tcl_ZlibStreamChecksum, /* 617 */
Tcl_ZlibStreamPut, /* 618 */
Tcl_ZlibStreamGet, /* 619 */
Tcl_ZlibStreamClose, /* 620 */
diff --git a/generic/tclZlib.c b/generic/tclZlib.c
index 4fc56e1..8db482a 100644
--- a/generic/tclZlib.c
+++ b/generic/tclZlib.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclZlib.c,v 1.18 2008/12/22 01:39:33 patthoyts Exp $
+ * RCS: @(#) $Id: tclZlib.c,v 1.19 2008/12/27 00:04:17 dkf Exp $
*/
#include "tclInt.h"
@@ -818,8 +818,13 @@ Tcl_ZlibStreamGetCommandName(
Tcl_ZlibStream zshandle) /* as obtained from Tcl_ZlibStreamInit */
{
ZlibStreamHandle *zsh = (ZlibStreamHandle *) zshandle;
- Tcl_Obj *objPtr = Tcl_NewObj();
+ Tcl_Obj *objPtr;
+ if (!zsh->interp) {
+ return NULL;
+ }
+
+ TclNewObj(objPtr);
Tcl_GetCommandFullName(zsh->interp, zsh->cmd, objPtr);
return objPtr;
}
@@ -855,7 +860,7 @@ Tcl_ZlibStreamEof(
/*
*----------------------------------------------------------------------
*
- * Tcl_ZlibStreamAdler32 --
+ * Tcl_ZlibStreamChecksum --
*
* Return the checksum of the uncompressed data seen so far by the
* stream.
@@ -864,7 +869,7 @@ Tcl_ZlibStreamEof(
*/
int
-Tcl_ZlibStreamAdler32(
+Tcl_ZlibStreamChecksum(
Tcl_ZlibStream zshandle) /* As obtained from Tcl_ZlibStreamInit */
{
ZlibStreamHandle *zsh = (ZlibStreamHandle *) zshandle;
@@ -877,7 +882,8 @@ Tcl_ZlibStreamAdler32(
*
* Tcl_ZlibStreamPut --
*
- * Add data to the stream for compression or decompression.
+ * Add data to the stream for compression or decompression from a
+ * bytearray Tcl_Obj.
*
*----------------------------------------------------------------------
*/
@@ -929,7 +935,7 @@ Tcl_ZlibStreamPut(
* Now append the compressed data to the outData list.
*/
- Tcl_ListObjAppendElement(zsh->interp, zsh->outData, obj);
+ Tcl_ListObjAppendElement(NULL, zsh->outData, obj);
}
if (outSize < 0xFFFF) {
outSize = 0xFFFF; /* There may be *lots* of data left to
@@ -955,14 +961,14 @@ Tcl_ZlibStreamPut(
* Now append the compressed data to the outData list.
*/
- Tcl_ListObjAppendElement(zsh->interp, zsh->outData, obj);
+ Tcl_ListObjAppendElement(NULL, zsh->outData, obj);
}
} else {
/*
* This is easy. Just append to the inData list.
*/
- Tcl_ListObjAppendElement(zsh->interp, zsh->inData, data);
+ Tcl_ListObjAppendElement(NULL, zsh->inData, data);
/*
* and we'll need the flush parameter for the Inflate call.
@@ -979,7 +985,8 @@ Tcl_ZlibStreamPut(
*
* Tcl_ZlibStreamGet --
*
- * Retrieve data (now compressed or decompressed) from the stream.
+ * Retrieve data (now compressed or decompressed) from the stream into a
+ * bytearray Tcl_Obj.
*
*----------------------------------------------------------------------
*/
@@ -987,7 +994,7 @@ Tcl_ZlibStreamPut(
int
Tcl_ZlibStreamGet(
Tcl_ZlibStream zshandle, /* As obtained from Tcl_ZlibStreamInit */
- Tcl_Obj *data, /* A place to put the data */
+ Tcl_Obj *data, /* A place to append the data. */
int count) /* Number of bytes to grab as a maximum, you
* may get less! */
{
@@ -995,6 +1002,7 @@ Tcl_ZlibStreamGet(
int e, i, listLen, itemLen, dataPos = 0;
Tcl_Obj *itemObj;
unsigned char *dataPtr, *itemPtr;
+ int existing;
/*
* Getting beyond the of stream, just return empty string.
@@ -1004,6 +1012,8 @@ Tcl_ZlibStreamGet(
return TCL_OK;
}
+ (void) Tcl_GetByteArrayFromObj(data, &existing);
+
if (zsh->mode == TCL_ZLIB_STREAM_INFLATE) {
if (count == -1) {
/*
@@ -1018,7 +1028,8 @@ Tcl_ZlibStreamGet(
* Prepare the place to store the data.
*/
- dataPtr = Tcl_SetByteArrayLength(data, count);
+ dataPtr = Tcl_SetByteArrayLength(data, existing+count);
+ dataPtr += existing;
zsh->stream.next_out = dataPtr;
zsh->stream.avail_out = count;
@@ -1031,20 +1042,14 @@ Tcl_ZlibStreamGet(
Tcl_DecrRefCount(zsh->currentInput);
zsh->currentInput = NULL;
}
- if (Tcl_ListObjLength(zsh->interp, zsh->inData,
- &listLen) != TCL_OK) {
- return TCL_ERROR;
- }
+ Tcl_ListObjLength(NULL, zsh->inData, &listLen);
if (listLen > 0) {
/*
* There is more input available, get it from the list and
* give it to zlib.
*/
- if (Tcl_ListObjIndex(zsh->interp, zsh->inData, 0,
- &itemObj) != TCL_OK) {
- return TCL_ERROR;
- }
+ Tcl_ListObjIndex(NULL, zsh->inData, 0, &itemObj);
itemPtr = Tcl_GetByteArrayFromObj(itemObj, &itemLen);
Tcl_IncrRefCount(itemObj);
zsh->currentInput = itemObj;
@@ -1061,11 +1066,9 @@ Tcl_ZlibStreamGet(
}
e = inflate(&zsh->stream, zsh->flush);
- if (Tcl_ListObjLength(zsh->interp, zsh->inData, &listLen) != TCL_OK) {
- return TCL_ERROR;
- }
+ Tcl_ListObjLength(NULL, zsh->inData, &listLen);
- while ((zsh->stream.avail_out > 0) && (e==Z_OK || e==Z_BUF_ERROR)
+ while ((zsh->stream.avail_out > 0) && (e == Z_OK || e == Z_BUF_ERROR)
&& (listLen > 0)) {
/*
* State: We have not satisfied the request yet and there may be
@@ -1078,6 +1081,7 @@ Tcl_ZlibStreamGet(
"Unexpected zlib internal state during decompression",
TCL_STATIC);
}
+ Tcl_SetByteArrayLength(data, existing);
return TCL_ERROR;
}
@@ -1086,10 +1090,7 @@ Tcl_ZlibStreamGet(
zsh->currentInput = 0;
}
- if (Tcl_ListObjIndex(zsh->interp, zsh->inData, 0,
- &itemObj) != TCL_OK) {
- return TCL_ERROR;
- }
+ Tcl_ListObjIndex(zsh->interp, zsh->inData, 0, &itemObj);
itemPtr = Tcl_GetByteArrayFromObj(itemObj, &itemLen);
Tcl_IncrRefCount(itemObj);
zsh->currentInput = itemObj;
@@ -1110,9 +1111,11 @@ Tcl_ZlibStreamGet(
e = inflate(&zsh->stream, zsh->flush);
}
if (zsh->stream.avail_out > 0) {
- Tcl_SetByteArrayLength(data, count - zsh->stream.avail_out);
+ Tcl_SetByteArrayLength(data,
+ existing + count - zsh->stream.avail_out);
}
if (!(e==Z_OK || e==Z_STREAM_END || e==Z_BUF_ERROR)) {
+ Tcl_SetByteArrayLength(data, existing);
ConvertError(zsh->interp, e);
return TCL_ERROR;
}
@@ -1125,18 +1128,11 @@ Tcl_ZlibStreamGet(
inflateEnd(&zsh->stream);
}
} else {
- if (Tcl_ListObjLength(zsh->interp, zsh->outData,
- &listLen) != TCL_OK) {
- return TCL_ERROR;
- }
-
+ Tcl_ListObjLength(NULL, zsh->outData, &listLen);
if (count == -1) {
count = 0;
for (i=0; i<listLen; i++) {
- if (Tcl_ListObjIndex(zsh->interp, zsh->outData, i,
- &itemObj) != TCL_OK) {
- return TCL_ERROR;
- }
+ Tcl_ListObjIndex(NULL, zsh->outData, i, &itemObj);
itemPtr = Tcl_GetByteArrayFromObj(itemObj, &itemLen);
if (i == 0) {
count += itemLen - zsh->outPos;
@@ -1150,11 +1146,12 @@ Tcl_ZlibStreamGet(
* Prepare the place to store the data.
*/
- dataPtr = Tcl_SetByteArrayLength(data, count);
+ dataPtr = Tcl_SetByteArrayLength(data, existing + count);
+ dataPtr += existing;
- while ((count > dataPos) && (Tcl_ListObjLength(zsh->interp,
- zsh->outData, &listLen) == TCL_OK) && (listLen > 0)) {
- Tcl_ListObjIndex(zsh->interp, zsh->outData, 0, &itemObj);
+ while ((count > dataPos) && (Tcl_ListObjLength(NULL, zsh->outData,
+ &listLen) == TCL_OK) && (listLen > 0)) {
+ Tcl_ListObjIndex(NULL, zsh->outData, 0, &itemObj);
itemPtr = Tcl_GetByteArrayFromObj(itemObj, &itemLen);
if (itemLen-zsh->outPos >= count-dataPos) {
unsigned len = count - dataPos;
@@ -1177,7 +1174,7 @@ Tcl_ZlibStreamGet(
listLen--;
}
}
- Tcl_SetByteArrayLength(data, dataPos);
+ Tcl_SetByteArrayLength(data, existing + dataPos);
}
return TCL_OK;
}
@@ -1537,7 +1534,7 @@ Tcl_ZlibInflate(
unsigned int
Tcl_ZlibCRC32(
unsigned int crc,
- const char *buf,
+ const unsigned char *buf,
int len)
{
/* Nothing much to do, just wrap the crc32(). */
@@ -1547,7 +1544,7 @@ Tcl_ZlibCRC32(
unsigned int
Tcl_ZlibAdler32(
unsigned int adler,
- const char *buf,
+ const unsigned char *buf,
int len)
{
return adler32(adler, (Bytef *) buf, (unsigned) len);