98 lines
4.1 KiB
C
98 lines
4.1 KiB
C
|
/*
|
|||
|
* tclStringRep.h --
|
|||
|
*
|
|||
|
* This file contains the definition of the Unicode string internal
|
|||
|
* representation and macros to access it.
|
|||
|
*
|
|||
|
* A Unicode string is an internationalized string. Conceptually, a
|
|||
|
* Unicode string is an array of 16-bit quantities organized as a
|
|||
|
* sequence of properly formed UTF-8 characters. There is a one-to-one
|
|||
|
* map between Unicode and UTF characters. Because Unicode characters
|
|||
|
* have a fixed width, operations such as indexing operate on Unicode
|
|||
|
* data. The String object is optimized for the case where each UTF char
|
|||
|
* in a string is only one byte. In this case, we store the value of
|
|||
|
* numChars, but we don't store the Unicode data (unless Tcl_GetUnicode
|
|||
|
* is explicitly called).
|
|||
|
*
|
|||
|
* The String object type stores one or both formats. The default
|
|||
|
* behavior is to store UTF. Once Unicode is calculated by a function, it
|
|||
|
* is stored in the internal rep for future access (without an additional
|
|||
|
* O(n) cost).
|
|||
|
*
|
|||
|
* To allow many appends to be done to an object without constantly
|
|||
|
* reallocating the space for the string or Unicode representation, we
|
|||
|
* allocate double the space for the string or Unicode and use the
|
|||
|
* internal representation to keep track of how much space is used vs.
|
|||
|
* allocated.
|
|||
|
*
|
|||
|
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
|
|||
|
* Copyright (c) 1999 by Scriptics Corporation.
|
|||
|
*
|
|||
|
* See the file "license.terms" for information on usage and redistribution of
|
|||
|
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|||
|
*/
|
|||
|
|
|||
|
/*
|
|||
|
* The following structure is the internal rep for a String object. It keeps
|
|||
|
* track of how much memory has been used and how much has been allocated for
|
|||
|
* the Unicode and UTF string to enable growing and shrinking of the UTF and
|
|||
|
* Unicode reps of the String object with fewer mallocs. To optimize string
|
|||
|
* length and indexing operations, this structure also stores the number of
|
|||
|
* characters (same of UTF and Unicode!) once that value has been computed.
|
|||
|
*
|
|||
|
* Under normal configurations, what Tcl calls "Unicode" is actually UTF-16
|
|||
|
* restricted to the Basic Multilingual Plane (i.e. U+00000 to U+0FFFF). This
|
|||
|
* can be officially modified by altering the definition of Tcl_UniChar in
|
|||
|
* tcl.h, but do not do that unless you are sure what you're doing!
|
|||
|
*/
|
|||
|
|
|||
|
typedef struct String {
|
|||
|
int numChars; /* The number of chars in the string. -1 means
|
|||
|
* this value has not been calculated. >= 0
|
|||
|
* means that there is a valid Unicode rep, or
|
|||
|
* that the number of UTF bytes == the number
|
|||
|
* of chars. */
|
|||
|
int allocated; /* The amount of space actually allocated for
|
|||
|
* the UTF string (minus 1 byte for the
|
|||
|
* termination char). */
|
|||
|
int maxChars; /* Max number of chars that can fit in the
|
|||
|
* space allocated for the unicode array. */
|
|||
|
int hasUnicode; /* Boolean determining whether the string has
|
|||
|
* a Unicode representation. */
|
|||
|
Tcl_UniChar unicode[TCLFLEXARRAY]; /* The array of Unicode chars. The actual size
|
|||
|
* of this field depends on the 'maxChars'
|
|||
|
* field above. */
|
|||
|
} String;
|
|||
|
|
|||
|
#define STRING_MAXCHARS \
|
|||
|
(int)(((size_t)UINT_MAX - 1 - TclOffset(String, unicode))/sizeof(Tcl_UniChar))
|
|||
|
#define STRING_SIZE(numChars) \
|
|||
|
(TclOffset(String, unicode) + ((numChars + 1) * sizeof(Tcl_UniChar)))
|
|||
|
#define stringCheckLimits(numChars) \
|
|||
|
do { \
|
|||
|
if ((numChars) < 0 || (numChars) > STRING_MAXCHARS) { \
|
|||
|
Tcl_Panic("max length for a Tcl unicode value (%d chars) exceeded", \
|
|||
|
STRING_MAXCHARS); \
|
|||
|
} \
|
|||
|
} while (0)
|
|||
|
#define stringAttemptAlloc(numChars) \
|
|||
|
(String *) attemptckalloc((unsigned) STRING_SIZE(numChars))
|
|||
|
#define stringAlloc(numChars) \
|
|||
|
(String *) ckalloc((unsigned) STRING_SIZE(numChars))
|
|||
|
#define stringRealloc(ptr, numChars) \
|
|||
|
(String *) ckrealloc((ptr), (unsigned) STRING_SIZE(numChars))
|
|||
|
#define stringAttemptRealloc(ptr, numChars) \
|
|||
|
(String *) attemptckrealloc((ptr), (unsigned) STRING_SIZE(numChars))
|
|||
|
#define GET_STRING(objPtr) \
|
|||
|
((String *) (objPtr)->internalRep.twoPtrValue.ptr1)
|
|||
|
#define SET_STRING(objPtr, stringPtr) \
|
|||
|
((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (stringPtr))
|
|||
|
|
|||
|
/*
|
|||
|
* Local Variables:
|
|||
|
* mode: c
|
|||
|
* c-basic-offset: 4
|
|||
|
* fill-column: 78
|
|||
|
* End:
|
|||
|
*/
|