diff --git a/Source/NSArray.m b/Source/NSArray.m
index e991f4d80..c493813e2 100644
--- a/Source/NSArray.m
+++ b/Source/NSArray.m
@@ -39,6 +39,8 @@
#include
+@class NSGMutableCString;
+
@class NSArrayEnumerator;
@class NSArrayEnumeratorReverse;
@@ -601,7 +603,8 @@ static Class NSMutableArray_concrete_class;
{
NSMutableString *result;
- result = [NSMutableString stringWithCapacity: 20*[self count]];
+ result = [[[NSGMutableCString alloc] initWithCapacity: 20*[self count]]
+ autorelease];
[self descriptionWithLocale: locale
indent: level
to: (id)result];
diff --git a/Source/NSDictionary.m b/Source/NSDictionary.m
index 969a4b2bf..e0f56a3ef 100644
--- a/Source/NSDictionary.m
+++ b/Source/NSDictionary.m
@@ -39,6 +39,8 @@
@implementation NSDictionary
+@class NSGMutableCString;
+
@class NSGDictionary;
@class NSGMutableDictionary;
@@ -503,10 +505,11 @@ compareIt(id o1, id o2, void* context)
- (NSString*) descriptionInStringsFileFormat
{
- NSMutableString *result = [NSMutableString stringWithCapacity: 1024];
+ NSMutableString *result;
NSEnumerator *enumerator;
id key;
+ result = [[[NSGMutableCString alloc] initWithCapacity: 1024] autorelease];
enumerator = [self keyEnumerator];
while ((key = [enumerator nextObject]) != nil)
{
@@ -536,7 +539,8 @@ compareIt(id o1, id o2, void* context)
{
NSMutableString *result;
- result = [NSMutableString stringWithCapacity: 20*[self count]];
+ result = [[[NSGMutableCString alloc] initWithCapacity: 20*[self count]]
+ autorelease];
[self descriptionWithLocale: locale
indent: level
to: (id)result];
diff --git a/Source/NSGCString.m b/Source/NSGCString.m
index 2c004f07c..38ff4e7f8 100644
--- a/Source/NSGCString.m
+++ b/Source/NSGCString.m
@@ -74,6 +74,10 @@ static SEL msInitSel = @selector(initWithCapacity:);
static IMP csInitImp; /* designated initialiser for cString */
static IMP msInitImp; /* designated initialiser for mutable */
+@interface NSGMutableCString (GNUDescription)
+- (char*) _extendBy: (unsigned)len;
+@end
+
@implementation NSGCString
+ (void) initialize
@@ -539,6 +543,9 @@ static IMP msInitImp; /* designated initialiser for mutable */
- (void) descriptionTo: (id)output
{
+ if (output == nil)
+ return;
+
if (_count == 0)
{
[output appendString: @"\"\""];
@@ -586,11 +593,21 @@ static IMP msInitImp; /* designated initialiser for mutable */
if (needQuote || length != _count)
{
- NSZone *z = fastZone(self);
- char *buf = NSZoneMalloc(z, length+3);
- char *ptr = buf;
- NSString *result;
+ Class c = fastClass(output);
+ NSZone *z = NSDefaultMallocZone();
+ char *buf;
+ char *ptr;
+ length += 2;
+ if (c == _fastCls._NSGMutableCString)
+ {
+ buf = [(NSGMutableCString*)output _extendBy: length];
+ }
+ else
+ {
+ buf = NSZoneMalloc(z, length+1);
+ }
+ ptr = buf;
*ptr++ = '"';
for (i = 0; i < _count; i++)
{
@@ -626,10 +643,15 @@ static IMP msInitImp; /* designated initialiser for mutable */
}
*ptr++ = '"';
*ptr = '\0';
- result = [[_fastCls._NSGCString allocWithZone: NSDefaultMallocZone()]
- initWithCStringNoCopy: buf length: length+2 fromZone: z];
- [output appendString: result];
- [result release];
+ if (c != _fastCls._NSGMutableCString)
+ {
+ NSString *result;
+
+ result = [[_fastCls._NSGCString allocWithZone: z]
+ initWithCStringNoCopy: buf length: length fromZone: z];
+ [output appendString: result];
+ [result release];
+ }
}
else
{
@@ -757,6 +779,14 @@ typedef struct {
@defs(NSGMutableCString)
} NSGMutableCStringStruct;
+static inline void
+stringGrowBy(NSGMutableCStringStruct *self, unsigned size)
+{
+ self->_capacity = MAX(self->_capacity*2, self->_count+size+1);
+ self->_contents_chars
+ = NSZoneRealloc(self->_zone, self->_contents_chars, self->_capacity);
+}
+
static inline void
stringIncrementCountAndMakeHoleAt(NSGMutableCStringStruct *self,
int index, int size)
@@ -939,10 +969,7 @@ stringDecrementCountAndFillHoleAt(NSGMutableCStringStruct *self,
unsigned c = [aString cStringLength];
char save;
if (_count + c >= _capacity)
- {
- _capacity = MAX(_capacity*2, _count+c+1);
- _contents_chars = NSZoneRealloc(_zone, _contents_chars, _capacity);
- }
+ stringGrowBy((NSGMutableCStringStruct *)self, c);
stringIncrementCountAndMakeHoleAt((NSGMutableCStringStruct*)self, index, c);
save = _contents_chars[index+c]; // getCString will put a nul here.
[aString getCString: _contents_chars + index];
@@ -961,11 +988,7 @@ stringDecrementCountAndFillHoleAt(NSGMutableCStringStruct *self,
unsigned l = other->_count;
if (_count + l > _capacity)
- {
- _capacity = MAX(_capacity*2, _count+l);
- _contents_chars =
- NSZoneRealloc(fastZone(self), _contents_chars, _capacity);
- }
+ stringGrowBy((NSGMutableCStringStruct *)self, l);
memcpy(_contents_chars + _count, other->_contents_chars, l);
_count += l;
_hash = 0;
@@ -974,11 +997,7 @@ stringDecrementCountAndFillHoleAt(NSGMutableCStringStruct *self,
{
unsigned l = [aString cStringLength];
if (_count + l >= _capacity)
- {
- _capacity = MAX(_capacity*2, _count+l+1);
- _contents_chars =
- NSZoneRealloc(fastZone(self), _contents_chars, _capacity);
- }
+ stringGrowBy((NSGMutableCStringStruct *)self, l);
[aString getCString: _contents_chars + _count];
_count += l;
_hash = 0;
@@ -1061,6 +1080,16 @@ stringDecrementCountAndFillHoleAt(NSGMutableCStringStruct *self,
stringDecrementCountAndFillHoleAt((NSGMutableCStringStruct*)self, index, 1);
}
+- (char*) _extendBy: (unsigned)len
+{
+ char *ptr;
+
+ stringGrowBy((NSGMutableCStringStruct *)self, len);
+ ptr = _contents_chars + _count;
+ _count += len;
+ _hash = 0;
+ return ptr;
+}
@end
@implementation NXConstantString
diff --git a/Source/NSSerializer.m b/Source/NSSerializer.m
index 6619eeea1..436d08071 100644
--- a/Source/NSSerializer.m
+++ b/Source/NSSerializer.m
@@ -24,7 +24,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -32,10 +31,10 @@
#include
#include
-@class NSGCString;
-@class NSGString;
-@class NSGArray;
-@class NSGMutableArray;
+#include
+#include
+#include
+
@class NSGDictionary;
@class NSGMutableDictionary;
@class NSDataMalloc;
@@ -82,6 +81,14 @@ static char st_dict = (char)ST_DICT;
static char st_mdict = (char)ST_MDICT;
static char st_data = (char)ST_DATA;
+typedef struct {
+ @defs(NSGArray)
+} NSGArrayStruct;
+
+typedef struct {
+ @defs(NSGMutableArray)
+} NSGMutableArrayStruct;
+
/*
@@ -339,11 +346,13 @@ static BOOL shouldBeCompact = NO;
/*
* Variables to cache class information.
*/
-static Class GArrayClass = 0;
-static Class GMutableArrayClass = 0;
-static Class GDataClass = 0;
-static Class GDictionaryClass = 0;
-static Class GMutableDictionaryClass = 0;
+static Class IACls = 0; /* Immutable Array */
+static Class MACls = 0; /* Mutable Array */
+static Class DCls = 0; /* Data */
+static Class IDCls = 0; /* Immutable Dictionary */
+static Class MDCls = 0; /* Mutable Dictionary */
+static Class USCls = 0; /* Unicode String */
+static Class CSCls = 0; /* C String */
typedef struct {
NSData *data;
@@ -355,8 +364,22 @@ typedef struct {
FastArray_t array;
} _NSDeserializerInfo;
-static SEL debSel = @selector(deserializeBytes:length:atCursor:);
-static SEL deiSel = @selector(deserializeIntAtCursor:);
+static SEL debSel = @selector(deserializeBytes:length:atCursor:);
+static SEL deiSel = @selector(deserializeIntAtCursor:);
+static SEL csInitSel = @selector(initWithCStringNoCopy:length:fromZone:);
+static SEL usInitSel = @selector(initWithCharactersNoCopy:length:fromZone:);
+static SEL dInitSel = @selector(initWithBytesNoCopy:length:fromZone:);
+static SEL iaInitSel = @selector(initWithObjects:count:);
+static SEL maInitSel = @selector(initWithObjects:count:);
+static SEL idInitSel = @selector(initWithObjects:forKeys:count:);
+static SEL mdInitSel = @selector(initWithObjects:forKeys:count:);
+static IMP csInitImp;
+static IMP usInitImp;
+static IMP dInitImp;
+static IMP iaInitImp;
+static IMP maInitImp;
+static IMP idInitImp;
+static IMP mdInitImp;
static void
initDeserializerInfo(_NSDeserializerInfo* info, NSData *d, unsigned *c, BOOL m)
@@ -400,10 +423,8 @@ deserializeFromInfo(_NSDeserializerInfo* info)
char *b = objc_malloc(size);
(*info->debImp)(info->data, debSel, b, size, info->cursor);
- s = [_fastCls._NSGCString allocWithZone: NSDefaultMallocZone()];
- s = [s initWithCStringNoCopy: b
- length: size-1
- fromZone: NSDefaultMallocZone()];
+ s = (NSGCString*)NSAllocateObject(CSCls, 0, NSDefaultMallocZone());
+ s = (*csInitImp)(s, csInitSel, b, size-1, NSDefaultMallocZone());
if (info->didUnique)
FastArrayAddItem(&info->array, (FastArrayItem)s);
return s;
@@ -415,10 +436,8 @@ deserializeFromInfo(_NSDeserializerInfo* info)
unichar *b = objc_malloc(size*2);
(*info->debImp)(info->data, debSel, b, size*2, info->cursor);
- s = [_fastCls._NSGString allocWithZone: NSDefaultMallocZone()];
- s = [s initWithCharactersNoCopy: b
- length: size
- fromZone: NSDefaultMallocZone()];
+ s = (NSGString*)NSAllocateObject(USCls, 0, NSDefaultMallocZone());
+ s = (*usInitImp)(s, usInitSel, b, size, NSDefaultMallocZone());
if (info->didUnique)
FastArrayAddItem(&info->array, (FastArrayItem)s);
return s;
@@ -427,9 +446,9 @@ deserializeFromInfo(_NSDeserializerInfo* info)
case ST_ARRAY:
case ST_MARRAY:
{
- id objects[size];
- id a;
- int i;
+ id objects[size];
+ id a;
+ unsigned i;
for (i = 0; i < size; i++)
{
@@ -440,24 +459,24 @@ deserializeFromInfo(_NSDeserializerInfo* info)
{
[objects[--i] release];
}
+ objc_free(objects);
return nil;
}
}
if (code == ST_MARRAY || info->mutable)
{
- a = [GMutableArrayClass allocWithZone: NSDefaultMallocZone()];
- a = [a initWithObjects: objects
- count: size];
+ a = NSAllocateObject(MACls, 0, NSDefaultMallocZone());
+ a = (*maInitImp)(a, maInitSel, objects, size);
}
else
{
- a = [GArrayClass allocWithZone: NSDefaultMallocZone()];
- a = [a initWithObjects: objects
- count: size];
+ a = NSAllocateObject(IACls, 0, NSDefaultMallocZone());
+ a = (*iaInitImp)(a, iaInitSel, objects, size);
}
- while (i > 0)
+
+ for (i = 0; i < size; i++)
{
- [objects[--i] release];
+ [objects[i] release];
}
return a;
}
@@ -496,21 +515,17 @@ deserializeFromInfo(_NSDeserializerInfo* info)
}
if (code == ST_MDICT || info->mutable)
{
- d=[GMutableDictionaryClass allocWithZone: NSDefaultMallocZone()];
- d = [d initWithObjects: objects
- forKeys: keys
- count: size];
+ d = NSAllocateObject(MDCls, 0, NSDefaultMallocZone());
+ d = (*mdInitImp)(d, mdInitSel, objects, keys, size);
}
else
{
- d = [GDictionaryClass allocWithZone: NSDefaultMallocZone()];
- d = [d initWithObjects: objects
- forKeys: keys
- count: size];
+ d = NSAllocateObject(IDCls, 0, NSDefaultMallocZone());
+ d = (*idInitImp)(d, idInitSel, objects, keys, size);
}
- while (i > 0)
+ for (i = 0; i < size; i++)
{
- [keys[--i] release];
+ [keys[i] release];
[objects[i] release];
}
return d;
@@ -522,10 +537,8 @@ deserializeFromInfo(_NSDeserializerInfo* info)
void *b = objc_malloc(size);
(*info->debImp)(info->data, debSel, b, size, info->cursor);
- d = [GDataClass allocWithZone: NSDefaultMallocZone()];
- d = [d initWithBytesNoCopy: b
- length: size
- fromZone: NSDefaultMallocZone()];
+ d = (NSData*)NSAllocateObject(DCls, 0, NSDefaultMallocZone());
+ d = (*dInitImp)(d, dInitSel, b, size, NSDefaultMallocZone());
return d;
}
@@ -605,11 +618,20 @@ deserializeFromInfo(_NSDeserializerInfo* info)
{
if (self == [NSDeserializer class])
{
- GArrayClass = [NSGArray class];
- GMutableArrayClass = [NSGMutableArray class];
- GDataClass = [NSDataMalloc class];
- GDictionaryClass = [NSGDictionary class];
- GMutableDictionaryClass = [NSGMutableDictionary class];
+ IACls = [NSGArray class];
+ MACls = [NSGMutableArray class];
+ DCls = [NSDataMalloc class];
+ IDCls = [NSGDictionary class];
+ MDCls = [NSGMutableDictionary class];
+ USCls = [NSGString class];
+ CSCls = [NSGCString class];
+ csInitImp = [CSCls instanceMethodForSelector: csInitSel];
+ usInitImp = [USCls instanceMethodForSelector: usInitSel];
+ dInitImp = [DCls instanceMethodForSelector: dInitSel];
+ iaInitImp = [IACls instanceMethodForSelector: iaInitSel];
+ maInitImp = [MACls instanceMethodForSelector: maInitSel];
+ idInitImp = [IDCls instanceMethodForSelector: idInitSel];
+ mdInitImp = [MDCls instanceMethodForSelector: mdInitSel];
}
}