Index: generic/tclBinary.c ================================================================== --- generic/tclBinary.c +++ generic/tclBinary.c @@ -55,13 +55,16 @@ * Prototypes for local procedures defined in this file: */ static void DupByteArrayInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); +static void DupProperByteArrayInternalRep(Tcl_Obj *srcPtr, + Tcl_Obj *copyPtr); static int FormatNumber(Tcl_Interp *interp, int type, Tcl_Obj *src, unsigned char **cursorPtr); static void FreeByteArrayInternalRep(Tcl_Obj *objPtr); +static void FreeProperByteArrayInternalRep(Tcl_Obj *objPtr); static int GetFormatSpec(const char **formatPtr, char *cmdPtr, size_t *countPtr, int *flagsPtr); static Tcl_Obj * ScanNumber(unsigned char *buffer, int type, int flags, Tcl_HashTable **numberCachePtr); static int SetByteArrayFromAny(Tcl_Interp *interp, @@ -243,14 +246,14 @@ * changes now in place are the limit of what can be done short of * interface repair. They provide a great expansion of the histories * over which bytearray values can be useful in the meanwhile. */ -const Tcl_ObjType tclPureByteArrayType = { +static const Tcl_ObjType properByteArrayType = { "bytearray", - FreeByteArrayInternalRep, - DupByteArrayInternalRep, + FreeProperByteArrayInternalRep, + DupProperByteArrayInternalRep, UpdateStringOfByteArray, NULL }; const Tcl_ObjType tclByteArrayType = { @@ -281,10 +284,17 @@ #define BYTEARRAY_SIZE(len) \ ((TclOffset(ByteArray, bytes) + (len))) #define GET_BYTEARRAY(irPtr) ((ByteArray *) (irPtr)->twoPtrValue.ptr1) #define SET_BYTEARRAY(irPtr, baPtr) \ (irPtr)->twoPtrValue.ptr1 = (baPtr) + +int +TclIsPureByteArray( + Tcl_Obj * objPtr) +{ + return objPtr->typePtr == &properByteArrayType; +} /* *---------------------------------------------------------------------- * * Tcl_NewByteArrayObj -- @@ -408,11 +418,11 @@ if ((bytes != NULL) && (length > 0)) { memcpy(byteArrayPtr->bytes, bytes, length); } SET_BYTEARRAY(&ir, byteArrayPtr); - Tcl_StoreIntRep(objPtr, &tclPureByteArrayType, &ir); + Tcl_StoreIntRep(objPtr, &properByteArrayType, &ir); } /* *---------------------------------------------------------------------- * @@ -436,17 +446,17 @@ Tcl_Obj *objPtr, /* The ByteArray object. */ int *lengthPtr) /* If non-NULL, filled with length of the * array of bytes in the ByteArray object. */ { ByteArray *baPtr; - const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objPtr, &tclPureByteArrayType); + const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objPtr, &properByteArrayType); if (irPtr == NULL) { irPtr = TclFetchIntRep(objPtr, &tclByteArrayType); if (irPtr == NULL) { SetByteArrayFromAny(NULL, objPtr); - irPtr = TclFetchIntRep(objPtr, &tclPureByteArrayType); + irPtr = TclFetchIntRep(objPtr, &properByteArrayType); if (irPtr == NULL) { irPtr = TclFetchIntRep(objPtr, &tclByteArrayType); } } } @@ -490,16 +500,16 @@ if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayLength"); } - irPtr = TclFetchIntRep(objPtr, &tclPureByteArrayType); + irPtr = TclFetchIntRep(objPtr, &properByteArrayType); if (irPtr == NULL) { irPtr = TclFetchIntRep(objPtr, &tclByteArrayType); if (irPtr == NULL) { SetByteArrayFromAny(NULL, objPtr); - irPtr = TclFetchIntRep(objPtr, &tclPureByteArrayType); + irPtr = TclFetchIntRep(objPtr, &properByteArrayType); if (irPtr == NULL) { irPtr = TclFetchIntRep(objPtr, &tclByteArrayType); } } } @@ -542,11 +552,11 @@ unsigned char *dst; Tcl_UniChar ch = 0; ByteArray *byteArrayPtr; Tcl_ObjIntRep ir; - if ((objPtr->typePtr == &tclPureByteArrayType) + if ((objPtr->typePtr == &properByteArrayType) || (objPtr->typePtr == &tclByteArrayType)) { return TCL_OK; } src = TclGetStringFromObj(objPtr, &length); @@ -562,11 +572,11 @@ byteArrayPtr->used = dst - byteArrayPtr->bytes; byteArrayPtr->allocated = length; SET_BYTEARRAY(&ir, byteArrayPtr); Tcl_StoreIntRep(objPtr, - improper ? &tclByteArrayType : &tclPureByteArrayType, &ir); + improper ? &tclByteArrayType : &properByteArrayType, &ir); return TCL_OK; } /* *---------------------------------------------------------------------- @@ -587,11 +597,18 @@ static void FreeByteArrayInternalRep( Tcl_Obj *objPtr) /* Object with internal rep to free. */ { - Tcl_Free(GET_BYTEARRAY(&(objPtr->internalRep))); + Tcl_Free(GET_BYTEARRAY(TclFetchIntRep(objPtr, &tclByteArrayType))); +} + +static void +FreeProperByteArrayInternalRep( + Tcl_Obj *objPtr) /* Object with internal rep to free. */ +{ + Tcl_Free(GET_BYTEARRAY(TclFetchIntRep(objPtr, &properByteArrayType))); } /* *---------------------------------------------------------------------- * @@ -616,20 +633,41 @@ { size_t length; ByteArray *srcArrayPtr, *copyArrayPtr; Tcl_ObjIntRep ir; - srcArrayPtr = GET_BYTEARRAY(&(srcPtr->internalRep)); + srcArrayPtr = GET_BYTEARRAY(TclFetchIntRep(srcPtr, &tclByteArrayType)); + length = srcArrayPtr->used; + + copyArrayPtr = Tcl_Alloc(BYTEARRAY_SIZE(length)); + copyArrayPtr->used = length; + copyArrayPtr->allocated = length; + memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, length); + + SET_BYTEARRAY(&ir, copyArrayPtr); + Tcl_StoreIntRep(copyPtr, &tclByteArrayType, &ir); +} + +static void +DupProperByteArrayInternalRep( + Tcl_Obj *srcPtr, /* Object with internal rep to copy. */ + Tcl_Obj *copyPtr) /* Object with internal rep to set. */ +{ + size_t length; + ByteArray *srcArrayPtr, *copyArrayPtr; + Tcl_ObjIntRep ir; + + srcArrayPtr = GET_BYTEARRAY(TclFetchIntRep(srcPtr, &properByteArrayType)); length = srcArrayPtr->used; copyArrayPtr = Tcl_Alloc(BYTEARRAY_SIZE(length)); copyArrayPtr->used = length; copyArrayPtr->allocated = length; memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, length); SET_BYTEARRAY(&ir, copyArrayPtr); - Tcl_StoreIntRep(copyPtr, srcPtr->typePtr, &ir); + Tcl_StoreIntRep(copyPtr, &properByteArrayType, &ir); } /* *---------------------------------------------------------------------- * @@ -650,11 +688,11 @@ static void UpdateStringOfByteArray( Tcl_Obj *objPtr) /* ByteArray object whose string rep to * update. */ { - const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objPtr, &tclPureByteArrayType); + const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objPtr, &properByteArrayType); ByteArray *byteArrayPtr = GET_BYTEARRAY(irPtr); unsigned char *src = byteArrayPtr->bytes; size_t i, length = byteArrayPtr->used; size_t size = length; @@ -720,16 +758,16 @@ if (len == 0) { /* Append zero bytes is a no-op. */ return; } - irPtr = TclFetchIntRep(objPtr, &tclPureByteArrayType); + irPtr = TclFetchIntRep(objPtr, &properByteArrayType); if (irPtr == NULL) { irPtr = TclFetchIntRep(objPtr, &tclByteArrayType); if (irPtr == NULL) { SetByteArrayFromAny(NULL, objPtr); - irPtr = TclFetchIntRep(objPtr, &tclPureByteArrayType); + irPtr = TclFetchIntRep(objPtr, &properByteArrayType); if (irPtr == NULL) { irPtr = TclFetchIntRep(objPtr, &tclByteArrayType); } } } Index: generic/tclInt.h ================================================================== --- generic/tclInt.h +++ generic/tclInt.h @@ -2677,11 +2677,10 @@ */ MODULE_SCOPE const Tcl_ObjType tclBignumType; MODULE_SCOPE const Tcl_ObjType tclBooleanType; MODULE_SCOPE const Tcl_ObjType tclByteArrayType; -MODULE_SCOPE const Tcl_ObjType tclPureByteArrayType; MODULE_SCOPE const Tcl_ObjType tclByteCodeType; MODULE_SCOPE const Tcl_ObjType tclDoubleType; MODULE_SCOPE const Tcl_ObjType tclIntType; MODULE_SCOPE const Tcl_ObjType tclListType; MODULE_SCOPE const Tcl_ObjType tclDictType; @@ -4569,12 +4568,11 @@ * * MODULE_SCOPE int TclIsPureByteArray(Tcl_Obj *objPtr); *---------------------------------------------------------------- */ -#define TclIsPureByteArray(objPtr) \ - ((objPtr)->typePtr==&tclPureByteArrayType) +MODULE_SCOPE int TclIsPureByteArray(Tcl_Obj *objPtr); #define TclIsPureDict(objPtr) \ (((objPtr)->bytes==NULL) && ((objPtr)->typePtr==&tclDictType)) #define TclFetchIntRep(objPtr, type) \ (((objPtr)->typePtr == type) ? &((objPtr)->internalRep) : NULL)