summaryrefslogtreecommitdiffstats
path: root/generic/tclStringObj.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2016-10-31 16:15:16 (GMT)
committerdgp <dgp@users.sourceforge.net>2016-10-31 16:15:16 (GMT)
commit77c9a433f701214eafd76617a8e3c67316ebf08e (patch)
tree4477866b94fc260e926957d7a062ea019d12de89 /generic/tclStringObj.c
parent2ec95332a24721f3017b4f6bdaa4cca1bf06cdd5 (diff)
downloadtcl-77c9a433f701214eafd76617a8e3c67316ebf08e.zip
tcl-77c9a433f701214eafd76617a8e3c67316ebf08e.tar.gz
tcl-77c9a433f701214eafd76617a8e3c67316ebf08e.tar.bz2
Complete the "pure binary" implementation of the [string cat] engine.
Diffstat (limited to 'generic/tclStringObj.c')
-rw-r--r--generic/tclStringObj.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index c248749..c0d85a0 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -2694,12 +2694,26 @@ TclStringCatObjv(
}
if (binary) {
- Tcl_SetByteArrayLength(objResultPtr, length);
- }
-
-
- while (objc--) {
- Tcl_AppendObjToObj(objResultPtr, *objv++);
+ /* Efficiently produce a pure binary result */
+ unsigned char *dst;
+ int start;
+
+ Tcl_GetByteArrayFromObj(objResultPtr, &start);
+ dst = Tcl_SetByteArrayLength(objResultPtr, length) + start;
+ while (objc--) {
+ Tcl_Obj *objPtr = *objv++;
+
+ if (objPtr->bytes == NULL) {
+ int more;
+ unsigned char *src = Tcl_GetByteArrayFromObj(objPtr, &more);
+ memcpy(dst, src, (size_t) more);
+ dst += more;
+ }
+ }
+ } else {
+ while (objc--) {
+ Tcl_AppendObjToObj(objResultPtr, *objv++);
+ }
}
*objPtrPtr = objResultPtr;
return TCL_OK;