More string internals tidyups

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22944 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2006-05-20 09:27:31 +00:00
parent 85b1050160
commit 192adaf6cd
3 changed files with 242 additions and 540 deletions

View file

@ -1,3 +1,15 @@
2006-05-20 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSString.m:
* Source/NSSerializer.m:
Commit more string tidyups and simplifications made while I was
travelling. Changed private internal string subclasses so that
they can't be re-initialised ... all instances are initialised
'manually' rather than through a method that could be called by
other code outside this file ... thus all initialisation by external
code goes through ([-initWithBytesNoCopy:length:encoding:shouldFree])
method of the placeholder string.
2006-05-15 Richard Frith-Macdonald <rfm@gnu.org> 2006-05-15 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSHTTPURLHandle.m: Fix error when parsing response with no * Source/GSHTTPURLHandle.m: Fix error when parsing response with no

View file

@ -125,17 +125,11 @@ we need to free the buffer when we are deallocated.
@interface GSCBufferString : GSCString @interface GSCBufferString : GSCString
{ {
} }
- (id) initWithCStringNoCopy: (char*)chars
length: (unsigned int)length
freeWhenDone: (BOOL)flag;
@end @end
@interface GSUnicodeBufferString : GSUnicodeString @interface GSUnicodeBufferString : GSUnicodeString
{ {
} }
- (id) initWithCharactersNoCopy: (unichar *)chars
length: (unsigned int)length
freeWhenDone: (BOOL)flag;
@end @end
@ -146,13 +140,11 @@ the instance iself.
@interface GSCInlineString : GSCString @interface GSCInlineString : GSCString
{ {
} }
- (id) initWithCString: (const char*)chars length: (unsigned)length;
@end @end
@interface GSUnicodeInlineString : GSUnicodeString @interface GSUnicodeInlineString : GSUnicodeString
{ {
} }
- (id) initWithCharacters: (const unichar*)chars length: (unsigned)length;
@end @end
@ -165,8 +157,6 @@ instance.
@public @public
GSCString *_parent; GSCString *_parent;
} }
- (id) initWithCString: (char *)chars length: (unsigned)length
fromParent: (GSCString *)parent;
@end @end
@interface GSUnicodeSubString : GSUnicodeString @interface GSUnicodeSubString : GSUnicodeString
@ -174,8 +164,6 @@ instance.
@public @public
GSUnicodeString *_parent; GSUnicodeString *_parent;
} }
- (id) initWithCharacters: (unichar *)chars length: (unsigned)length
fromParent: (GSUnicodeString *)parent;
@end @end
@ -2462,48 +2450,37 @@ rangeOfString_u(GSStr self, NSString *aString, unsigned mask, NSRange aRange)
static inline NSString* static inline NSString*
substring_c(GSStr self, NSRange aRange) substring_c(GSStr self, NSRange aRange)
{ {
id sub; struct {
@defs(GSCSubString)
} *o;
if (self->_flags.free == 1) o = (typeof(o))NSAllocateObject(GSCSubStringClass,
{ 0, NSDefaultMallocZone());
sub = NSAllocateObject(GSCSubStringClass, 0, NSDefaultMallocZone()); o->_contents.c = self->_contents.c + aRange.location;
sub = [sub initWithCString: (char*)self->_contents.c + aRange.location o->_count = aRange.length;
length: aRange.length o->_flags.wide = 0;
fromParent: (GSCString *)self]; o->_flags.free = 0;
} ASSIGN(o->_parent, self);
else AUTORELEASE((id)o);
{ return (id)o;
sub = NSAllocateObject(GSCInlineStringClass,
aRange.length, NSDefaultMallocZone());
sub = [sub initWithCString: (char*)self->_contents.c + aRange.location
length: aRange.length];
}
AUTORELEASE(sub);
return sub;
} }
static inline NSString* static inline NSString*
substring_u(GSStr self, NSRange aRange) substring_u(GSStr self, NSRange aRange)
{ {
id sub; struct {
@defs(GSUnicodeSubString)
} *o;
if (self->_flags.free == 1) o = (typeof(o))NSAllocateObject(GSUnicodeSubStringClass,
{ 0, NSDefaultMallocZone());
sub = NSAllocateObject(GSUnicodeSubStringClass, 0, NSDefaultMallocZone()); o->_contents.u = self->_contents.u + aRange.location;
sub = [sub initWithCharacters: self->_contents.u + aRange.location o->_count = aRange.length;
length: aRange.length o->_flags.wide = 1;
fromParent: (GSUnicodeString *)self]; o->_flags.free = 0;
} ASSIGN(o->_parent, self);
else AUTORELEASE((id)o);
{ return (id)o;
sub = NSAllocateObject(GSUnicodeInlineStringClass,
aRange.length*sizeof(unichar),
NSDefaultMallocZone());
sub = [sub initWithCharacters: self->_contents.u + aRange.location
length: aRange.length];
}
AUTORELEASE(sub);
return sub;
} }
/* /*
@ -2934,11 +2911,17 @@ agree, create a new GSCInlineString otherwise.
{ {
if (!_flags.free || NSShouldRetainWithZone(self, z) == NO) if (!_flags.free || NSShouldRetainWithZone(self, z) == NO)
{ {
NSString *obj; struct {
@defs(GSCInlineString)
} *o;
obj = (NSString*)NSAllocateObject(GSCInlineStringClass, _count, z); o = (typeof(o))NSAllocateObject(GSCInlineStringClass, _count, z);
obj = [obj initWithCString: (char*)_contents.c length: _count]; o->_contents.c = (unsigned char*)&o[1];
return obj; o->_count = _count;
memcpy(o->_contents.c, _contents.c, _count);
o->_flags.wide = 0;
o->_flags.free = 0;
return (id)o;
} }
else else
{ {
@ -2951,25 +2934,6 @@ agree, create a new GSCInlineString otherwise.
@implementation GSCBufferString @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 = (unsigned char*)chars;
_flags.wide = 0;
if (flag == YES)
{
_flags.free = 1;
}
return self;
}
- (void) dealloc - (void) dealloc
{ {
if (_flags.free && _contents.c != 0) if (_flags.free && _contents.c != 0)
@ -2984,22 +2948,6 @@ agree, create a new GSCInlineString otherwise.
@implementation GSCInlineString @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 - (void) dealloc
{ {
NSDeallocateObject(self); NSDeallocateObject(self);
@ -3009,32 +2957,23 @@ agree, create a new GSCInlineString otherwise.
@implementation GSCSubString @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. * Assume that a copy should be a new string, never just a retained substring.
*/ */
- (id) copyWithZone: (NSZone*)z - (id) copyWithZone: (NSZone*)z
{ {
NSString *obj; struct {
@defs(GSCInlineString)
} *o;
obj = (NSString*)NSAllocateObject(GSCInlineStringClass, _count, z); o = (typeof(o))NSAllocateObject(GSCInlineStringClass, _count, z);
obj = [obj initWithCString: (char*)_contents.c length: _count]; o->_contents.c = (unsigned char*)&o[1];
return obj; o->_count = _count;
memcpy(o->_contents.c, _contents.c, _count);
o->_flags.wide = 0;
o->_flags.free = 0;
return (id)o;
} }
- (void) dealloc - (void) dealloc
@ -3208,7 +3147,9 @@ agree, create a new GSCInlineString otherwise.
obj = (GSMutableString*)NSAllocateObject(GSMutableStringClass, 0, obj = (GSMutableString*)NSAllocateObject(GSMutableStringClass, 0,
NSDefaultMallocZone()); NSDefaultMallocZone());
obj = [obj initWithCharacters: _contents.u length: _count]; obj = [obj initWithBytes: (const void*)_contents.u
length: _count * sizeof(unichar)
encoding: NSUnicodeStringEncoding];
return obj; return obj;
} }
@ -3217,7 +3158,9 @@ agree, create a new GSCInlineString otherwise.
GSMutableString *obj; GSMutableString *obj;
obj = (GSMutableString*)NSAllocateObject(GSMutableStringClass, 0, z); obj = (GSMutableString*)NSAllocateObject(GSMutableStringClass, 0, z);
obj = [obj initWithCharacters: _contents.u length: _count]; obj = [obj initWithBytes: (const void*)_contents.u
length: _count * sizeof(unichar)
encoding: NSUnicodeStringEncoding];
return obj; return obj;
} }
@ -3278,12 +3221,18 @@ agree, create a new GSUnicodeInlineString otherwise.
{ {
if (!_flags.free || NSShouldRetainWithZone(self, z) == NO) if (!_flags.free || NSShouldRetainWithZone(self, z) == NO)
{ {
NSString *obj; struct {
@defs(GSUnicodeInlineString)
} *o;
obj = (NSString*)NSAllocateObject(GSUnicodeInlineStringClass, o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass,
_count*sizeof(unichar), z); _count * sizeof(unichar), z);
obj = [obj initWithCharacters: _contents.u length: _count]; o->_contents.u = (unichar*)&o[1];
return obj; o->_count = _count;
memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
o->_flags.wide = 1;
o->_flags.free = 0;
return (id)o;
} }
else else
{ {
@ -3296,62 +3245,6 @@ agree, create a new GSUnicodeInlineString otherwise.
@implementation GSUnicodeBufferString @implementation GSUnicodeBufferString
- (id) initWithCharactersNoCopy: (unichar *)chars
length: (unsigned int)length
freeWhenDone: (BOOL)flag
{
BOOL isASCII;
BOOL isLatin1;
if (GSUnicode(chars, length, &isASCII, &isLatin1) != length)
{
RELEASE(self);
if (flag == YES && chars != 0)
{
NSZoneFree(NSZoneFromPointer(chars), chars);
}
return nil; // Invalid data
}
if (isASCII == YES
|| (internalEncoding == NSISOLatin1StringEncoding && isLatin1 == YES))
{
GSStr me;
/*
* OK ... we can do a more compact version
*/
me = (GSStr)NSAllocateObject(GSCInlineStringClass, length,
GSObjCZone(self));
me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
me->_count = length;
me->_flags.wide = 0;
me->_flags.free = 1;
while (length-- > 0)
{
me->_contents.c[length] = (unsigned char)chars[length];
}
RELEASE(self);
if (flag == YES && chars != 0)
{
NSZoneFree(NSZoneFromPointer(chars), chars);
}
return (id)me;
}
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 - (void) dealloc
{ {
if (_flags.free && _contents.u != 0) if (_flags.free && _contents.u != 0)
@ -3366,51 +3259,6 @@ agree, create a new GSUnicodeInlineString otherwise.
@implementation GSUnicodeInlineString @implementation GSUnicodeInlineString
- (id) initWithCharacters: (const unichar*)chars length: (unsigned)length
{
BOOL isASCII;
BOOL isLatin1;
if (GSUnicode(chars, length, &isASCII, &isLatin1) != length)
{
RELEASE(self);
return nil; // Invalid data
}
if (isASCII == YES
|| (internalEncoding == NSISOLatin1StringEncoding && isLatin1 == YES))
{
GSStr me;
/*
* OK ... we can do a more compact version
*/
me = (GSStr)NSAllocateObject(GSCInlineStringClass, length,
GSObjCZone(self));
me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
me->_count = length;
me->_flags.wide = 0;
me->_flags.free = 1;
while (length-- > 0)
{
me->_contents.c[length] = (unsigned char)chars[length];
}
RELEASE(self);
return (id)me;
}
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 - (void) dealloc
{ {
NSDeallocateObject(self); NSDeallocateObject(self);
@ -3420,33 +3268,24 @@ agree, create a new GSUnicodeInlineString otherwise.
@implementation GSUnicodeSubString @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. * Assume that a copy should be a new string, never just a retained substring.
*/ */
- (id) copyWithZone: (NSZone*)z - (id) copyWithZone: (NSZone*)z
{ {
NSString *obj; struct {
@defs(GSUnicodeInlineString)
} *o;
obj = (NSString*)NSAllocateObject(GSUnicodeInlineStringClass, o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass,
_count*sizeof(unichar), z); _count * sizeof(unichar), z);
obj = [obj initWithCharacters: _contents.u length: _count]; o->_contents.u = (unichar*)&o[1];
return obj; o->_count = _count;
memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
o->_flags.wide = 1;
o->_flags.free = 0;
return (id)o;
} }
- (void) dealloc - (void) dealloc
@ -3552,29 +3391,35 @@ agree, create a new GSUnicodeInlineString otherwise.
- (id) copyWithZone: (NSZone*)z - (id) copyWithZone: (NSZone*)z
{ {
GSMutableString *copy;
if (_flags.wide == 1) if (_flags.wide == 1)
{ {
copy = (GSMutableString*)NSAllocateObject(GSUnicodeInlineStringClass, struct {
_count*sizeof(unichar), z); @defs(GSUnicodeInlineString)
copy->_contents.u = (unichar*)&((GSUnicodeInlineString*)copy)[1]; } *o;
copy->_count = _count;
copy->_flags.wide = 1; o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass,
copy->_flags.free = 0; _count * sizeof(unichar), z);
memcpy(copy->_contents.u, _contents.u, _count * sizeof(unichar)); o->_contents.u = (unichar*)&o[1];
o->_count = _count;
memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
o->_flags.wide = 1;
o->_flags.free = 0;
return (id)o;
} }
else else
{ {
copy = (GSMutableString*)NSAllocateObject(GSCInlineStringClass, struct {
_count, z); @defs(GSCInlineString)
copy->_contents.c = (unsigned char*)&((GSCInlineString*)copy)[1]; } *o;
copy->_count = _count;
copy->_flags.wide = 0; o = (typeof(o))NSAllocateObject(GSCInlineStringClass, _count, z);
copy->_flags.free = 0; o->_contents.c = (unsigned char*)&o[1];
memcpy(copy->_contents.c, _contents.c, _count); o->_count = _count;
memcpy(o->_contents.c, _contents.c, _count);
o->_flags.wide = 0;
o->_flags.free = 0;
return (id)o;
} }
return copy;
} }
- (const char *) cString - (const char *) cString
@ -4046,9 +3891,11 @@ agree, create a new GSUnicodeInlineString otherwise.
NSDefaultMallocZone()); NSDefaultMallocZone());
if (_flags.wide == 1) if (_flags.wide == 1)
obj = [obj initWithCharacters: _contents.u length: _count]; obj = [obj initWithBytes: (void*)_contents.u
length: _count * sizeof(unichar)
encoding: NSUnicodeStringEncoding];
else else
obj = [obj initWithBytes: (char*)_contents.c obj = [obj initWithBytes: (void*)_contents.c
length: _count length: _count
encoding: internalEncoding]; encoding: internalEncoding];
return obj; return obj;
@ -4061,7 +3908,9 @@ agree, create a new GSUnicodeInlineString otherwise.
obj = (GSMutableString*)NSAllocateObject(GSMutableStringClass, 0, z); obj = (GSMutableString*)NSAllocateObject(GSMutableStringClass, 0, z);
if (_flags.wide == 1) if (_flags.wide == 1)
obj = [obj initWithCharacters: _contents.u length: _count]; obj = [obj initWithBytes: (void*)_contents.u
length: _count * sizeof(unichar)
encoding: NSUnicodeStringEncoding];
else else
obj = [obj initWithBytes: (char*)_contents.c obj = [obj initWithBytes: (char*)_contents.c
length: _count length: _count
@ -4279,52 +4128,76 @@ agree, create a new GSUnicodeInlineString otherwise.
- (NSString*) substringFromRange: (NSRange)aRange - (NSString*) substringFromRange: (NSRange)aRange
{ {
NSString *sub;
GS_RANGE_CHECK(aRange, _count); GS_RANGE_CHECK(aRange, _count);
if (_flags.wide == 1) if (_flags.wide == 1)
{ {
sub = (NSString*)NSAllocateObject(GSUnicodeInlineStringClass, struct {
_count*sizeof(unichar), NSDefaultMallocZone()); @defs(GSUnicodeInlineString)
sub = [sub initWithCharacters: self->_contents.u + aRange.location } *o;
length: aRange.length];
o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass,
aRange.length * sizeof(unichar), NSDefaultMallocZone());
o->_contents.u = (unichar*)&o[1];
o->_count = aRange.length;
memcpy(o->_contents.u, _contents.u + aRange.location,
aRange.length * sizeof(unichar));
o->_flags.wide = 1;
o->_flags.free = 0;
return AUTORELEASE((id)o);
} }
else else
{ {
sub = (NSString*)NSAllocateObject(GSCInlineStringClass, struct {
_count, NSDefaultMallocZone()); @defs(GSCInlineString)
sub = [sub initWithCString: (char*)self->_contents.c + aRange.location } *o;
length: aRange.length];
o = (typeof(o))NSAllocateObject(GSCInlineStringClass,
aRange.length, NSDefaultMallocZone());
o->_contents.c = (unsigned char*)&o[1];
o->_count = aRange.length;
memcpy(o->_contents.c, _contents.c + aRange.location, aRange.length);
o->_flags.wide = 0;
o->_flags.free = 0;
return AUTORELEASE((id)o);
} }
AUTORELEASE(sub);
return sub;
} }
- (NSString*) substringWithRange: (NSRange)aRange - (NSString*) substringWithRange: (NSRange)aRange
{ {
NSString *sub;
GS_RANGE_CHECK(aRange, _count); GS_RANGE_CHECK(aRange, _count);
if (_flags.wide == 1) if (_flags.wide == 1)
{ {
sub = (NSString*)NSAllocateObject(GSUnicodeInlineStringClass, struct {
(aRange.length)*sizeof(unichar), @defs(GSUnicodeInlineString)
NSDefaultMallocZone()); } *o;
sub = [sub initWithCharacters: self->_contents.u + aRange.location
length: aRange.length]; o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass,
aRange.length * sizeof(unichar), NSDefaultMallocZone());
o->_contents.u = (unichar*)&o[1];
o->_count = aRange.length;
memcpy(o->_contents.u, _contents.u + aRange.location,
aRange.length * sizeof(unichar));
o->_flags.wide = 1;
o->_flags.free = 0;
return AUTORELEASE((id)o);
} }
else else
{ {
sub = (NSString*)NSAllocateObject(GSCInlineStringClass, struct {
aRange.length, @defs(GSCInlineString)
NSDefaultMallocZone()); } *o;
sub = [sub initWithCString: (char*)self->_contents.c + aRange.location
length: aRange.length]; o = (typeof(o))NSAllocateObject(GSCInlineStringClass,
aRange.length, NSDefaultMallocZone());
o->_contents.c = (unsigned char*)&o[1];
o->_count = aRange.length;
memcpy(o->_contents.c, _contents.c + aRange.location, aRange.length);
o->_flags.wide = 0;
o->_flags.free = 0;
return AUTORELEASE((id)o);
} }
AUTORELEASE(sub);
return sub;
} }
// private method for Unicode level 3 implementation // private method for Unicode level 3 implementation
@ -4973,134 +4846,6 @@ agree, create a new GSUnicodeInlineString otherwise.
@end @end
/*
* Some classes for backward compatibility with archives.
*/
@interface NSGCString : NSString
@end
@implementation NSGCString
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
NSLog(@"Warning - decoding archive containing obsolete %@ object - please delete/replace this archive", NSStringFromClass([self class]));
RELEASE(self);
self = (id)NSAllocateObject(GSCBufferStringClass, 0, NSDefaultMallocZone());
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &count];
if (count > 0)
{
unsigned char *chars;
chars = NSZoneMalloc(NSDefaultMallocZone(), count+1);
[aCoder decodeArrayOfObjCType: @encode(unsigned char)
count: count
at: chars];
self = [self initWithCStringNoCopy: (char*)chars
length: count
freeWhenDone: YES];
}
else
{
self = [self initWithCStringNoCopy: (char*)0 length: 0 freeWhenDone: NO];
}
return self;
}
@end
@interface NSGMutableCString : NSMutableString
@end
@implementation NSGMutableCString
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
NSLog(@"Warning - decoding archive containing obsolete %@ object - please delete/replace this archive", NSStringFromClass([self class]));
RELEASE(self);
self = (id)NSAllocateObject(GSMutableStringClass, 0, NSDefaultMallocZone());
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &count];
if (count > 0)
{
unsigned char *chars;
chars = NSZoneMalloc(NSDefaultMallocZone(), count+1);
[aCoder decodeArrayOfObjCType: @encode(unsigned char)
count: count
at: chars];
self = [self initWithCStringNoCopy: (char*)chars
length: count
freeWhenDone: YES];
}
else
{
self = [self initWithCStringNoCopy: (char*)0 length: 0 freeWhenDone: NO];
}
return self;
}
@end
@interface NSGString : NSString
@end
@implementation NSGString
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
NSLog(@"Warning - decoding archive containing obsolete %@ object - please delete/replace this archive", NSStringFromClass([self class]));
RELEASE(self);
self = (id)NSAllocateObject(GSUnicodeBufferStringClass, 0, NSDefaultMallocZone());
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &count];
if (count > 0)
{
unichar *chars;
chars = NSZoneMalloc(NSDefaultMallocZone(), count*sizeof(unichar));
[aCoder decodeArrayOfObjCType: @encode(unichar)
count: count
at: chars];
self = [self initWithCharactersNoCopy: chars
length: count
freeWhenDone: YES];
}
else
{
self = [self initWithCharactersNoCopy: 0 length: 0 freeWhenDone: NO];
}
return self;
}
@end
@interface NSGMutableString : NSMutableString
@end
@implementation NSGMutableString
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
NSLog(@"Warning - decoding archive containing obsolete %@ object - please delete/replace this archive", NSStringFromClass([self class]));
RELEASE(self);
self = (id)NSAllocateObject(GSMutableStringClass, 0, NSDefaultMallocZone());
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &count];
if (count > 0)
{
unichar *chars;
chars = NSZoneMalloc(NSDefaultMallocZone(), count*sizeof(unichar));
[aCoder decodeArrayOfObjCType: @encode(unichar)
count: count
at: chars];
self = [self initWithCharactersNoCopy: chars
length: count
freeWhenDone: YES];
}
else
{
self = [self initWithCharactersNoCopy: 0 length: 0 freeWhenDone: NO];
}
return self;
}
@end
/** /**
* Append characters to a string. * Append characters to a string.
*/ */

View file

@ -18,7 +18,8 @@
You should have received a copy of the GNU Library General Public You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
<title>NSSerializer class reference</title> <title>NSSerializer class reference</title>
$Date$ $Revision$ $Date$ $Revision$
@ -48,21 +49,9 @@
@class NSDataMalloc; @class NSDataMalloc;
@interface NSDataMalloc : NSObject // Help the compiler @interface NSDataMalloc : NSObject // Help the compiler
@end @end
@class GSInlineArray;
@class GSMutableArray; @class GSMutableArray;
@interface GSMutableArray : NSObject // Help the compiler @interface GSMutableArray : NSObject // Help the compiler
@end @end
@class GSCString;
@interface GSCString : NSObject // Help the compiler
@end
@class GSCBufferString;
@interface GSCBufferString : NSObject // Help the compiler
@end
@class GSUnicodeString;
@class GSUnicodeBufferString;
@interface GSUnicodeBufferString : NSObject // Help the compiler
@end
@class GSMutableString;
/* /*
* Setup for inline operation of string map tables. * Setup for inline operation of string map tables.
@ -123,15 +112,9 @@ static Class DataClass = 0;
static Class DateClass = 0; static Class DateClass = 0;
static Class DictionaryClass = 0; static Class DictionaryClass = 0;
static Class MutableDictionaryClass = 0; static Class MutableDictionaryClass = 0;
static Class CStringClass = 0;
static Class MStringClass = 0;
static Class StringClass = 0; static Class StringClass = 0;
static Class NumberClass = 0; static Class NumberClass = 0;
typedef struct {
@defs(GSString)
} *ivars;
typedef struct { typedef struct {
NSMutableData *data; NSMutableData *data;
void (*appImp)(NSData*,SEL,const void*,unsigned); void (*appImp)(NSData*,SEL,const void*,unsigned);
@ -196,86 +179,87 @@ serializeToInfo(id object, _NSSerializerInfo* info)
} }
c = GSObjCClass(object); c = GSObjCClass(object);
if ((GSObjCIsKindOf(c, CStringClass) if (GSObjCIsKindOf(c, StringClass))
|| (c == MStringClass && ((ivars)object)->_flags.wide == 0)) {
/* /*
We can only save it as a c-string if it only contains ASCII characters. We can only save it as a c-string if it only contains ASCII characters.
Other characters might be decoded incorrectly when deserialized since Other characters might be decoded incorrectly when deserialized since
the c-string encoding might be different then. the c-string encoding might be different then.
*/ */
&& [object canBeConvertedToEncoding: NSASCIIStringEncoding]) if ([object canBeConvertedToEncoding: NSASCIIStringEncoding])
{
GSIMapNode node;
if (info->shouldUnique)
node = GSIMapNodeForKey(&info->map, (GSIMapKey)object);
else
node = 0;
if (node == 0)
{ {
unsigned slen; GSIMapNode node;
unsigned dlen;
slen = [object length] + 1;
(*info->appImp)(info->data, appSel, &st_cstring, 1);
(*info->serImp)(info->data, serSel, slen);
dlen = (*info->lenImp)(info->data, lenSel);
(*info->setImp)(info->data, setSel, dlen + slen);
[object getCString: (*info->datImp)(info->data, datSel) + dlen
maxLength: slen
encoding: NSASCIIStringEncoding];
if (info->shouldUnique) if (info->shouldUnique)
GSIMapAddPair(&info->map, node = GSIMapNodeForKey(&info->map, (GSIMapKey)object);
(GSIMapKey)object, (GSIMapVal)info->count++); else
} node = 0;
else if (node == 0)
{
(*info->appImp)(info->data, appSel, &st_xref, 1);
(*info->serImp)(info->data, serSel, node->value.uint);
}
}
else if (GSObjCIsKindOf(c, StringClass))
{
GSIMapNode node;
if (info->shouldUnique)
node = GSIMapNodeForKey(&info->map, (GSIMapKey)object);
else
node = 0;
if (node == 0)
{
unsigned slen;
unsigned dlen;
slen = [object length];
(*info->appImp)(info->data, appSel, &st_string, 1);
(*info->serImp)(info->data, serSel, slen);
dlen = (*info->lenImp)(info->data, lenSel);
(*info->setImp)(info->data, setSel, dlen + slen*sizeof(unichar));
#if NEED_WORD_ALIGNMENT
/*
* When packing data, an item may not be aligned on a
* word boundary, so we work with an aligned buffer
* and use memcmpy()
*/
if ((dlen % __alignof__(uint32_t)) != 0)
{ {
unichar buffer[slen]; unsigned slen;
[object getCharacters: buffer]; unsigned dlen;
memcpy((*info->datImp)(info->data, datSel) + dlen, buffer,
slen*sizeof(unichar)); slen = [object length] + 1;
(*info->appImp)(info->data, appSel, &st_cstring, 1);
(*info->serImp)(info->data, serSel, slen);
dlen = (*info->lenImp)(info->data, lenSel);
(*info->setImp)(info->data, setSel, dlen + slen);
[object getCString: (*info->datImp)(info->data, datSel) + dlen
maxLength: slen
encoding: NSASCIIStringEncoding];
if (info->shouldUnique)
GSIMapAddPair(&info->map,
(GSIMapKey)object, (GSIMapVal)info->count++);
} }
else else
#endif {
[object getCharacters: (*info->datImp)(info->data, datSel) + dlen]; (*info->appImp)(info->data, appSel, &st_xref, 1);
if (info->shouldUnique) (*info->serImp)(info->data, serSel, node->value.uint);
GSIMapAddPair(&info->map, }
(GSIMapKey)object, (GSIMapVal)info->count++);
} }
else else
{ {
(*info->appImp)(info->data, appSel, &st_xref, 1); GSIMapNode node;
(*info->serImp)(info->data, serSel, node->value.uint);
if (info->shouldUnique)
node = GSIMapNodeForKey(&info->map, (GSIMapKey)object);
else
node = 0;
if (node == 0)
{
unsigned slen;
unsigned dlen;
slen = [object length];
(*info->appImp)(info->data, appSel, &st_string, 1);
(*info->serImp)(info->data, serSel, slen);
dlen = (*info->lenImp)(info->data, lenSel);
(*info->setImp)(info->data, setSel, dlen + slen*sizeof(unichar));
#if NEED_WORD_ALIGNMENT
/*
* When packing data, an item may not be aligned on a
* word boundary, so we work with an aligned buffer
* and use memcmpy()
*/
if ((dlen % __alignof__(uint32_t)) != 0)
{
unichar buffer[slen];
[object getCharacters: buffer];
memcpy((*info->datImp)(info->data, datSel) + dlen, buffer,
slen*sizeof(unichar));
}
else
#endif
[object getCharacters: (*info->datImp)(info->data, datSel)+dlen];
if (info->shouldUnique)
GSIMapAddPair(&info->map,
(GSIMapKey)object, (GSIMapVal)info->count++);
}
else
{
(*info->appImp)(info->data, appSel, &st_xref, 1);
(*info->serImp)(info->data, serSel, node->value.uint);
}
} }
} }
else if (GSObjCIsKindOf(c, ArrayClass)) else if (GSObjCIsKindOf(c, ArrayClass))
@ -381,8 +365,6 @@ static BOOL shouldBeCompact = NO;
DictionaryClass = [NSDictionary class]; DictionaryClass = [NSDictionary class];
MutableDictionaryClass = [NSMutableDictionary class]; MutableDictionaryClass = [NSMutableDictionary class];
StringClass = [NSString class]; StringClass = [NSString class];
CStringClass = [GSCString class];
MStringClass = [GSMutableString class];
} }
} }
@ -452,8 +434,6 @@ static BOOL uniquing = NO; /* Make incoming strings unique */
static Class MACls = 0; /* Mutable Array */ static Class MACls = 0; /* Mutable Array */
static Class DCls = 0; /* Data */ static Class DCls = 0; /* Data */
static Class MDCls = 0; /* Mutable Dictionary */ static Class MDCls = 0; /* Mutable Dictionary */
static Class USCls = 0; /* Unicode String */
static Class CSCls = 0; /* C String */
typedef struct { typedef struct {
NSData *data; NSData *data;
@ -467,15 +447,11 @@ typedef struct {
static SEL debSel; static SEL debSel;
static SEL deiSel; static SEL deiSel;
static SEL csInitSel;
static SEL usInitSel;
static SEL dInitSel; static SEL dInitSel;
static SEL maInitSel; static SEL maInitSel;
static SEL mdInitSel; static SEL mdInitSel;
static SEL maAddSel; static SEL maAddSel;
static SEL mdSetSel; static SEL mdSetSel;
static IMP csInitImp;
static IMP usInitImp;
static IMP dInitImp; static IMP dInitImp;
static IMP maInitImp; static IMP maInitImp;
static IMP mdInitImp; static IMP mdInitImp;
@ -564,15 +540,16 @@ deserializeFromInfo(_NSDeserializerInfo* info)
case ST_CSTRING: case ST_CSTRING:
{ {
GSCString *s; NSString *s;
char *b; char *b;
size = (*info->deiImp)(info->data, deiSel, info->cursor); size = (*info->deiImp)(info->data, deiSel, info->cursor);
b = NSZoneMalloc(NSDefaultMallocZone(), size); b = NSZoneMalloc(NSDefaultMallocZone(), size);
(*info->debImp)(info->data, debSel, b, size, info->cursor); (*info->debImp)(info->data, debSel, b, size, info->cursor);
s = (GSCString*)NSAllocateObject(CSCls, 0, NSDefaultMallocZone()); s = [[StringClass alloc] initWithBytesNoCopy: b
s = (*csInitImp)(s, csInitSel, b, size-1, YES); length: size
encoding: NSASCIIStringEncoding
freeWhenDone: YES];
/* /*
* If we are supposed to be doing uniquing of strings, handle it. * If we are supposed to be doing uniquing of strings, handle it.
*/ */
@ -596,41 +573,15 @@ deserializeFromInfo(_NSDeserializerInfo* info)
{ {
NSString *s; NSString *s;
unichar *b; unichar *b;
unsigned i;
size = (*info->deiImp)(info->data, deiSel, info->cursor); size = (*info->deiImp)(info->data, deiSel, info->cursor);
b = NSZoneMalloc(NSDefaultMallocZone(), size*sizeof(unichar)); b = NSZoneMalloc(NSDefaultMallocZone(), size*sizeof(unichar));
(*info->debImp)(info->data, debSel, b, size*sizeof(unichar), (*info->debImp)(info->data, debSel, b, size*sizeof(unichar),
info->cursor); info->cursor);
s = [[StringClass alloc] initWithBytesNoCopy: b
/* length: size*sizeof(unichar)
* Check to see if this really IS unicode ... if not, use a cString encoding: NSUnicodeStringEncoding
*/ freeWhenDone: YES];
for (i = 0; i < size; i++)
{
if (b[i] > 127)
{
break;
}
}
if (i == size)
{
char *p = (char*)b;
for (i = 0; i < size; i++)
{
p[i] = (char)b[i];
}
p = NSZoneRealloc(NSDefaultMallocZone(), b, size);
s = (NSString*)NSAllocateObject(CSCls, 0, NSDefaultMallocZone());
s = (*csInitImp)(s, csInitSel, p, size, YES);
}
else
{
s = (NSString*)NSAllocateObject(USCls, 0, NSDefaultMallocZone());
s = (*usInitImp)(s, usInitSel, b, size, YES);
}
/* /*
* If we are supposed to be doing uniquing of strings, handle it. * If we are supposed to be doing uniquing of strings, handle it.
*/ */
@ -857,8 +808,6 @@ deserializeFromInfo(_NSDeserializerInfo* info)
{ {
debSel = @selector(deserializeBytes:length:atCursor:); debSel = @selector(deserializeBytes:length:atCursor:);
deiSel = @selector(deserializeIntAtCursor:); deiSel = @selector(deserializeIntAtCursor:);
csInitSel = @selector(initWithCStringNoCopy:length:freeWhenDone:);
usInitSel = @selector(initWithCharactersNoCopy:length:freeWhenDone:);
dInitSel = @selector(initWithBytesNoCopy:length:); dInitSel = @selector(initWithBytesNoCopy:length:);
maInitSel = @selector(initWithCapacity:); maInitSel = @selector(initWithCapacity:);
mdInitSel = @selector(initWithCapacity:); mdInitSel = @selector(initWithCapacity:);
@ -867,10 +816,6 @@ deserializeFromInfo(_NSDeserializerInfo* info)
MACls = [GSMutableArray class]; MACls = [GSMutableArray class];
DCls = [NSDataMalloc class]; DCls = [NSDataMalloc class];
MDCls = [GSMutableDictionary class]; MDCls = [GSMutableDictionary class];
USCls = [GSUnicodeBufferString class];
CSCls = [GSCBufferString class];
csInitImp = [CSCls instanceMethodForSelector: csInitSel];
usInitImp = [USCls instanceMethodForSelector: usInitSel];
dInitImp = [DCls instanceMethodForSelector: dInitSel]; dInitImp = [DCls instanceMethodForSelector: dInitSel];
maInitImp = [MACls instanceMethodForSelector: maInitSel]; maInitImp = [MACls instanceMethodForSelector: maInitSel];
mdInitImp = [MDCls instanceMethodForSelector: mdInitSel]; mdInitImp = [MDCls instanceMethodForSelector: mdInitSel];