literal string handling improvments.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@35359 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2012-08-08 09:46:08 +00:00
parent 23f70314d9
commit c767e8a8d3
2 changed files with 270 additions and 271 deletions

View file

@ -1,3 +1,9 @@
2012-08-08 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSString.m: Add upper and lower case methods for literal
strings. Change other literal string methods to check that content
is really utf8 in more places. Generally simplify/cleanup a bit.
2012-08-02 Richard Frith-Macdonald <rfm@gnu.org> 2012-08-02 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSValue.m: ([-isEqualToValue:]) add check for self equality * Source/GSValue.m: ([-isEqualToValue:]) add check for self equality

View file

@ -533,7 +533,7 @@ the instance iself.
} }
@end @end
@interface GSUnicodeInlineString : GSUnicodeString @interface GSUInlineString : GSUnicodeString
{ {
} }
@end @end
@ -612,7 +612,7 @@ static Class GSCSubStringClass = 0;
static Class GSUnicodeStringClass = 0; static Class GSUnicodeStringClass = 0;
static Class GSUnicodeBufferStringClass = 0; static Class GSUnicodeBufferStringClass = 0;
static Class GSUnicodeSubStringClass = 0; static Class GSUnicodeSubStringClass = 0;
static Class GSUnicodeInlineStringClass = 0; static Class GSUInlineStringClass = 0;
static Class GSMutableStringClass = 0; static Class GSMutableStringClass = 0;
static Class NSConstantStringClass = 0; static Class NSConstantStringClass = 0;
@ -663,7 +663,7 @@ setup(BOOL rerun)
GSCBufferStringClass = [GSCBufferString class]; GSCBufferStringClass = [GSCBufferString class];
GSUnicodeBufferStringClass = [GSUnicodeBufferString class]; GSUnicodeBufferStringClass = [GSUnicodeBufferString class];
GSCInlineStringClass = [GSCInlineString class]; GSCInlineStringClass = [GSCInlineString class];
GSUnicodeInlineStringClass = [GSUnicodeInlineString class]; GSUInlineStringClass = [GSUInlineString class];
GSCSubStringClass = [GSCSubString class]; GSCSubStringClass = [GSCSubString class];
GSUnicodeSubStringClass = [GSUnicodeSubString class]; GSUnicodeSubStringClass = [GSUnicodeSubString class];
GSMutableStringClass = [GSMutableString class]; GSMutableStringClass = [GSMutableString class];
@ -691,6 +691,36 @@ setup(BOOL rerun)
} }
} }
static GSCInlineString*
newCInline(unsigned length, NSZone *zone)
{
GSCInlineString *me;
me = (GSCInlineString*)
NSAllocateObject(GSCInlineStringClass, length, zone);
me->_contents.c = (unsigned char*)
(((void*)me)+class_getInstanceSize(GSCInlineStringClass));
me->_count = length;
me->_flags.wide = 0;
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return me;
}
static GSUInlineString*
newUInline(unsigned length, NSZone *zone)
{
GSUInlineString *me;
me = (GSUInlineString*)
NSAllocateObject(GSUInlineStringClass, length*sizeof(unichar), zone);
me->_contents.u = (unichar*)
(((void*)me)+class_getInstanceSize(GSUInlineStringClass));
me->_count = length;
me->_flags.wide = 1;
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return me;
}
/* Predeclare a few functions /* Predeclare a few functions
*/ */
static void GSStrWiden(GSStr s); static void GSStrWiden(GSStr s);
@ -1139,12 +1169,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *owned,
*/ */
if (GSPrivateIsCollectable(chars.c) == NO) if (GSPrivateIsCollectable(chars.c) == NO)
{ {
me = (GSStr)NSAllocateObject(GSCInlineStringClass, length, me = newCInline(length, [self zone]);
[self zone]);
me->_contents.c = (unsigned char*)&((GSCInlineString*)me)[1];
me->_count = length;
me->_flags.wide = 0;
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
memcpy(me->_contents.c, chars.c, length); memcpy(me->_contents.c, chars.c, length);
NSZoneFree(NSZoneFromPointer(chars.c), chars.c); NSZoneFree(NSZoneFromPointer(chars.c), chars.c);
return (id)me; return (id)me;
@ -1197,13 +1222,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *owned,
if (isASCII == YES if (isASCII == YES
|| (internalEncoding == NSISOLatin1StringEncoding && isLatin1 == YES)) || (internalEncoding == NSISOLatin1StringEncoding && isLatin1 == YES))
{ {
me = (GSStr)NSAllocateObject(GSCInlineStringClass, length, me = (GSStr)newCInline(length, [self zone]);
[self zone]);
me->_contents.c = (unsigned char*)
(((void*)me)+class_getInstanceSize(GSCInlineStringClass));
me->_count = length;
me->_flags.wide = 0;
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
while (length-- > 0) while (length-- > 0)
{ {
me->_contents.c[length] = chars.u[length]; me->_contents.c[length] = chars.u[length];
@ -1221,12 +1240,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *owned,
*/ */
if (GSPrivateIsCollectable(chars.u) == NO) if (GSPrivateIsCollectable(chars.u) == NO)
{ {
me = (GSStr)NSAllocateObject(GSUnicodeInlineStringClass, length, me = newUInline(length, [self zone]);
[self zone]);
me->_contents.u = (unichar*)&((GSUnicodeInlineString*)me)[1];
me->_count = length;
me->_flags.wide = 1;
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
memcpy(me->_contents.u, chars.u, length * sizeof(unichar)); memcpy(me->_contents.u, chars.u, length * sizeof(unichar));
NSZoneFree(NSZoneFromPointer(chars.u), chars.u); NSZoneFree(NSZoneFromPointer(chars.u), chars.u);
return (id)me; return (id)me;
@ -1239,7 +1253,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *owned,
me->_flags.wide = 1; me->_flags.wide = 1;
me->_flags.owned = flag; me->_flags.owned = flag;
} }
return (id)me; return me;
} }
- (id) initWithCharacters: (const unichar*)chars - (id) initWithCharacters: (const unichar*)chars
@ -1331,24 +1345,12 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *owned,
*/ */
if (f->_flags.wide == 1) if (f->_flags.wide == 1)
{ {
me = (GSStr)NSAllocateObject(GSUnicodeInlineStringClass, me = (GSStr)newUInline(f->_count, [self zone]);
f->_count*sizeof(unichar), [self zone]);
me->_contents.u = (unichar*)
(((void*)me)+class_getInstanceSize(GSUnicodeInlineStringClass));
me->_count = f->_count;
me->_flags.wide = 1;
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
memcpy(me->_contents.u, f->_contents.u, f->_count*sizeof(unichar)); memcpy(me->_contents.u, f->_contents.u, f->_count*sizeof(unichar));
} }
else else
{ {
me = (GSStr)NSAllocateObject(GSCInlineStringClass, f->_count, me = (GSStr)newCInline(f->_count, [self zone]);
[self zone]);
me->_contents.c = (unsigned char*)
(((void*)me)+class_getInstanceSize(GSCInlineStringClass));
me->_count = f->_count;
me->_flags.wide = 0;
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
memcpy(me->_contents.c, f->_contents.c, f->_count); memcpy(me->_contents.c, f->_contents.c, f->_count);
} }
@ -1356,7 +1358,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *owned,
* If the string had to grow beyond the initial buffer size, we must * If the string had to grow beyond the initial buffer size, we must
* release any allocated memory. * release any allocated memory.
*/ */
if (f->_flags.owned == 1) if (1 == f->_flags.owned)
{ {
NSZoneFree(f->_zone, f->_contents.c); NSZoneFree(f->_zone, f->_contents.c);
} }
@ -1388,15 +1390,9 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *owned,
{ {
/* /*
* For a GSCString subclass, or an 8-bit GSMutableString, * For a GSCString subclass, or an 8-bit GSMutableString,
* we can copy the bytes directly into a GSCString. * we can copy the bytes directly into an inline string.
*/ */
me = (GSStr)NSAllocateObject(GSCInlineStringClass, me = (GSStr)newCInline(length, [self zone]);
length, [self zone]);
me->_contents.c = (unsigned char*)
(((void*)me)+class_getInstanceSize(GSCInlineStringClass));
me->_count = length;
me->_flags.wide = 0;
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
memcpy(me->_contents.c, ((GSStr)string)->_contents.c, length); memcpy(me->_contents.c, ((GSStr)string)->_contents.c, length);
} }
else if (GSObjCIsKindOf(c, GSUnicodeStringClass) == YES else if (GSObjCIsKindOf(c, GSUnicodeStringClass) == YES
@ -1404,15 +1400,9 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *owned,
{ {
/* /*
* For a GSUnicodeString subclass, or a 16-bit GSMutableString, * For a GSUnicodeString subclass, or a 16-bit GSMutableString,
* we can copy the bytes directly into a GSUnicodeString. * we can copy the bytes directly into an inline string.
*/ */
me = (GSStr)NSAllocateObject(GSUnicodeInlineStringClass, me = (GSStr)newUInline(length, [self zone]);
length*sizeof(unichar), [self zone]);
me->_contents.u = (unichar*)
(((void*)me)+class_getInstanceSize(GSUnicodeInlineStringClass));
me->_count = length;
me->_flags.wide = 1;
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
memcpy(me->_contents.u, ((GSStr)string)->_contents.u, memcpy(me->_contents.u, ((GSStr)string)->_contents.u,
length*sizeof(unichar)); length*sizeof(unichar));
} }
@ -1422,13 +1412,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *owned,
* For a string with an unknown class, we can initialise by * For a string with an unknown class, we can initialise by
* having the string copy its content directly into our buffer. * having the string copy its content directly into our buffer.
*/ */
me = (GSStr)NSAllocateObject(GSUnicodeInlineStringClass, me = (GSStr)newUInline(length, [self zone]);
length*sizeof(unichar), [self zone]);
me->_contents.u = (unichar*)
(((void*)me)+class_getInstanceSize(GSUnicodeInlineStringClass));
me->_count = length;
me->_flags.wide = 1;
me->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
[string getCharacters: me->_contents.u]; [string getCharacters: me->_contents.u];
} }
return (id)me; return (id)me;
@ -1461,7 +1445,7 @@ fixBOM(unsigned char **bytes, NSUInteger*length, BOOL *owned,
* GSCSubString, GSCInlineString, GSCBufferString * GSCSubString, GSCInlineString, GSCBufferString
* inherit methods from GSCString. * inherit methods from GSCString.
* GSUnicodeString uses the functions with the _u suffix. * GSUnicodeString uses the functions with the _u suffix.
* GSUnicodeSubString, GSUnicodeInlineString, and GSUnicodeBufferString * GSUnicodeSubString, GSUInlineString, and GSUnicodeBufferString
* inherit methods from GSUnicodeString. * inherit methods from GSUnicodeString.
* GSMutableString uses all the functions, selecting the _c or _u versions * GSMutableString uses all the functions, selecting the _c or _u versions
* depending on whether its storage is 8-bit or 16-bit. * depending on whether its storage is 8-bit or 16-bit.
@ -3549,16 +3533,10 @@ agree, create a new GSCInlineString otherwise.
{ {
if (!_flags.owned || NSShouldRetainWithZone(self, z) == NO) if (!_flags.owned || NSShouldRetainWithZone(self, z) == NO)
{ {
GSCInlineString *o; GSCInlineString *me = newCInline(_count, z);
o = (typeof(o))NSAllocateObject(GSCInlineStringClass, _count, z); memcpy(me->_contents.c, _contents.c, _count);
o->_contents.c = (unsigned char*) return me;
(((void*)o)+class_getInstanceSize(GSCInlineStringClass));
o->_count = _count;
memcpy(o->_contents.c, _contents.c, _count);
o->_flags.wide = 0;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return (id)o;
} }
else else
{ {
@ -3695,18 +3673,13 @@ agree, create a new GSCInlineString otherwise.
GSCInlineString *o; GSCInlineString *o;
unsigned i; unsigned i;
o = (typeof(o))NSAllocateObject(GSCInlineStringClass, o = [newCInline(_count, [self zone]) autorelease];
_count, NSDefaultMallocZone()); i = _count;
o->_contents.c = (unsigned char*)
(((void*)o)+class_getInstanceSize(GSCInlineStringClass));
i = o->_count = _count;
while (i-- > 0) while (i-- > 0)
{ {
o->_contents.c[i] = tolower(_contents.c[i]); o->_contents.c[i] = tolower(_contents.c[i]);
} }
o->_flags.wide = 0; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return [(id)o autorelease];
} }
- (id) mutableCopy - (id) mutableCopy
@ -3795,18 +3768,13 @@ agree, create a new GSCInlineString otherwise.
GSCInlineString *o; GSCInlineString *o;
unsigned i; unsigned i;
o = (typeof(o))NSAllocateObject(GSCInlineStringClass, o = [newCInline(_count, [self zone]) autorelease];
_count, NSDefaultMallocZone()); i = _count;
o->_contents.c = (unsigned char*)
(((void*)o)+class_getInstanceSize(GSCInlineStringClass));
i = o->_count = _count;
while (i-- > 0) while (i-- > 0)
{ {
o->_contents.c[i] = toupper(_contents.c[i]); o->_contents.c[i] = toupper(_contents.c[i]);
} }
o->_flags.wide = 0; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return [(id)o autorelease];
} }
- (const char *) UTF8String - (const char *) UTF8String
@ -3855,13 +3823,8 @@ agree, create a new GSCInlineString otherwise.
{ {
GSCInlineString *o; GSCInlineString *o;
o = (typeof(o))NSAllocateObject(GSCInlineStringClass, _count, z); o = newCInline(_count, z);
o->_contents.c = (unsigned char*)
(((void*)o)+class_getInstanceSize(GSCInlineStringClass));
o->_count = _count;
memcpy(o->_contents.c, _contents.c, _count); memcpy(o->_contents.c, _contents.c, _count);
o->_flags.wide = 0;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return (id)o; return (id)o;
} }
@ -4038,21 +4001,16 @@ agree, create a new GSCInlineString otherwise.
- (id) lowercaseString - (id) lowercaseString
{ {
GSUnicodeInlineString *o; GSUInlineString *o;
unsigned i; unsigned i;
o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass, o = [newUInline(_count, [self zone]) autorelease];
_count * sizeof(unichar), NSDefaultMallocZone()); i = _count;
o->_contents.u = (unichar*)
(((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
i = o->_count = _count;
while (i-- > 0) while (i-- > 0)
{ {
o->_contents.u[i] = uni_tolower(_contents.u[i]); o->_contents.u[i] = uni_tolower(_contents.u[i]);
} }
o->_flags.wide = 1; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return [(id)o autorelease];
} }
- (id) mutableCopy - (id) mutableCopy
@ -4138,21 +4096,16 @@ agree, create a new GSCInlineString otherwise.
- (id) uppercaseString - (id) uppercaseString
{ {
GSUnicodeInlineString *o; GSUInlineString *o;
unsigned i; unsigned i;
o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass, o = [newUInline(_count, [self zone]) autorelease];
_count * sizeof(unichar), NSDefaultMallocZone()); i = _count;
o->_contents.u = (unichar*)
(((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
i = o->_count = _count;
while (i-- > 0) while (i-- > 0)
{ {
o->_contents.u[i] = uni_toupper(_contents.u[i]); o->_contents.u[i] = uni_toupper(_contents.u[i]);
} }
o->_flags.wide = 1; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return [(id)o autorelease];
} }
// private method for Unicode level 3 implementation // private method for Unicode level 3 implementation
@ -4169,23 +4122,17 @@ agree, create a new GSCInlineString otherwise.
/* /*
Default -copy implementation. Retain if we own the buffer and the zones Default -copy implementation. Retain if we own the buffer and the zones
agree, create a new GSUnicodeInlineString otherwise. agree, create a new GSUInlineString otherwise.
*/ */
- (id) copyWithZone: (NSZone*)z - (id) copyWithZone: (NSZone*)z
{ {
if (!_flags.owned || NSShouldRetainWithZone(self, z) == NO) if (!_flags.owned || NSShouldRetainWithZone(self, z) == NO)
{ {
GSUnicodeInlineString *o; GSUInlineString *o;
o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass, o = newUInline(_count, z);
_count * sizeof(unichar), z);
o->_contents.u = (unichar*)
(((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
o->_count = _count;
memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar)); memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
o->_flags.wide = 1; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return (id)o;
} }
else else
{ {
@ -4214,7 +4161,7 @@ agree, create a new GSUnicodeInlineString otherwise.
@implementation GSUnicodeInlineString @implementation GSUInlineString
@end @end
@ -4226,17 +4173,11 @@ agree, create a new GSUnicodeInlineString otherwise.
*/ */
- (id) copyWithZone: (NSZone*)z - (id) copyWithZone: (NSZone*)z
{ {
GSUnicodeInlineString *o; GSUInlineString *o;
o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass, o = newUInline(_count, z);
_count * sizeof(unichar), z);
o->_contents.u = (unichar*)
(((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
o->_count = _count;
memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar)); memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
o->_flags.wide = 1; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return (id)o;
} }
- (void) dealloc - (void) dealloc
@ -4355,30 +4296,19 @@ agree, create a new GSUnicodeInlineString otherwise.
{ {
if (_flags.wide == 1) if (_flags.wide == 1)
{ {
GSUnicodeInlineString *o; GSUInlineString *o;
o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass, o = newUInline(_count, z);
_count * sizeof(unichar), z);
o->_contents.u = (unichar*)
(((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
o->_count = _count;
memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar)); memcpy(o->_contents.u, _contents.u, _count * sizeof(unichar));
o->_flags.wide = 1; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return (id)o;
} }
else else
{ {
GSCInlineString *o; GSCInlineString *o;
o = (typeof(o))NSAllocateObject(GSCInlineStringClass, _count, z); o = newCInline(_count, z);
o->_contents.c = (unsigned char*)
(((void*)o)+class_getInstanceSize(GSCInlineStringClass));
o->_count = _count;
memcpy(o->_contents.c, _contents.c, _count); memcpy(o->_contents.c, _contents.c, _count);
o->_flags.wide = 0; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return (id)o;
} }
} }
@ -4854,39 +4784,29 @@ NSAssert(_flags.owned == 1 && _zone != 0, NSInternalInconsistencyException);
{ {
if (_flags.wide == 1) if (_flags.wide == 1)
{ {
GSUnicodeInlineString *o; GSUInlineString *o;
unsigned i; unsigned i;
o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass, o = newUInline(_count, [self zone]);
_count * sizeof(unichar), NSDefaultMallocZone()); i = _count;
o->_contents.u = (unichar*)
(((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
i = o->_count = _count;
while (i-- > 0) while (i-- > 0)
{ {
o->_contents.u[i] = uni_tolower(_contents.u[i]); o->_contents.u[i] = uni_tolower(_contents.u[i]);
} }
o->_flags.wide = 1; return [o autorelease];
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return [(id)o autorelease];
} }
else else
{ {
GSCInlineString *o; GSCInlineString *o;
unsigned i; unsigned i;
o = (typeof(o))NSAllocateObject(GSCInlineStringClass, o = newCInline(_count, [self zone]);
_count, NSDefaultMallocZone()); i = _count;
o->_contents.c = (unsigned char*)
(((void*)o)+class_getInstanceSize(GSCInlineStringClass));
i = o->_count = _count;
while (i-- > 0) while (i-- > 0)
{ {
o->_contents.c[i] = tolower(_contents.c[i]); o->_contents.c[i] = tolower(_contents.c[i]);
} }
o->_flags.wide = 0; return [o autorelease];
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return [(id)o autorelease];
} }
} }
@ -5175,32 +5095,20 @@ NSAssert(_flags.owned == 1 && _zone != 0, NSInternalInconsistencyException);
} }
if (_flags.wide == 1) if (_flags.wide == 1)
{ {
GSUnicodeInlineString *o; GSUInlineString *o;
o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass, o = [newUInline(aRange.length, [self zone]) autorelease];
aRange.length * sizeof(unichar), NSDefaultMallocZone());
o->_contents.u = (unichar*)
(((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
o->_count = aRange.length;
memcpy(o->_contents.u, _contents.u + aRange.location, memcpy(o->_contents.u, _contents.u + aRange.location,
aRange.length * sizeof(unichar)); aRange.length * sizeof(unichar));
o->_flags.wide = 1; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return AUTORELEASE((id)o);
} }
else else
{ {
GSCInlineString *o; GSCInlineString *o;
o = (typeof(o))NSAllocateObject(GSCInlineStringClass, o = [newCInline(aRange.length, [self zone]) autorelease];
aRange.length, NSDefaultMallocZone());
o->_contents.c = (unsigned char*)
(((void*)o)+class_getInstanceSize(GSCInlineStringClass));
o->_count = aRange.length;
memcpy(o->_contents.c, _contents.c + aRange.location, aRange.length); memcpy(o->_contents.c, _contents.c + aRange.location, aRange.length);
o->_flags.wide = 0; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return AUTORELEASE((id)o);
} }
} }
@ -5214,32 +5122,20 @@ NSAssert(_flags.owned == 1 && _zone != 0, NSInternalInconsistencyException);
} }
if (_flags.wide == 1) if (_flags.wide == 1)
{ {
GSUnicodeInlineString *o; GSUInlineString *o;
o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass, o = [newUInline(aRange.length, [self zone]) autorelease];
aRange.length * sizeof(unichar), NSDefaultMallocZone());
o->_contents.u = (unichar*)
(((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
o->_count = aRange.length;
memcpy(o->_contents.u, _contents.u + aRange.location, memcpy(o->_contents.u, _contents.u + aRange.location,
aRange.length * sizeof(unichar)); aRange.length * sizeof(unichar));
o->_flags.wide = 1; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return AUTORELEASE((id)o);
} }
else else
{ {
GSCInlineString *o; GSCInlineString *o;
o = (typeof(o))NSAllocateObject(GSCInlineStringClass, o = [newCInline(aRange.length, [self zone]) autorelease];
aRange.length, NSDefaultMallocZone());
o->_contents.c = (unsigned char*)
(((void*)o)+class_getInstanceSize(GSCInlineStringClass));
o->_count = aRange.length;
memcpy(o->_contents.c, _contents.c + aRange.location, aRange.length); memcpy(o->_contents.c, _contents.c + aRange.location, aRange.length);
o->_flags.wide = 0; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return AUTORELEASE((id)o);
} }
} }
@ -5247,39 +5143,29 @@ NSAssert(_flags.owned == 1 && _zone != 0, NSInternalInconsistencyException);
{ {
if (_flags.wide == 1) if (_flags.wide == 1)
{ {
GSUnicodeInlineString *o; GSUInlineString *o;
unsigned i; unsigned i;
o = (typeof(o))NSAllocateObject(GSUnicodeInlineStringClass, o = [newUInline(_count, [self zone]) autorelease];
_count * sizeof(unichar), NSDefaultMallocZone()); i = _count;
o->_contents.u = (unichar*)
(((void*)o)+class_getInstanceSize(GSUnicodeInlineStringClass));
i = o->_count = _count;
while (i-- > 0) while (i-- > 0)
{ {
o->_contents.u[i] = uni_toupper(_contents.u[i]); o->_contents.u[i] = uni_toupper(_contents.u[i]);
} }
o->_flags.wide = 1; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return [(id)o autorelease];
} }
else else
{ {
GSCInlineString *o; GSCInlineString *o;
unsigned i; unsigned i;
o = (typeof(o))NSAllocateObject(GSCInlineStringClass, o = [newCInline(_count, [self zone]) autorelease];
_count, NSDefaultMallocZone()); i = _count;
o->_contents.c = (unsigned char*)
(((void*)o)+class_getInstanceSize(GSCInlineStringClass));
i = o->_count = _count;
while (i-- > 0) while (i-- > 0)
{ {
o->_contents.c[i] = toupper(_contents.c[i]); o->_contents.c[i] = toupper(_contents.c[i]);
} }
o->_flags.wide = 0; return o;
o->_flags.owned = 1; // Ignored on dealloc, but means we own buffer
return [(id)o autorelease];
} }
} }
@ -5422,6 +5308,12 @@ literalIsEqual(NXConstantString *self, id anObject)
} }
- (BOOL) canBeConvertedToEncoding: (NSStringEncoding)encoding - (BOOL) canBeConvertedToEncoding: (NSStringEncoding)encoding
{
/* If the string contains bad (non-utf8) data, the lengthUTF8() function
* will raise an exception ... we catch it and return NO in that case
* since this method is not expected to raise exceptions.
*/
NS_DURING
{ {
if (NSASCIIStringEncoding == encoding) if (NSASCIIStringEncoding == encoding)
{ {
@ -5440,6 +5332,7 @@ literalIsEqual(NXConstantString *self, id anObject)
else if (NSUTF8StringEncoding == encoding else if (NSUTF8StringEncoding == encoding
|| NSUnicodeStringEncoding == encoding) || NSUnicodeStringEncoding == encoding)
{ {
lengthUTF8((const uint8_t*)nxcsptr, nxcslen, 0, 0);
return YES; return YES;
} }
else else
@ -5449,41 +5342,53 @@ literalIsEqual(NXConstantString *self, id anObject)
return d != nil ? YES : NO; return d != nil ? YES : NO;
} }
} }
NS_HANDLER
{
return NO;
}
NS_ENDHANDLER
}
- (NSData*) dataUsingEncoding: (NSStringEncoding)encoding - (NSData*) dataUsingEncoding: (NSStringEncoding)encoding
allowLossyConversion: (BOOL)flag allowLossyConversion: (BOOL)flag
{
if (0 == nxcslen)
{
return [NSDataClass data];
}
if (NSUTF8StringEncoding == encoding)
{
/* We want utf-8, so we can just return an object pointing to the
* constant string data.
*/
return [NSDataClass dataWithBytesNoCopy: (void*)nxcsptr
length: nxcslen
freeWhenDone: NO];
}
if (NSASCIIStringEncoding == encoding
|| NSISOLatin1StringEncoding == encoding)
{ {
BOOL ascii; BOOL ascii;
BOOL latin1; BOOL latin1;
unsigned length; unsigned length;
length = lengthUTF8((const uint8_t*)nxcsptr, nxcslen, &ascii, &latin1); if (0 == nxcslen)
if (YES == ascii)
{ {
/* The coonstant string data is just ascii, so we can return a return [NSDataClass data];
* pointer to it dierctly. }
/* Check what is actually in this string ... if it's corrupt an exception
* is raised.
*/
length = lengthUTF8((const uint8_t*)nxcsptr, nxcslen, &ascii, &latin1);
if (NSUTF8StringEncoding == encoding)
{
/* We want utf-8, so we can just return an object pointing to the
* constant string data since e just checked that it's UTF8 in
* lengthUTF8().
*/ */
return [NSDataClass dataWithBytesNoCopy: (void*)nxcsptr return [NSDataClass dataWithBytesNoCopy: (void*)nxcsptr
length: nxcslen length: nxcslen
freeWhenDone: NO]; freeWhenDone: NO];
} }
if (YES == latin1)
if (YES == ascii && GSPrivateIsByteEncoding(encoding))
{
/* The constant string data is just ascii, so we can return a
* pointer to it directly for any encoding which has ascii as
* a subset.
*/
return [NSDataClass dataWithBytesNoCopy: (void*)nxcsptr
length: nxcslen
freeWhenDone: NO];
}
if (YES == latin1 && NSISOLatin1StringEncoding == encoding)
{ {
unsigned i = 0; unsigned i = 0;
unichar n = 0; unichar n = 0;
@ -5500,7 +5405,7 @@ literalIsEqual(NXConstantString *self, id anObject)
length: length length: length
freeWhenDone: YES]; freeWhenDone: YES];
} }
}
return [super dataUsingEncoding: encoding allowLossyConversion: flag]; return [super dataUsingEncoding: encoding allowLossyConversion: flag];
} }
@ -5610,6 +5515,50 @@ literalIsEqual(NXConstantString *self, id anObject)
return lengthUTF8((const uint8_t*)nxcsptr, nxcslen, 0, 0); return lengthUTF8((const uint8_t*)nxcsptr, nxcslen, 0, 0);
} }
- (NSString*) lowercaseString
{
if (nxcslen > 0)
{
BOOL ascii;
BOOL latin1;
unsigned length;
unsigned i = 0;
length = lengthUTF8((const uint8_t*)nxcsptr, nxcslen, &ascii, &latin1);
if (YES == ascii)
{
GSCInlineString *result;
result = [newCInline(length, [self zone]) autorelease];
while (i < length)
{
result->_contents.c[i] = tolower(((const char*)nxcsptr)[i]);
i++;
}
return result;
}
else
{
NSUInteger l = 0;
unichar u;
unichar n = 0;
GSUInlineString *result;
result = [newUInline(length, [self zone]) autorelease];
while (l < length)
{
u = nextUTF8((const uint8_t *)nxcsptr, nxcslen, &i, &n);
result->_contents.u[l++] = uni_tolower(u);
}
return result;
}
}
else
{
return self;
}
}
- (NSRange) rangeOfCharacterFromSet: (NSCharacterSet*)aSet - (NSRange) rangeOfCharacterFromSet: (NSCharacterSet*)aSet
options: (NSUInteger)mask options: (NSUInteger)mask
range: (NSRange)aRange range: (NSRange)aRange
@ -5725,6 +5674,50 @@ literalIsEqual(NXConstantString *self, id anObject)
return NSMakeRange(NSNotFound, 0); return NSMakeRange(NSNotFound, 0);
} }
- (NSString*) uppercaseString
{
if (nxcslen > 0)
{
BOOL ascii;
BOOL latin1;
unsigned length;
unsigned i = 0;
length = lengthUTF8((const uint8_t*)nxcsptr, nxcslen, &ascii, &latin1);
if (YES == ascii)
{
GSCInlineString *result;
result = [newCInline(length, [self zone]) autorelease];
while (i < length)
{
result->_contents.c[i] = toupper(((const char*)nxcsptr)[i]);
i++;
}
return result;
}
else
{
NSUInteger l = 0;
unichar u;
unichar n = 0;
GSUInlineString *result;
result = [newUInline(length, [self zone]) autorelease];
while (l < length)
{
u = nextUTF8((const uint8_t *)nxcsptr, nxcslen, &i, &n);
result->_contents.u[l++] = uni_toupper(u);
}
return result;
}
}
else
{
return self;
}
}
- (id) retain - (id) retain
{ {
return self; return self;