TclZlib(3)
π TclZlib(3) π
okay bestie, welcome to the Tcl Library Procedures page for TclZlib β yes, the compression/decompression one, and it's lowkey iconic. We're doing part 1, so hydrate, sit pretty, and let's get into it. π«Άβ¨
β¨ NAME β¨
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. π
β¨ SYNOPSIS β¨
Bestie, the C API said:
#include <tcl.h>
int
Tcl_ZlibDeflate(interp, format, dataObj, level, dictObj)
int
Tcl_ZlibInflate(interp, format, dataObj, bufferSize, 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)
β¨ ARGUMENTS β¨
okay, now the receipts. Every argument, every type, every in/out, no skipping. π
Tcl_Interp *interp(in) β the interpreter where the resulting compressed or uncompressed data gets stored. It's also where any error messages are written. ForTcl_ZlibStreamInit, this can beNULLto create a stream that is not bound to a command. πint format(in) β what format of compressed data you're working with. Must be one ofTCL_ZLIB_FORMAT_ZLIBfor zlib-format data,TCL_ZLIB_FORMAT_GZIPfor gzip-format data, orTCL_ZLIB_FORMAT_RAWfor raw compressed data. In addition, for decompression only,TCL_ZLIB_FORMAT_AUTOmay also be chosen, which can automatically detect whether the compressed data was in zlib or gzip format. β¨Tcl_Obj *dataObj(in/out) β a byte-array value containing the data to be compressed or decompressed, or to which the data extracted from the stream is appended when passed toTcl_ZlibStreamGet. π¦int level(in) β what level of compression to use. Should be a number from0to9, or one of these:TCL_ZLIB_COMPRESS_NONEfor no compression,TCL_ZLIB_COMPRESS_FASTfor fast but inefficient compression,TCL_ZLIB_COMPRESS_BESTfor slow but maximal compression, orTCL_ZLIB_COMPRESS_DEFAULTfor the level recommended by the zlib library. πTcl_Obj *dictObj(in/out) β a dictionary that contains, or which will be updated to contain, a description of the gzip header associated with the compressed data. Only useful when the format isTCL_ZLIB_FORMAT_GZIPorTCL_ZLIB_FORMAT_AUTO. If aNULLis passed, a default header will be used on compression and the header will be ignored (apart from integrity checks) on decompression. See the section GZIP OPTIONS DICTIONARY for details about the contents of this dictionary. πunsigned int initValue(in) β the initial value for the checksum algorithm. βTcl_Size bufferSize(in) β a hint as to what size of buffer is to be used to receive the data. Use0to use a geric guess based on the input data. πunsigned char *bytes(in) β an array of bytes to run the checksum algorithm over, orNULLto get the recommended initial value for the checksum algorithm. π§Tcl_Size length(in) β the number of bytes in the array. πΈint mode(in) β what mode to operate the stream in. Should be eitherTCL_ZLIB_STREAM_DEFLATEfor a compressing stream orTCL_ZLIB_STREAM_INFLATEfor a decompressing stream. πTcl_ZlibStream *zshandlePtr(out) β a pointer to a variable in which to write the abstract token for the stream upon successful creation. πTcl_ZlibStream zshandle(in) β the abstract token for the stream to operate on. π«Άint flush(in) β whether and how to flush the stream after writing the data to it. Must be one of:TCL_ZLIB_NO_FLUSHif no flushing is to be done,TCL_ZLIB_FLUSHif the currently compressed data must be made available for access usingTcl_ZlibStreamGet,TCL_ZLIB_FULLFLUSHif the stream must be put into a state where the decompressor can recover from on corruption, orTCL_ZLIB_FINALIZEto ensure that the stream is finished and that any trailer demanded by the format is written. π₯Tcl_Size count(in) β the maximum number of bytes to get from the stream, or-1to get all remaining bytes from the stream's buffers. β¨Tcl_Obj *compDict(in) β a byte array value that is the compression dictionary to use with the stream.
β οΈ note that this is not a Tcl dictionary, and it is recommended that this only ever be used with streams that were created with their format set to TCL_ZLIB_FORMAT_ZLIB because the other formats have no mechanism to indicate whether a compression dictionary was present other than to fail on decompression. π
π DESCRIPTION π
Okay bestie, so these functions? They're literally the whole interface from the Tcl library over to the Zlib library, which was written by Jean-loup Gailly and Mark Adler. Legends, honestly. π
Tcl_ZlibDeflate and Tcl_ZlibInflate respectively compress and decompress the data sitting inside the dataObj argument β following whatever the format argument says, and for compression, the level argument too. The dictionary in the dictObj parameter is the little messenger that carries extra header info about the compressed data whenever the compression format actually supports that; and rn, that dictionary is only used when format is TCL_ZLIB_FORMAT_GZIP or TCL_ZLIB_FORMAT_AUTO. Wanna know what goes inside that dictionary? Scroll down to the GZIP OPTIONS DICTIONARY section, babes. π
On success, both of those functions leave the resulting compressed-or-decompressed data in a byte-array value that is the Tcl interpreter's result, and the thing they return is a standard Tcl result code. Simple as that. β¨
Tcl_ZlibAdler32 and Tcl_ZlibCRC32 compute checksums over arrays of bytes and hand you back the computed checksum. Now here's the cute part β checksums get computed incrementally, so you can process your data one block at a time if you want. The catch? You have to hold onto the current checksum yourself and pass it in as the initValue parameter. And how do you get that starting value? Just pass NULL for the bytes parameter instead of a pointer to the array of bytes you're checksumming. So the typical single-data-block usage looks exactly like this:
checksum = Tcl_ZlibCRC32(Tcl_ZlibCRC32(0,NULL,0), data, length);
Real talk though: the Adler-32 algorithm is not a real checksum β it's actually a related type of hash, and it works best on longer data. So don't come for it when it acts different. π
π ZLIB STREAMS π
Tcl_ZlibStreamInit creates a compressing or decompressing stream that's linked to a Tcl command, according to its arguments, and it gives you back an abstract token for the stream plus a normal Tcl result code. Then Tcl_ZlibStreamGetCommandName gives you the name of that command when you hand it the stream token β or NULL if that stream has no command at all. π
Important, no cap: streams are not designed to be thread-safe. Each stream should only ever be used from the thread that created it. Periodt. π§΅π«
When you're working with gzip streams, you can pass in a dictionary via the dictObj parameter (fields are all listed in the GZIP OPTIONS DICTIONARY section below) β and that dictionary lets you control the generated headers on compression, and lets you discover the existing headers on decompression. Heads up: on decompression the dictionary gets written to once enough data has been read to have a complete header. Which means in that case the dictionary must be an unshared value β a blank value created with Tcl_NewObj is the suggested move. π
Once a stream has been constructed, Tcl_ZlibStreamPut is your girl for adding data to the stream, and Tcl_ZlibStreamGet is your girl for retrieving data from the stream after processing. Both return normal Tcl result codes, and in the error case they leave an error message in the result of the interpreter that the stream is registered with (if such a registration has been performed). With Tcl_ZlibStreamPut, the data buffer value you pass in should not be modified afterwards. With Tcl_ZlibStreamGet, the data buffer value you pass in will have the data bytes appended to it. And internally? The stream keeps data compressed so the cost of buffer space stays low. Efficiency slay. π
β¨
Tcl_ZlibStreamChecksum returns the checksum computed over the uncompressed data, according to the format. And Tcl_ZlibStreamEof returns a boolean value telling you whether the end of the uncompressed data has been reached. Yes or no, bestie, that's it. π¦
Tcl_ZlibStreamSetCompressionDictionary is how you control the compression dictionary used with the stream. And what even is a compression dictionary? It's an array of bytes (like, the kind you'd create with Tcl_NewByteArrayObj) that gets used to initialize the compression engine β instead of letting the engine build one on the fly from the data being compressed. Setting a compression dictionary gets you more efficient compression when the start of your data is highly regular, but it does require the compressor and the decompressor to agree on the value. π€
Compression dictionaries are only fully supported for zlib-format data. So:
- On compression, you must set them before any data is sent in with
Tcl_ZlibStreamPut. - On decompression, you should set them when
Tcl_ZlibStreamGetproduces an error with its-errorcodeset toZLIB NEED_DICTcode β and that code will be the Adler-32 checksum (seeTcl_ZlibAdler32) of the compression dictionary being sought.
Little note: that whole errorcode situation is only true for zlib-format streams. gzip streams just ignore compression dictionaries, because the format specification doesn't permit them β and raw streams will straight up produce a data error if the compression dictionary is missing or wrong. π
Wanna clear a stream and reuse it for a brand new compression or decompression action? Tcl_ZlibStreamReset does exactly that and returns a normal Tcl result code to tell you if it worked. And if the stream is registered with an interpreter, an error message gets left in the interpreter result whenever this function returns TCL_ERROR.
And finally β the goodbye kiss β Tcl_ZlibStreamClose cleans up the stream and deletes the associated command. Fun fact: using Tcl_DeleteCommand on the stream's command is equivalent to doing that (when such a command exists). π
π GZIP OPTIONS DICTIONARY π
The dictObj parameter to Tcl_ZlibDeflate, Tcl_ZlibInflate and Tcl_ZlibStreamInit is how you pass a dictionary of options that describes the gzip header inside the compressed data. When you're creating compressed data, the dictionary gets read. When you're unpacking compressed data, the dictionary gets written β and in that case the dictObj parameter must refer to an unshared dictionary value, okay? π
Here are the fields in the dictionary value that are understood. Everything else? Ignored, boo. And when you're creating a gzip-format stream, no field is required. π
comment
This one holds the comment field of the header, if present. If it's absent, no comment was supplied (on decompression) or will be created (on compression). π¬
crc
A boolean value describing whether a CRC of the header is computed. Fun little tea: the gzip program does not use or allow a CRC on the header. π
filename
The name of the file that held the uncompressed data. This should not contain any directory separators, and should be sanitized before use on decompression with file tail. Safety first, babe. π
os
The operating system type code field from the header (if it's not the βunknownβ value). See RFC 1952 for the meaning of these codes. On compression, if this is absent then the field will be set to the βunknownβ value. π
size
The size of the uncompressed data. This gets ignored on compression β because the size of the data compressed depends on how much data is supplied to the compression engine. π€·
time
The time field from the header, if non-zero, expected to be the time that the file named by the filename field was modified. Suitable for use with clock format. On creation, the right value to use is the one from clock seconds or file mtime. β°
type
The type of the uncompressed data β either binary or text β if known. π§
π₯ REFERENCE COUNT MANAGEMENT π₯
Okay this part is the responsible-adult section, but it's still important, bestie. Stay with me.
Tcl_ZlibDeflateandTcl_ZlibInflatetake a value with arbitrary reference count for their dataObj and dictObj arguments (the latter often beingNULLinstead), and they set the interpreter result with their output value (or an error). The existing interpreter result should not be passed as any argument value unless an additional reference is held. π«ΆTcl_ZlibStreamInittakes a value with arbitrary reference count for its dictObj argument β and it only reads from it. The existing interpreter result should not be passed unless an additional reference is held.Tcl_ZlibStreamGetCommandNamereturns a zero reference count value, much likeTcl_NewObj.- The dataObj argument to
Tcl_ZlibStreamPutis a value with arbitrary reference count; it is only ever read from. - The dataObj argument to
Tcl_ZlibStreamGetis an unshared value (seeTcl_IsShared) that will be updated by the function. - The compDict argument to
Tcl_ZlibStreamSetCompressionDictionary, if non-NULL, may be duplicated or may have its reference count incremented. Using a zero reference count value is not recommended. π
π PORTABILITY NOTES π
These functions will fail gracefully if Tcl is not linked with the zlib library. No drama, no crash. She's polite like that. π
π SEE ALSO π
β KEYWORDS β
compress, decompress, deflate, gzip, inflate
And that's a wrap on this page, bestie!! π This one came from the Tcl manual, version 8.6, and it's dated TclZlib(3) β so yeah, you've officially read the whole thing. Go compress something iconic. Mwah. πβ¨π¦
π¦ where this page comes from
- alpine 3.23: tcl9-doc 9.0.3-r0 Β· TCL
- alpine 3.24: tcl9-doc 9.0.3-r2 Β· TCL
- fedora 43: tcl-doc 1:9.0.2-1.fc43 Β· TCL AND GPL-3.0-or-later WITH Bison-exception-2.2 AND BSD-3-Clause
- fedora 44: tcl-doc 1:9.0.2-1.fc44 Β· TCL AND GPL-3.0-or-later WITH Bison-exception-2.2 AND BSD-3-Clause
- nixos 26.05: tcl 9.0.3
- Copyright (c) 2008 Donal K. Fellows
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms