Tcl_ByteArrayObj(3)
π NAME π
okay bestie, sit down, we're doing bytes today π«Ά
Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetBytesFromObj, Tcl_GetByteArrayFromObj, Tcl_SetByteArrayLength β they all manipulate a Tcl value as an array of bytes. that's the whole job description, no cap.
(yes you're on the Tcl_ByteArrayObj(3) page from the Tcl Library Procedures. welcome. it's giving C API realness π
)
β¨ SYNOPSIS β¨
#include <tcl.h>
Tcl_Obj *
Tcl_NewByteArrayObj(bytes, numBytes)
Tcl_SetByteArrayObj(objPtr, bytes, numBytes)
unsigned char * 2
Tcl_GetBytesFromObj(interp, objPtr, numBytesPtr) 2
unsigned char *
Tcl_GetByteArrayFromObj(objPtr, numBytesPtr)
unsigned char *
Tcl_SetByteArrayLength(objPtr, numBytes)
those stray little 2s floating off to the side? not a typo, not me being chaotic, they're literally on the page. we keep everything here. πΈ
π ARGUMENTS π
const unsigned char *bytes(in) β the array of bytes you use to initialize or set a byte-array value. plot twist: it may beNULLeven ifnumBytesis non-zero. yes really.Tcl_Size numBytes(in) β the number of bytes in the array.Tcl_Obj *objPtr(in/out) β forTcl_SetByteArrayObj, this points to an unshared value that's about to be overwritten by a byte-array value. forTcl_GetBytesFromObj,Tcl_GetByteArrayFromObjandTcl_SetByteArrayLength, this points to the value you're extracting an array of bytes from.Tcl_Interp *interp(in) β the interpreter to use for error reporting.Tcl_Size | int *numBytesPtr(out) β points to space where the number of bytes in the array may be written. may be(Tcl_Size *)NULLwhen it's not used. if it points to a variable whose type isn'tTcl_Size, a compiler warning will be generated. and here's the spicy bit: if your extension is compiled with-DTCL_8_API, this function will returnNULLfor byte arrays larger thanINT_MAX(which should trigger proper error-handling), otherwise expect it to crash. π
π DESCRIPTION π
these routines are your whole toolkit for creating, modifying, storing, transferring, and retrieving arbitrary binary data in Tcl values. specifically, data that can be represented as a sequence of arbitrary byte values. that includes data read from binary channels, values created by the binary command, encrypted data, or literally any other information representable as a finite byte sequence. iconic behavior honestly π¦
a byte is an 8-bit quantity with no inherent meaning. when you interpret those 8 bits as an integer value, the range of possible values is (0-255). the C type best suited to store a byte is unsigned char. an unsigned char array of size N stores an arbitrary binary value of size N bytes. we call this representation a byte-array. and here we're documenting the routines that let us operate on Tcl values as byte-arrays. periodt.
π byte-arrays vs. strings π
all Tcl values must correspond to a string representation. so when a byte-array value has to be processed as a string, the sequence of N bytes gets transformed into the corresponding sequence of N characters, where each byte value transforms to the same character codepoint value in the range (U+0000 - U+00FF). obtaining the string representation of a byte-array value (by calling Tcl_GetStringFromObj) produces this string in Tcl's usual Modified UTF-8 encoding. noted. remembered. never forgotten. β¨
π§ making them: Tcl_NewByteArrayObj and Tcl_SetByteArrayObj π§
Tcl_NewByteArrayObj and Tcl_SetByteArrayObj create a new value or overwrite an existing unshared value, respectively, to hold a byte-array value of numBytes bytes.
when a caller passes a non-NULL value of bytes, it must point to memory from which numBytes bytes can be read. these routines allocate numBytes bytes of memory, copy numBytes bytes from bytes into it, and keep the result in the internal representation of the new or overwritten value.
when the caller passes a NULL value of bytes, the data copying step is skipped, and the bytes stored in the value are undefined. a bytes value of NULL is useful only when the caller will arrange to write known contents into the byte-array through a pointer retrieved by a call to one of the routines explained below. π
Tcl_NewByteArrayObjreturns a pointer to the created value with a reference count of zero.Tcl_SetByteArrayObjoverwrites and invalidates any old contents of the unsharedobjPtras appropriate, and keeps its reference count (0or1) unchanged.
the value produced by these routines has no string representation.
any memory allocation failure may cause a panic. so like, handle your memory, bestie. π
π₯ reading them back: Tcl_GetBytesFromObj π₯
Tcl_GetBytesFromObj performs the opposite function of Tcl_SetByteArrayObj, giving you access to read a byte-array from a Tcl value that was previously written into it.
when objPtr is a value previously produced by Tcl_NewByteArrayObj or Tcl_SetByteArrayObj, then Tcl_GetBytesFromObj returns a pointer to the byte-array kept in the value's internal representation.
if the caller provides a non-NULL value for numBytesPtr, it must point to memory where Tcl_GetBytesFromObj can write the number of bytes in the value's internal byte-array. with both pieces of information, the caller is able to retrieve any information about the contents of that byte-array that it seeks. β¨
when objPtr does not already contain an internal byte-array, Tcl_GetBytesFromObj will try to create one from the value's string representation. any string value that does not include any character codepoints outside the range (U+0000 - U+00FF) will successfully translate to a unique byte-array value. with the created byte-array, the routine returns as before.
for any string representation which does contain a forbidden character codepoint, the conversion fails, and Tcl_GetBytesFromObj returns NULL to signal that failure. on failure, nothing will be written to numBytesPtr, and if the interp argument is non-NULL, then error messages and codes are left in it recording the error. π«Ά
πΈ Tcl_GetByteArrayFromObj πΈ
Tcl_GetByteArrayFromObj performs exactly the same function as Tcl_GetBytesFromObj does when called with the interp argument passed the value NULL.
heads up: this is incompatible with the way the Tcl_GetByteArrayFromObj function worked in Tcl 8. π
Tcl_GetBytesFromObj is the more capable interface and should usually be favored for use over Tcl_GetByteArrayFromObj.
π the pointer rules (read this part, fr fr) π
on success, both Tcl_GetBytesFromObj and Tcl_GetByteArrayFromObj return a pointer into the internal representation of a Tcl_Obj.
- that pointer must not be freed by the caller.
- it should not be retained for use beyond the known time the internal representation of the value has not been disturbed.
- the pointer may be used to overwrite the byte contents of the internal representation, so long as the value is unshared and any string representation is invalidated.
on success, both Tcl_GetBytesFromObj and Tcl_GetByteArrayFromObj write the number of bytes in the byte-array value of objPtr to the space pointed to by numBytesPtr. this space may be of type Tcl_Size or of type int. it is recommended that callers provide a Tcl_Size space for this purpose.
if the caller provides only an int space and the number of bytes in the byte-array value of objPtr is greater than INT_MAX, the routine will fail, due to being unable to correctly report the byte-array size to the caller. the ability to provide an int space is best considered a migration aid for codebases constrained to continue operating with Tcl releases older than 9.0. π
π¦ resizing: Tcl_SetByteArrayLength π¦
Tcl_SetByteArrayLength lets a caller change the size of a byte-array in the internal representation of an unshared objPtr to become numBytes bytes.
this is most often useful after the bytes of the internal byte-array have been directly overwritten and it has been discovered that the required size differs from the first estimate used in the allocation. (we've all been there, bestie. estimating is hard. π)
Tcl_SetByteArrayLength returns a pointer to the resized byte-array.
because resizing the byte-array changes the internal representation, Tcl_SetByteArrayLength also invalidates any string representation in objPtr.
- if resizing grows the byte-array, the new byte values are undefined.
- if
objPtrdoes not already possess an internal byte-array, one is produced in the same way thatTcl_GetBytesFromObjdoes, also returningNULLwhen any characters of the value inobjPtr(up tonumBytesof them) are not valid bytes.
π REFERENCE COUNT MANAGEMENT π
keeping the refcounts in check, because that's the main character energy this page deserves π
Tcl_NewByteArrayObjalways returns a zero-reference object, much likeTcl_NewObj.Tcl_SetByteArrayObjandTcl_SetByteArrayLengthdo not modify the reference count of theirobjPtrarguments, but do require that the object be unshared.Tcl_GetBytesFromObjandTcl_GetByteArrayFromObjdo not modify the reference count ofobjPtr; they only read.
π SEE ALSO π
Tcl_GetStringFromObjTcl_NewObjTcl_IncrRefCountTcl_DecrRefCount
π KEYWORDS π
value, binary data, byte array, utf, unicode
and that's the page, bestie!! go forth and byte-array responsibly π§π
this was the Tcl_ByteArrayObj(3) manual page, Tcl 9.0, from the Tcl Library Procedures. mwah. no notes. πβ
π¦ 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) 1997 Sun Microsystems, Inc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms