From f97029e9b2d61b827b8f6380b65e7b98f6677ac0 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 5 Nov 2003 02:11:49 +0000 Subject: [PATCH] Reorganize GSString class hierarchy. Update users. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@18050 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 15 ++ Source/GSPrivate.h | 3 +- Source/GSString.m | 506 ++++++++++++++++++++++++------------------ Source/NSSerializer.m | 19 +- 4 files changed, 315 insertions(+), 228 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9b622e1ee..0efc0a5f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2003-11-05 03:10 Alexander Malmberg + + * Source/GSString.m: Reorganize class heirarchy. Remove unused + GSCEmptyString class. Add new concrete leaf classes GSCBufferString + and GSCUnicodeString. Make GSString, GSCString, and GSUnicodeString + abstract and move the real memory management code to the two new + classes. Update the other concrete leaf classes. Update callers. + + * Source/GSPrivate.h: Update comment about the semantics of the free + flag in GSString. + + * Source/NSSerializer.m: Clarify comments about the cached classes. + Use GSCBufferString and GSUnicodeBufferString instead of GSCString + and GSUnicodeString when creating string instances. + Mon Nov 03 12:30:00 2003 Richard Frith-Macdonald * Source/NSNotificationCenter.m: Use locking at all times until diff --git a/Source/GSPrivate.h b/Source/GSPrivate.h index b61d7d1ca..43b248c89 100644 --- a/Source/GSPrivate.h +++ b/Source/GSPrivate.h @@ -76,7 +76,8 @@ GS_EXPORT BOOL GSIsByteEncoding(NSStringEncoding encoding); unsigned int _count; struct { unsigned int wide: 1; // 16-bit characters in string? - unsigned int free: 1; // Should free memory? + unsigned int free: 1; // Set if the instance owns the + // _contents buffer unsigned int unused: 2; unsigned int hash: 28; } _flags; diff --git a/Source/GSString.m b/Source/GSString.m index 109f99085..dcf24b1eb 100644 --- a/Source/GSString.m +++ b/Source/GSString.m @@ -61,6 +61,7 @@ struct objc_class _NSConstantStringClassReference; #endif + /* * GSPlaceholderString - placeholder class for objects awaiting intialisation. */ @@ -69,71 +70,116 @@ struct objc_class _NSConstantStringClassReference; } @end + /* - * GSCString - concrete class for strings using 8-bit character sets. - */ +GSString is the root class of our hierarchy of string classes. All our +classes except GSPlaceholderString inherit from it. GSString provides +the common part of the ivar layout. It also has safe implementations +of all the memory management methods subclasses should override. + +Concrete subclasses of GSString are identified by two properties: +how the string is encoded (its structure; 8-bit data or 16-bit unicode +data), and how the memory for the contents is handled (its memory +management). + +Two direct subclasses of GSString provide the code for the two structures. +The memory management part of the concrete subclasses is abstracted to +a single flag for the structure classes: free. This is set only if the +_contents buffer is guaranteed to remain valid at least until the instance +has been deallocated. + +(It really should be named 'ownsContents' or something similar, but it's +'free' in GSMutableString, and the structures need to be interchangeable.) + +Many optimizations, such as retaining instead of copying, and using pointers +to another strings _contents buffer, are valid only if this flag is set. + +GSCString, an abstract class that stores the string as 8-bit data in the +internal encoding. GSCString and its subclasses are used only if +intEnc==defEnc. +*/ @interface GSCString : GSString { } @end /* - * GSCInlineString - concrete subclass of GSCString, that expects the - * characterData to appear in memory immediately after the object itsself. - */ -@interface GSCInlineString : GSCString -{ -} -@end - -/* - * GSCSubString - concrete subclass of GSCString, that relies on the - * data stored in a GSCString object. - */ -@interface GSCSubString : GSCString -{ -@public - GSCString *_parent; -} -@end - -/* - * GSCEmptyString - concrete class for empty string - */ -@interface GSCEmptyString : GSCString -{ -} -@end - -/* - * GSUnicodeString - concrete class for strings using 16-bit character sets. - */ +And GSUnicodeString, an abstract class that stores the string as 16-bit +unicode characters. +*/ @interface GSUnicodeString : GSString { } @end + /* - * GSUnicodeInlineString - concrete subclass of GSUnicodeString, that - * expects the characterData to appear in memory immediately after the - * object itsself. - */ +For each memory management scheme, there is a pair of concrete subclasses +of the two abstract structure classes. Each subclass has a single -init... +method which can be used to initialize that specific subclass. + +GS*BufferString, concrete subclasses that store the data in an external +(wrt. the instance itself) buffer. The buffer may or may not be owned +by the instance; the 'free' flag indicates which. If it is set, +we need to free the buffer when we are deallocated. +*/ +@interface GSCBufferString : GSCString +{ +} +- (id) initWithCStringNoCopy: (char*)chars + length: (unsigned int)length + freeWhenDone: (BOOL)flag; +@end + +@interface GSUnicodeBufferString : GSUnicodeString +{ +} +- (id) initWithCharactersNoCopy: (unichar *)chars + length: (unsigned int)length + freeWhenDone: (BOOL)flag; +@end + + +/* +GS*InlineString, concrete subclasses that store the data immediately after +the instance iself. +*/ +@interface GSCInlineString : GSCString +{ +} +- (id) initWithCString: (const char*)chars length: (unsigned)length; +@end + @interface GSUnicodeInlineString : GSUnicodeString { } +- (id) initWithCharacters: (const unichar*)chars length: (unsigned)length; @end + /* - * GSUnicodeSubString - concrete subclass of GSUnicodeString, that - * relies on data stored in a GSUnicodeString object. - */ +GS*SubString, concrete subclasses that use the data in another string +instance. +*/ +@interface GSCSubString : GSCString +{ +@public + GSCString *_parent; +} +- (id) initWithCString: (char *)chars length: (unsigned)length + fromParent: (GSCString *)parent; +@end + @interface GSUnicodeSubString : GSUnicodeString { @public GSUnicodeString *_parent; } +- (id) initWithCharacters: (unichar *)chars length: (unsigned)length + fromParent: (GSUnicodeString *)parent; @end + /* * GSMutableString - concrete mutable string, capable of changing its storage * from holding 8-bit to 16-bit character set. @@ -207,9 +253,11 @@ static Class NSDataClass = 0; static Class NSStringClass = 0; static Class GSStringClass = 0; static Class GSCStringClass = 0; +static Class GSCBufferStringClass = 0; static Class GSCInlineStringClass = 0; static Class GSCSubStringClass = 0; static Class GSUnicodeStringClass = 0; +static Class GSUnicodeBufferStringClass = 0; static Class GSUnicodeSubStringClass = 0; static Class GSUnicodeInlineStringClass = 0; static Class GSMutableStringClass = 0; @@ -250,6 +298,8 @@ setup(void) GSStringClass = [GSString class]; GSCStringClass = [GSCString class]; GSUnicodeStringClass = [GSUnicodeString class]; + GSCBufferStringClass = [GSCBufferString class]; + GSUnicodeBufferStringClass = [GSUnicodeBufferString class]; GSCInlineStringClass = [GSCInlineString class]; GSUnicodeInlineStringClass = [GSUnicodeInlineString class]; GSCSubStringClass = [GSCSubString class]; @@ -319,11 +369,11 @@ setup(void) - (void) dealloc { - return; // placeholders never get deallocated. + return; // Placeholders never get deallocated. } /* - * Replace self with an inline unicode string + * Replace self with an inline unicode string. */ - (id) initWithCharacters: (const unichar*)chars length: (unsigned)length @@ -335,12 +385,13 @@ setup(void) me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1]; me->_count = length; me->_flags.wide = 1; + me->_flags.free = 1; memcpy(me->_contents.u, chars, length*sizeof(unichar)); return (id)me; } /* - * Replace self with a simple unicode string + * Replace self with a simple unicode string. */ - (id) initWithCharactersNoCopy: (unichar*)chars length: (unsigned)length @@ -348,7 +399,7 @@ setup(void) { ivars me; - me = (ivars)NSAllocateObject(GSUnicodeStringClass, 0, GSObjCZone(self)); + me = (ivars)NSAllocateObject(GSUnicodeBufferStringClass, 0, GSObjCZone(self)); me->_contents.u = chars; me->_count = length; me->_flags.wide = 1; @@ -360,7 +411,7 @@ setup(void) } /* - * Replace self with an inline 'C' string + * Replace self with an inline 'C' string. */ - (id) initWithCString: (const char*)chars length: (unsigned)length @@ -374,6 +425,7 @@ setup(void) me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1]; me->_count = length; me->_flags.wide = 0; + me->_flags.free = 1; memcpy(me->_contents.c, chars, length); return (id)me; } @@ -401,7 +453,7 @@ setup(void) { ivars me; - me = (ivars)NSAllocateObject(GSCStringClass, 0, GSObjCZone(self)); + me = (ivars)NSAllocateObject(GSCBufferStringClass, 0, GSObjCZone(self)); me->_contents.c = (unsigned char*)chars; me->_count = length; me->_flags.wide = 0; @@ -464,6 +516,7 @@ setup(void) me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1]; me->_count = length; me->_flags.wide = 0; + me->_flags.free = 1; memcpy(me->_contents.c, ((ivars)string)->_contents.c, length); } else if (GSObjCIsKindOf(c, GSUnicodeStringClass) == YES @@ -478,6 +531,7 @@ setup(void) me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1]; me->_count = length; me->_flags.wide = 1; + me->_flags.free = 1; memcpy(me->_contents.u, ((ivars)string)->_contents.u, length*sizeof(unichar)); } @@ -492,6 +546,7 @@ setup(void) me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1]; me->_count = length; me->_flags.wide = 1; + me->_flags.free = 1; [string getCharacters: me->_contents.u]; } return (id)me; @@ -521,9 +576,11 @@ setup(void) * The following inline functions are used by the concrete string classes * to implement their core functionality. * GSCString uses the functions with the _c suffix. - * GSCSubString and ??ConstantString inherit methods from GSCString. + * GSCSubString, GSCInlineString, GSCBufferString, and ??ConstantString + * inherit methods from GSCString. * GSUnicodeString uses the functions with the _u suffix. - * GSUnicodeSubString inherits methods from GSUnicodeString. + * GSUnicodeSubString, GSUnicodeInlineString, and GSUnicodeBufferString + * inherit methods from GSUnicodeString. * GSMutableString uses all the functions, selecting the _c or _u versions * depending on whether its storage is 8-bit or 16-bit. * In addition, GSMutableString uses a few functions without a suffix that are @@ -1692,13 +1749,9 @@ substring_c(ivars self, NSRange aRange) if (self->_flags.free == 1) { sub = NSAllocateObject(GSCSubStringClass, 0, NSDefaultMallocZone()); - sub = [sub initWithCStringNoCopy: self->_contents.c + aRange.location - length: aRange.length - freeWhenDone: NO]; - if (sub != nil) - { - ((GSCSubString*)sub)->_parent = RETAIN((id)self); - } + sub = [sub initWithCString: self->_contents.c + aRange.location + length: aRange.length + fromParent: (GSCString *)self]; } else { @@ -1719,13 +1772,9 @@ substring_u(ivars self, NSRange aRange) if (self->_flags.free == 1) { sub = NSAllocateObject(GSUnicodeSubStringClass, 0, NSDefaultMallocZone()); - sub = [sub initWithCharactersNoCopy: self->_contents.u + aRange.location - length: aRange.length - freeWhenDone: NO]; - if (sub != nil) - { - ((GSUnicodeSubString*)sub)->_parent = RETAIN((id)self); - } + sub = [sub initWithCharacters: self->_contents.u + aRange.location + length: aRange.length + fromParent: (GSUnicodeString *)self]; } else { @@ -1862,11 +1911,12 @@ transmute(ivars self, NSString *aString) /* * The GSString class is actually only provided to provide a common ivar * layout for all subclasses, so that they can all share the same code. - * We don't expect this class to ever be instantiated, but we do provide - * a common deallocation method, and standard initialisation methods that - * will try to convert an instance to a type we can really use if necessary. + * This class should never be instantiated, and with the exception of + * -copyWithZone:, none of its memory management related methods + * (initializers and -dealloc) should ever be called. We guard against + * this happening. */ -@implementation GSString +@implementation GSString + (void) initialize { @@ -1875,12 +1925,7 @@ transmute(ivars self, NSString *aString) - (void) dealloc { - if (_flags.free == 1 && _contents.c != 0) - { - NSZoneFree(NSZoneFromPointer(_contents.c), _contents.c); - _contents.c = 0; - } - NSDeallocateObject(self); + [self subclassResponsibility: _cmd]; } /* @@ -1890,23 +1935,8 @@ transmute(ivars self, NSString *aString) length: (unsigned int)length freeWhenDone: (BOOL)flag { - if (isa == GSStringClass) - { - isa = GSUnicodeStringClass; - } - else if (_contents.u != 0) - { - [NSException raise: NSInternalInconsistencyException - format: @"re-initialisation of string"]; - } - _count = length; - _contents.u = chars; - _flags.wide = 1; - if (flag == YES) - { - _flags.free = 1; - } - return self; + [self subclassResponsibility: _cmd]; + return nil; } /* @@ -1917,33 +1947,20 @@ transmute(ivars self, NSString *aString) length: (unsigned int)length freeWhenDone: (BOOL)flag { - if (isa == GSStringClass) - { - isa = GSCStringClass; - } - else if (_contents.c != 0) - { - [NSException raise: NSInternalInconsistencyException - format: @"re-initialisation of string"]; - } - _count = length; - _contents.c = chars; - _flags.wide = 0; - if (flag == YES) - { - _flags.free = 1; - } - return self; + [self subclassResponsibility: _cmd]; + return nil; } + +- (id) copyWithZone: (NSZone*)z +{ + [self subclassResponsibility: _cmd]; + return nil; +} + @end -/* - * The GSCString class is the basic implementation of a concrete - * 8-bit string class, storing immutable data in a single buffer. - * It is only ever used when defEnc==intEnc - */ @implementation GSCString - (const char *) UTF8String { @@ -1972,23 +1989,6 @@ transmute(ivars self, NSString *aString) return compare_c((ivars)self, aString, mask, aRange); } -- (id) copyWithZone: (NSZone*)z -{ - if (_flags.free == NO - || NSShouldRetainWithZone(self, z) == NO) - { - NSString *obj; - - obj = (NSString*)NSAllocateObject(GSCInlineStringClass, _count, z); - obj = [obj initWithCString: _contents.c length: _count]; - return obj; - } - else - { - return RETAIN(self); - } -} - - (const char *) cString { return cString_c((ivars)self); @@ -2160,41 +2160,13 @@ transmute(ivars self, NSString *aString) return _count; } -@end - - - /* - * The GSCInlineString class is a GSCString subclass that stores data - * in memory immediately after the object. - */ -@implementation GSCInlineString -- (id) initWithCStringNoCopy: (char*)chars - length: (unsigned)length - freeWhenDone: (BOOL)flag -{ - RELEASE(self); - [NSException raise: NSInternalInconsistencyException - format: @"Illegal method used to initialise inline string"]; - return nil; -} -- (id) initWithCString: (const char*)chars length: (unsigned)length -{ - if (_contents.c != 0) - { - [NSException raise: NSInternalInconsistencyException - format: @"re-initialisation of string"]; - } - _count = length; - _contents.c = (unsigned char*)&self[1]; - if (_count > 0) - memcpy(_contents.c, chars, length); - _flags.wide = 0; - return self; -} +Default copy implementation. Retain if we own the buffer and the zones +agree, create a new GSCInlineString otherwise. +*/ - (id) copyWithZone: (NSZone*)z { - if (NSShouldRetainWithZone(self, z) == NO) + if (!_flags.free || NSShouldRetainWithZone(self, z) == NO) { NSString *obj; @@ -2207,6 +2179,61 @@ transmute(ivars self, NSString *aString) return RETAIN(self); } } + +@end + + + +@implementation GSCBufferString +- (id) initWithCStringNoCopy: (char*)chars + length: (unsigned int)length + freeWhenDone: (BOOL)flag +{ + if (_contents.c != 0) + { + [NSException raise: NSInternalInconsistencyException + format: @"re-initialisation of string"]; + } + _count = length; + _contents.c = chars; + _flags.wide = 0; + if (flag == YES) + { + _flags.free = 1; + } + return self; +} + +- (void) dealloc +{ + if (_flags.free && _contents.c != 0) + { + NSZoneFree(NSZoneFromPointer(_contents.c), _contents.c); + _contents.c = 0; + } + NSDeallocateObject(self); +} +@end + + + +@implementation GSCInlineString +- (id) initWithCString: (const char*)chars length: (unsigned)length +{ + if (_contents.c != 0) + { + [NSException raise: NSInternalInconsistencyException + format: @"re-initialisation of string"]; + } + _count = length; + _contents.c = (unsigned char*)&self[1]; + if (_count > 0) + memcpy(_contents.c, chars, length); + _flags.wide = 0; + _flags.free = 1; + return self; +} + - (void) dealloc { NSDeallocateObject(self); @@ -2215,11 +2242,23 @@ transmute(ivars self, NSString *aString) -/* - * The GSCSubString class is a GSCString subclass that points into - * a section of a parent constant string class. - */ @implementation GSCSubString +- (id) initWithCString: (char *)chars length: (unsigned)length + fromParent: (GSCString *)parent +{ + if (_contents.c != 0) + { + [NSException raise: NSInternalInconsistencyException + format: @"re-initialisation of string"]; + } + _count = length; + _contents.c = (unsigned char *)chars; + _flags.wide = 0; + _flags.free = 1; + ASSIGN(_parent, parent); + return self; +} + /* * Assume that a copy should be a new string, never just a retained substring. */ @@ -2231,9 +2270,10 @@ transmute(ivars self, NSString *aString) obj = [obj initWithCString: _contents.c length: _count]; return obj; } + - (void) dealloc { - RELEASE(_parent); + DESTROY(_parent); NSDeallocateObject(self); } @end @@ -2268,24 +2308,6 @@ transmute(ivars self, NSString *aString) return compare_u((ivars)self, aString, mask, aRange); } -- (id) copyWithZone: (NSZone*)z -{ - if (_flags.free == NO - || NSShouldRetainWithZone(self, z) == NO) - { - NSString *obj; - - obj = (NSString*)NSAllocateObject(GSUnicodeInlineStringClass, - _count*sizeof(unichar), z); - obj = [obj initWithCharacters: _contents.u length: _count]; - return obj; - } - else - { - return RETAIN(self); - } -} - - (const char *) cString { return cString_u((ivars)self); @@ -2466,37 +2488,13 @@ transmute(ivars self, NSString *aString) return blen; } -@end - - - -@implementation GSUnicodeInlineString -- (id) initWithCharactersNoCopy: (unichar*)chars - length: (unsigned)length - freeWhenDone: (BOOL)flag -{ - RELEASE(self); - [NSException raise: NSInternalInconsistencyException - format: @"Illegal method used to initialise inline string"]; - return nil; -} -- (id) initWithCharacters: (const unichar*)chars length: (unsigned)length -{ - if (_contents.u != 0) - { - [NSException raise: NSInternalInconsistencyException - format: @"re-initialisation of string"]; - } - _count = length; - _contents.u = (unichar*)&((GSUnicodeInlineString*)self)[1]; - if (_count > 0) - memcpy(_contents.u, chars, length*sizeof(unichar)); - _flags.wide = 1; - return self; -} +/* +Default -copy implementation. Retain if we own the buffer and the zones +agree, create a new GSUnicodeInlineString otherwise. +*/ - (id) copyWithZone: (NSZone*)z { - if (NSShouldRetainWithZone(self, z) == NO) + if (!_flags.free || NSShouldRetainWithZone(self, z) == NO) { NSString *obj; @@ -2510,6 +2508,61 @@ transmute(ivars self, NSString *aString) return RETAIN(self); } } + +@end + + + +@implementation GSUnicodeBufferString +- (id) initWithCharactersNoCopy: (unichar *)chars + length: (unsigned int)length + freeWhenDone: (BOOL)flag +{ + if (_contents.u != 0) + { + [NSException raise: NSInternalInconsistencyException + format: @"re-initialisation of string"]; + } + _count = length; + _contents.u = chars; + _flags.wide = 1; + if (flag == YES) + { + _flags.free = 1; + } + return self; +} + +- (void) dealloc +{ + if (_flags.free && _contents.u != 0) + { + NSZoneFree(NSZoneFromPointer(_contents.u), _contents.u); + _contents.u = 0; + } + NSDeallocateObject(self); +} +@end + + + +@implementation GSUnicodeInlineString +- (id) initWithCharacters: (const unichar*)chars length: (unsigned)length +{ + if (_contents.u != 0) + { + [NSException raise: NSInternalInconsistencyException + format: @"re-initialisation of string"]; + } + _count = length; + _contents.u = (unichar*)&((GSUnicodeInlineString*)self)[1]; + if (_count > 0) + memcpy(_contents.u, chars, length*sizeof(unichar)); + _flags.wide = 1; + _flags.free = 1; + return self; +} + - (void) dealloc { NSDeallocateObject(self); @@ -2518,11 +2571,23 @@ transmute(ivars self, NSString *aString) -/* - * The GSUnicodeSubString class is a GSUnicodeString subclass that points - * into a section of a parent constant string class. - */ @implementation GSUnicodeSubString +- (id) initWithCharacters: (unichar *)chars length: (unsigned)length + fromParent: (GSUnicodeString *)parent +{ + if (_contents.u != 0) + { + [NSException raise: NSInternalInconsistencyException + format: @"re-initialisation of string"]; + } + _count = length; + _contents.u = chars; + _flags.wide = 1; + _flags.free = 1; + ASSIGN(_parent, parent); + return self; +} + /* * Assume that a copy should be a new string, never just a retained substring. */ @@ -2535,9 +2600,10 @@ transmute(ivars self, NSString *aString) obj = [obj initWithCharacters: _contents.u length: _count]; return obj; } + - (void) dealloc { - RELEASE(_parent); + DESTROY(_parent); NSDeallocateObject(self); } @end @@ -2982,11 +3048,11 @@ transmute(ivars self, NSString *aString) #endif if (_flags.wide == 1) { - isa = [GSUnicodeString class]; + isa = [GSUnicodeBufferString class]; } else { - isa = [GSCString class]; + isa = [GSCBufferString class]; } #ifndef NDEBUG GSDebugAllocationAdd(isa, self); @@ -3895,7 +3961,7 @@ transmute(ivars self, NSString *aString) NSLog(@"Warning - decoding archive containing obsolete %@ object - please delete/replace this archive", NSStringFromClass([self class])); RELEASE(self); - self = (id)NSAllocateObject(GSCStringClass, 0, NSDefaultMallocZone()); + self = (id)NSAllocateObject(GSCBufferStringClass, 0, NSDefaultMallocZone()); [aCoder decodeValueOfObjCType: @encode(unsigned) at: &count]; if (count > 0) { @@ -3957,7 +4023,7 @@ transmute(ivars self, NSString *aString) NSLog(@"Warning - decoding archive containing obsolete %@ object - please delete/replace this archive", NSStringFromClass([self class])); RELEASE(self); - self = (id)NSAllocateObject(GSUnicodeStringClass, 0, NSDefaultMallocZone()); + self = (id)NSAllocateObject(GSUnicodeBufferStringClass, 0, NSDefaultMallocZone()); [aCoder decodeValueOfObjCType: @encode(unsigned) at: &count]; if (count > 0) { diff --git a/Source/NSSerializer.m b/Source/NSSerializer.m index 17b75dcd1..d7baca1bb 100644 --- a/Source/NSSerializer.m +++ b/Source/NSSerializer.m @@ -45,9 +45,11 @@ @class GSMutableDictionary; @class NSDataMalloc; @class GSInlineArray; -@class GSMutableArray; +@class GSMutableArray; @class GSCString; +@class GSCBufferString; @class GSUnicodeString; +@class GSUnicodeBufferString; @class GSMutableString; /* @@ -100,7 +102,8 @@ static char st_number = (char)ST_NUMBER; /* - * Variables to cache class information. + * Variables to cache class information. These are used to check how + * an instance should be serialized. */ static Class ArrayClass = 0; static Class MutableArrayClass = 0; @@ -421,10 +424,12 @@ static BOOL shouldBeCompact = NO; -/* - * Variables to cache class information. - */ static BOOL uniquing = NO; /* Make incoming strings unique */ + +/* + * Variables to cache class information. These are used to create instances + * when deserializing. + */ static Class MACls = 0; /* Mutable Array */ static Class DCls = 0; /* Data */ static Class MDCls = 0; /* Mutable Dictionary */ @@ -818,8 +823,8 @@ deserializeFromInfo(_NSDeserializerInfo* info) MACls = [GSMutableArray class]; DCls = [NSDataMalloc class]; MDCls = [GSMutableDictionary class]; - USCls = [GSUnicodeString class]; - CSCls = [GSCString class]; + USCls = [GSUnicodeBufferString class]; + CSCls = [GSCBufferString class]; csInitImp = [CSCls instanceMethodForSelector: csInitSel]; usInitImp = [USCls instanceMethodForSelector: usInitSel]; dInitImp = [DCls instanceMethodForSelector: dInitSel];