summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclBinary.c68
-rw-r--r--generic/tclDictObj.c3
-rw-r--r--generic/tclInt.h1
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);