summaryrefslogtreecommitdiffstats
path: root/generic/tclBinary.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2020-03-30 15:09:40 (GMT)
committerdgp <dgp@users.sourceforge.net>2020-03-30 15:09:40 (GMT)
commit987ffc2687ef44b4bda1b03ff9914d69130cd3c5 (patch)
tree026a675cec7db46066ecd7bc2dc2682d19e9ca47 /generic/tclBinary.c
parent1d7fa6b53d9ccc07f2a0d7f71a0d79995b960ccc (diff)
downloadtcl-987ffc2687ef44b4bda1b03ff9914d69130cd3c5.zip
tcl-987ffc2687ef44b4bda1b03ff9914d69130cd3c5.tar.gz
tcl-987ffc2687ef44b4bda1b03ff9914d69130cd3c5.tar.bz2
Optimize [binary decode uuencode] to process bytearray without string
generation when it can.
Diffstat (limited to 'generic/tclBinary.c')
-rw-r--r--generic/tclBinary.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/generic/tclBinary.c b/generic/tclBinary.c
index e4d7365..de1333f 100644
--- a/generic/tclBinary.c
+++ b/generic/tclBinary.c
@@ -2726,8 +2726,9 @@ BinaryDecodeUu(
Tcl_Obj *resultObj = NULL;
unsigned char *data, *datastart, *dataend;
unsigned char *begin, *cursor;
- int i, index, size, count = 0, strict = 0, lineLen;
+ int i, index, size, pure, count = 0, strict = 0, lineLen;
unsigned char c;
+ Tcl_UniChar ch;
enum { OPT_STRICT };
static const char *const optStrings[] = { "-strict", NULL };
@@ -2748,8 +2749,9 @@ BinaryDecodeUu(
}
TclNewObj(resultObj);
- datastart = data = (unsigned char *)
- TclGetStringFromObj(objv[objc - 1], &count);
+ pure = TclIsPureByteArray(objv[objc - 1]);
+ datastart = data = pure ? Tcl_GetByteArrayFromObj(objv[objc - 1], &count)
+ : (unsigned char *) TclGetStringFromObj(objv[objc - 1], &count);
dataend = data + count;
size = ((count + 3) & ~3) * 3 / 4;
begin = cursor = Tcl_SetByteArrayLength(resultObj, size);
@@ -2855,9 +2857,14 @@ BinaryDecodeUu(
return TCL_ERROR;
badUu:
+ if (pure) {
+ ch = c;
+ } else {
+ TclUtfToUniChar((const char *)(data - 1), &ch);
+ }
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"invalid uuencode character \"%c\" at position %d",
- c, (int) (data - datastart - 1)));
+ ch, (int) (data - datastart - 1)));
Tcl_SetErrorCode(interp, "TCL", "BINARY", "DECODE", "INVALID", NULL);
TclDecrRefCount(resultObj);
return TCL_ERROR;