summaryrefslogtreecommitdiffstats
path: root/generic/tclBinary.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclBinary.c')
-rw-r--r--generic/tclBinary.c77
1 files changed, 76 insertions, 1 deletions
diff --git a/generic/tclBinary.c b/generic/tclBinary.c
index 62f8f46..1d46902 100644
--- a/generic/tclBinary.c
+++ b/generic/tclBinary.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclBinary.c,v 1.60 2010/03/05 14:34:03 dkf Exp $
+ * RCS: @(#) $Id: tclBinary.c,v 1.61 2010/04/29 15:08:05 dkf Exp $
*/
#include "tclInt.h"
@@ -577,6 +577,81 @@ UpdateStringOfByteArray(
/*
*----------------------------------------------------------------------
*
+ * TclAppendBytesToByteArray --
+ *
+ * This function appends an array of bytes to a byte array object. Note
+ * that the object *must* be unshared, and the array of bytes *must not*
+ * refer to the object being appended to.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Allocates enough memory for an array of bytes of the requested total
+ * size, or possibly larger. [Bug 2992970]
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclAppendBytesToByteArray(
+ Tcl_Obj *objPtr,
+ const unsigned char *bytes,
+ unsigned len)
+{
+ ByteArray *byteArrayPtr;
+
+ if (Tcl_IsShared(objPtr)) {
+ Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray");
+ }
+ if (objPtr->typePtr != &tclByteArrayType) {
+ SetByteArrayFromAny(NULL, objPtr);
+ }
+ byteArrayPtr = GET_BYTEARRAY(objPtr);
+
+ /*
+ * If we need to, resize the allocated space in the byte array.
+ */
+
+ if (byteArrayPtr->used+len > byteArrayPtr->allocated) {
+ unsigned int attempt, used = byteArrayPtr->used;
+ ByteArray *tmpByteArrayPtr;
+
+ attempt = byteArrayPtr->allocated;
+ do {
+ attempt *= 2;
+ } while (attempt < used+len);
+
+ tmpByteArrayPtr = (ByteArray *)
+ attemptckrealloc((char *) byteArrayPtr,
+ BYTEARRAY_SIZE(attempt));
+
+ if (tmpByteArrayPtr == NULL) {
+ attempt = used + len;
+ tmpByteArrayPtr = (ByteArray *) ckrealloc((char *) byteArrayPtr,
+ BYTEARRAY_SIZE(attempt));
+ }
+
+ byteArrayPtr = tmpByteArrayPtr;
+ byteArrayPtr->allocated = attempt;
+ byteArrayPtr->used = used;
+ SET_BYTEARRAY(objPtr, byteArrayPtr);
+ }
+
+ /*
+ * Do the append if there's any point.
+ */
+
+ if (len > 0) {
+ memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, len);
+ byteArrayPtr->used += len;
+ Tcl_InvalidateStringRep(objPtr);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclInitBinaryCmd --
*
* This function is called to create the "binary" Tcl command. See the