summaryrefslogtreecommitdiffstats
path: root/generic/tclStringObj.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclStringObj.c')
-rw-r--r--generic/tclStringObj.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index fc19ce6..b7961b8 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -33,7 +33,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclStringObj.c,v 1.84 2009/02/04 21:45:19 dgp Exp $ */
+ * RCS: @(#) $Id: tclStringObj.c,v 1.85 2009/02/05 01:21:59 dkf Exp $ */
#include "tclInt.h"
#include "tommath.h"
@@ -1216,6 +1216,35 @@ Tcl_AppendObjToObj(
int length, numChars, allOneByteChars;
char *bytes;
+ /*
+ * Handle append of one bytearray object to another as a special case.
+ * Note that we only do this when the object being written doesn't have a
+ * string rep; if it did, then appending the byte arrays together could
+ * well lose information; this is a special-case optimization only.
+ */
+
+ if (objPtr->typePtr == &tclByteArrayType && objPtr->bytes == NULL
+ && appendObjPtr->typePtr == &tclByteArrayType) {
+ unsigned char *bytesDst, *bytesSrc;
+ int lengthSrc, lengthTotal;
+
+ /*
+ * Note that we do not assume that objPtr and appendObjPtr must be
+ * distinct!
+ */
+
+ (void) Tcl_GetByteArrayFromObj(objPtr, &length);
+ (void) Tcl_GetByteArrayFromObj(appendObjPtr, &lengthSrc);
+ lengthTotal = length + lengthSrc;
+ if (((length > lengthSrc) ? length : lengthSrc) > lengthTotal) {
+ Tcl_Panic("overflow when calculating byte array size");
+ }
+ bytesDst = Tcl_SetByteArrayLength(objPtr, lengthTotal);
+ bytesSrc = Tcl_GetByteArrayFromObj(appendObjPtr, NULL);
+ memcpy(bytesDst + length, bytesSrc, lengthSrc);
+ return;
+ }
+
SetStringFromAny(NULL, objPtr);
/*