#include <tcl.h> int Tcl_ZlibDeflate(interp, format, dataObj, level, dictObj) int Tcl_ZlibInflate(interp, format, dataObj, dictObj) unsigned int Tcl_ZlibCRC32(initValue, bytes, length) unsigned int Tcl_ZlibAdler32(initValue, bytes, length) int Tcl_ZlibStreamInit(interp, mode, format, level, dictObj, zshandlePtr) Tcl_Obj * Tcl_ZlibStreamGetCommandName(zshandle) int Tcl_ZlibStreamEof(zshandle) int Tcl_ZlibStreamClose(zshandle) int Tcl_ZlibStreamReset(zshandle) int Tcl_ZlibStreamChecksum(zshandle) int Tcl_ZlibStreamPut(zshandle, dataObj, flush) int Tcl_ZlibStreamGet(zshandle, dataObj, count) Tcl_ZlibStreamSetCompressionDictionary(zshandle, compDict)
Tcl_ZlibDeflate and Tcl_ZlibInflate respectively compress and decompress the data contained in the dataObj argument, according to the format and, for compression, level arguments. The dictionary in the dictObj parameter is used to convey additional header information about the compressed data when the compression format supports it; currently, the dictionary is only used when the format parameter is TCL_ZLIB_FORMAT_GZIP or TCL_ZLIB_FORMAT_AUTO. For details of the contents of the dictionary, see the GZIP OPTIONS DICTIONARY section below. Upon success, both functions leave the resulting compressed or decompressed data in a byte-array value that is the Tcl interpreter's result; the returned value is a standard Tcl result code.
Tcl_ZlibAdler32 and Tcl_ZlibCRC32 compute checksums on arrays of bytes, returning the computed checksum. Checksums are computed incrementally, allowing data to be processed one block at a time, but this requires the caller to maintain the current checksum and pass it in as the initValue parameter; the initial value to use for this can be obtained by using NULL for the bytes parameter instead of a pointer to the array of bytes to compute the checksum over. Thus, typical usage in the single data block case is like this:
checksum = Tcl_ZlibCRC32(Tcl_ZlibCRC32(0,NULL,0), data, length);
Note that the Adler-32 algorithm is not a real checksum, but instead is a related type of hash that works best on longer data.
Tcl_ZlibStreamInit 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 and returns a normal Tcl result code; Tcl_ZlibStreamGetCommandName returns the name of that command given the stream token, or NULL if the stream has no command. Streams are not designed to be thread-safe; each stream should only ever be used from the thread that created it. When working with gzip streams, a dictionary (fields as given in the GZIP OPTIONS DICTIONARY section below) can be given via the dictObj parameter that on compression allows control over the generated headers, and on decompression allows discovery of the existing headers. Note that the dictionary will be written to on decompression once sufficient data has been read to have a complete header. This means that the dictionary must be an unshared value in that case; a blank value created with Tcl_NewObj is suggested.
Once a stream has been constructed, Tcl_ZlibStreamPut is used to add data to the stream and Tcl_ZlibStreamGet is used to retrieve data from the stream after processing. Both return normal Tcl result codes and leave an error message in the result of the interpreter that the stream is registered with in the error case (if such a registration has been performed). With Tcl_ZlibStreamPut, the data buffer value passed to it should not be modified afterwards. With Tcl_ZlibStreamGet, the data buffer value passed to it will have the data bytes appended to it. Internally to the stream, data is kept compressed so as to minimize the cost of buffer space.
Tcl_ZlibStreamChecksum returns the checksum computed over the uncompressed data according to the format, and Tcl_ZlibStreamEof returns a boolean value indicating whether the end of the uncompressed data has been reached.
Tcl_ZlibStreamSetCompressionDictionary is used to control the compression dictionary used with the stream, a compression dictionary being an array of bytes (such as might be created with Tcl_NewByteArrayObj) that is used to initialize the compression engine rather than leaving it to create it on the fly from the data being compressed. Setting a compression dictionary allows for more efficient compression in the case where the start of the data is highly regular, but it does require both the compressor and the decompressor to agreee on the value to use. Compression dictionaries are only fully supported for zlib-format data; on compression, they must be set before any data is sent in with Tcl_ZlibStreamPut, and on decompression they should be set when Tcl_ZlibStreamGet produces an error with its -errorcode set to ``ZLIB NEED_DICT code''; the code will be the Adler-32 checksum (see Tcl_ZlibAdler32) of the compression dictionary sought. (Note that this is only true for zlib-format streams; gzip streams ignore compression dictionaries as the format specification doesn't permit them, and raw streams just produce a data error if the compression dictionary is missing or incorrect.)
If you wish to clear a stream and reuse it for a new compression or decompression action, Tcl_ZlibStreamReset will do this and return a normal Tcl result code to indicate whether it was successful; if the stream is registered with an interpreter, an error message will be left in the interpreter result when this function returns TCL_ERROR. Finally, Tcl_ZlibStreamClose will clean up the stream and delete the associated command: using Tcl_DeleteCommand on the stream's command is equivalent (when such a command exists).
The dictObj parameter to Tcl_ZlibDeflate, Tcl_ZlibInflate and Tcl_ZlibStreamInit is used to pass a dictionary of options about that is used to describe the gzip header in the compressed data. When creating compressed data, the dictionary is read and when unpacking compressed data the dictionary is written (in which case the dictObj parameter must refer to an unshared dictionary value).
The following fields in the dictionary value are understood. All other fields are ignored. No field is required when creating a gzip-format stream.