diff options
-rw-r--r-- | generic/tclBinary.c | 68 | ||||
-rw-r--r-- | generic/tclDictObj.c | 3 | ||||
-rw-r--r-- | generic/tclInt.h | 1 |
3 files changed, 54 insertions, 18 deletions
diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 9175036..bcba677 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -453,36 +453,70 @@ Tcl_SetByteArrayLength( */ static int -SetByteArrayFromAny( - Tcl_Interp *interp, /* Not used. */ - Tcl_Obj *objPtr) /* The object to convert to type ByteArray. */ +MakeByteArray( + Tcl_Obj *objPtr, + int earlyOut, + ByteArray **byteArrayPtrPtr) { - int length; - const char *src, *srcEnd; + int length, proper = 1; unsigned char *dst; - ByteArray *byteArrayPtr; - Tcl_UniChar ch; - - if (objPtr->typePtr == &properByteArrayType) { - return TCL_OK; - } - - src = TclGetStringFromObj(objPtr, &length); - srcEnd = src + length; + const char *src = TclGetStringFromObj(objPtr, &length); + ByteArray *byteArrayPtr = ckalloc(BYTEARRAY_SIZE(length)); + const char *srcEnd = src + length; - byteArrayPtr = ckalloc(BYTEARRAY_SIZE(length)); for (dst = byteArrayPtr->bytes; src < srcEnd; ) { + Tcl_UniChar ch; + src += Tcl_UtfToUniChar(src, &ch); if (ch > 255) { + proper = 0; + if (earlyOut) { ckfree(byteArrayPtr); - return TCL_ERROR; + *byteArrayPtrPtr = NULL; + return proper; + } } *dst++ = UCHAR(ch); } - byteArrayPtr->used = dst - byteArrayPtr->bytes; byteArrayPtr->allocated = length; + *byteArrayPtrPtr = byteArrayPtr; + return proper; +} + +Tcl_Obj * +TclNarrowToBytes( + Tcl_Obj *objPtr) +{ + ByteArray *byteArrayPtr; + + if (0 == MakeByteArray(objPtr, 0, &byteArrayPtr)) { + objPtr = Tcl_NewObj(); + TclInvalidateStringRep(objPtr); + } + TclFreeIntRep(objPtr); + objPtr->typePtr = &properByteArrayType; + SET_BYTEARRAY(objPtr, byteArrayPtr); + Tcl_IncrRefCount(objPtr); + return objPtr; +} + +static int +SetByteArrayFromAny( + Tcl_Interp *interp, /* Not used. */ + Tcl_Obj *objPtr) /* The object to convert to type ByteArray. */ +{ + ByteArray *byteArrayPtr; + + if (objPtr->typePtr == &properByteArrayType) { + return TCL_OK; + } + + if (0 == MakeByteArray(objPtr, 1, &byteArrayPtr)) { + return TCL_ERROR; + } + TclFreeIntRep(objPtr); objPtr->typePtr = &properByteArrayType; SET_BYTEARRAY(objPtr, byteArrayPtr); diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 29ab973..3bb2d63 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -492,7 +492,8 @@ UpdateStringOfDict( Dict *dict = DICT(dictPtr); ChainEntry *cPtr; Tcl_Obj *keyPtr, *valuePtr; - size_t i, length, bytesNeeded = 0; + size_t i, length; + int bytesNeeded = 0; const char *elem; char *dst; diff --git a/generic/tclInt.h b/generic/tclInt.h index 253a2f0..4bbaa5c 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2969,6 +2969,7 @@ MODULE_SCOPE int TclMaxListLength(const char *bytes, int numBytes, MODULE_SCOPE int TclMergeReturnOptions(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], Tcl_Obj **optionsPtrPtr, int *codePtr, int *levelPtr); +MODULE_SCOPE Tcl_Obj * TclNarrowToBytes(Tcl_Obj *objPtr); MODULE_SCOPE Tcl_Obj * TclNoErrorStack(Tcl_Interp *interp, Tcl_Obj *options); MODULE_SCOPE int TclNokia770Doubles(void); MODULE_SCOPE void TclNsDecrRefCount(Namespace *nsPtr); |