String Services includes only a handful of functions for creating mutable CFString objects. The reason for this much smaller set is obvious. Because these are mutable objects, you can modify them after you create them with the functions described in Manipulating Mutable String Objects.
There are two basic functions for creating mutable CFString objects. The
CFStringCreateMutable
function creates an "empty" object; the
CFStringCreateMutableCopy
makes a mutable copy of an immutable CFString object. Listing 5 illustrates the latter function and shows a character being appended to the created object:
Listing 5 Creating a mutable copy of a CFString object
const UniChar u[] = {'5', '+', '*', `d', 'x', '4', 'Q', '?'}; CFMutableStringRef str; str = CFStringCreateMutableCopy(alloc, 0, CFSTR("abc")); CFStringAppendCharacters(str, &u[3], 1); CFRelease(str);
The second parameter of both functions is a
CFIndex
value named
maxLength
. This value specifies the maximum numbers of characters in the string and allows the created object to optimize its storage and catch errors if too many characters are inserted. If zero is specified for this parameter (as above), the string can grow to any size.
When you create most Core Foundation objects, the object takes the initializing data you provide and stores that data internally. String Services allows some exceptions to this behavior, and for mutable CFString objects that exception is the
CFStringCreateMutableWithExternalCharactersNoCopy
function. This function creates a mutable CFString object whose backing store is some Unicode buffer that you create and own. You can test and manipulate this buffer independently of the object.
Listing 6 shows how to create such a cheap mutable CFString "wrapper" for your character buffer.
Listing 6 Creating a mutable CFString object with independent backing store
void stringWithExternalContentsExample(void) { #define BufferSize 1000 CFMutableStringRef mutStr; UniChar *myBuffer; myBuffer = malloc(BufferSize * sizeof(UniChar)); mutStr = CFStringCreateMutableWithExternalCharactersNoCopy(NULL, myBuffer, 0, BufferSize, kCFAllocatorNull); CFStringAppend(mutStr, CFSTR("Appended string... ")); CFStringAppend(mutStr, CFSTR("More stuff... ")); CFStringAppendPascalString(mutStr, "\pA pascal string. ", CFStringGetSystemEncoding()); CFStringAppendFormat(mutStr, NULL, CFSTR("%d %4.2f %@..."), 42, -3.14, CFSTR("Hello")); CFRelease(mutStr); free(myBuffer); }
The third and fourth parameters in the creation function specify the number of characters in the buffer and the buffer capacity; as with the other mutable creation functions, if the capacity parameter is zero, no limit is placed on growth. The final parameter,
externalCharsAllocator
, specifies the CFAllocator object to use for reallocating the buffer when editing takes place and for deallocating the buffer when the CFString object is deallocated. In the above example,
kCFAllocatorNull
is specified, which tells the object that the client assumes responsibility for these actions. If you specified an allocator object to use, such as
NULL
for the default allocator, there is usually no need to worry about reallocation or deallocation of the buffer.
The example illustrates how you can modify the contents of the buffer with CFString functions. You can also modify the contents of the buffer directly, but if you do so, you must notify the mutable CFString "wrapper" object with the
CFStringSetExternalCharactersNoCopy
function. You can also substitute an entirely different buffer with this function because it makes the mutable CFString object point directly at the specified
UniChar
array as its backing store. (However, the CFString object must have been created with the
CFStringCreateMutableWithExternalCharactersNoCopy
function.) The
CFStringSetExternalCharactersNoCopy
function does not free the previous buffer.
Using these functions comes at a cost because some CFString optimizations are invalidated. For example, mutable CFString objects can no longer use a gap for editing, and they cannot optimize storage by using 8-bit characters.