More string fixes

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@7886 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 2000-10-23 06:18:03 +00:00
parent bfa3711ce8
commit 72e48ac96c
4 changed files with 78 additions and 114 deletions

View file

@ -1,3 +1,15 @@
2000-10-23 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSString.m: ([-fastestEncoding]), ([-smallestEncoding])
implemented to return NSUnicodeStringEncoding. Use new string
classes more effectively - let GSString turn itsself into either
GSCString or GSUstring when initialised.
* Source/GSString.m: ([-dataUsingEncoding:allowLossyConversion:])
bugfixes for cString reported by Freed Kiefer
Removed 'ascii' flag - more trouble than a minor optimisation is
worth.
Fixed transmute() to be careful about freeing old string.
2000-10-21 Richard Frith-Macdonald <rfm@gnu.org> 2000-10-21 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/Foundation/NSNull.h: New placeholder class. * Headers/Foundation/NSNull.h: New placeholder class.

View file

@ -343,9 +343,8 @@ enum {
unsigned int _count; unsigned int _count;
struct { struct {
unsigned int wide: 1; // 16-bit characters in string? unsigned int wide: 1; // 16-bit characters in string?
unsigned int ascii: 1; // String contains only ascii?
unsigned int free: 1; // Should free memory? unsigned int free: 1; // Should free memory?
unsigned int unused: 1; unsigned int unused: 2;
unsigned int hash: 28; unsigned int hash: 28;
} _flags; } _flags;
} }

View file

@ -100,9 +100,8 @@
unsigned int _count; unsigned int _count;
struct { struct {
unsigned int wide: 1; unsigned int wide: 1;
unsigned int ascii: 1;
unsigned int free: 1; unsigned int free: 1;
unsigned int unused: 1; unsigned int unused: 2;
unsigned int hash: 28; unsigned int hash: 28;
} _flags; } _flags;
NSZone *_zone; NSZone *_zone;
@ -286,16 +285,10 @@ canBeConvertedToEncoding_c(ivars self, NSStringEncoding enc)
{ {
if (enc == defEnc) if (enc == defEnc)
return YES; return YES;
else if (self->_flags.ascii == 1)
return YES;
else else
{ {
BOOL result = (*convertImp)((id)self, convertSel, enc); BOOL result = (*convertImp)((id)self, convertSel, enc);
if (enc == NSASCIIStringEncoding)
{
self->_flags.ascii = 1;
}
return result; return result;
} }
} }
@ -303,18 +296,9 @@ canBeConvertedToEncoding_c(ivars self, NSStringEncoding enc)
static inline BOOL static inline BOOL
canBeConvertedToEncoding_u(ivars self, NSStringEncoding enc) canBeConvertedToEncoding_u(ivars self, NSStringEncoding enc)
{ {
if (self->_flags.ascii == 1) BOOL result = (*convertImp)((id)self, convertSel, enc);
return YES;
else
{
BOOL result = (*convertImp)((id)self, convertSel, enc);
if (enc == NSASCIIStringEncoding) return result;
{
self->_flags.ascii = 1;
}
return result;
}
} }
static inline unichar static inline unichar
@ -450,9 +434,14 @@ dataUsingEncoding_c(ivars self, NSStringEncoding encoding, BOOL flag)
return [NSDataClass data]; return [NSDataClass data];
} }
if (encoding == defEnc) if ((encoding == defEnc)
|| ((defEnc == NSASCIIStringEncoding)
&& ((encoding == NSISOLatin1StringEncoding)
|| (encoding == NSISOLatin2StringEncoding)
|| (encoding == NSNEXTSTEPStringEncoding)
|| (encoding == NSNonLossyASCIIStringEncoding))))
{ {
unsigned char *buff; unsigned char *buff;
buff = (unsigned char*)NSZoneMalloc(NSDefaultMallocZone(), len); buff = (unsigned char*)NSZoneMalloc(NSDefaultMallocZone(), len);
memcpy(buff, self->_contents.c, len); memcpy(buff, self->_contents.c, len);
@ -468,20 +457,6 @@ dataUsingEncoding_c(ivars self, NSStringEncoding encoding, BOOL flag)
t = encode_strtoustr(buff+1, self->_contents.c, len, defEnc); t = encode_strtoustr(buff+1, self->_contents.c, len, defEnc);
return [NSDataClass dataWithBytesNoCopy: buff length: t+2]; return [NSDataClass dataWithBytesNoCopy: buff length: t+2];
} }
else if ((encoding == defEnc)
|| ((defEnc == NSASCIIStringEncoding)
&& ((encoding == NSISOLatin1StringEncoding)
|| (encoding == NSISOLatin2StringEncoding)
|| (encoding == NSNEXTSTEPStringEncoding)
|| (encoding == NSNonLossyASCIIStringEncoding))))
{
unsigned char *buff;
buff = (unsigned char*)NSZoneMalloc(NSDefaultMallocZone(), len+1);
memcpy(buff, self->_contents.c, len);
buff[len] = '\0';
return [NSDataClass dataWithBytesNoCopy: buff length: len];
}
else else
{ {
int t; int t;
@ -497,7 +472,7 @@ dataUsingEncoding_c(ivars self, NSStringEncoding encoding, BOOL flag)
t = encode_ustrtostr_strict(buff, ubuff, t, encoding); t = encode_ustrtostr_strict(buff, ubuff, t, encoding);
buff[t] = '\0'; buff[t] = '\0';
NSZoneFree(NSDefaultMallocZone(), ubuff); NSZoneFree(NSDefaultMallocZone(), ubuff);
if (t != 0) if (t != len)
{ {
NSZoneFree(NSDefaultMallocZone(), buff); NSZoneFree(NSDefaultMallocZone(), buff);
return nil; return nil;
@ -1095,17 +1070,6 @@ transmute(ivars self, NSString *aString)
other = (ivars)aString; other = (ivars)aString;
transmute = YES; transmute = YES;
/*
* Unless we are sure that the other string we are going to insert into
* this one contains only ascii characters, we clear the flag that says
* we contain only ascii.
*/
if (fastClassIsKindOfClass(c, GSStringClass) == NO
|| c == NXConstantStringClass || other->_flags.ascii == 0)
{
self->_flags.ascii = 0;
}
if (self->_flags.wide == 1) if (self->_flags.wide == 1)
{ {
/* /*
@ -1168,7 +1132,14 @@ transmute(ivars self, NSString *aString)
tmp = NSZoneMalloc(self->_zone, self->_capacity * sizeof(unichar)); tmp = NSZoneMalloc(self->_zone, self->_capacity * sizeof(unichar));
encode_strtoustr(tmp, self->_contents.c, self->_count, defEnc); encode_strtoustr(tmp, self->_contents.c, self->_count, defEnc);
NSZoneFree(self->_zone, self->_contents.c); if (self->_flags.free == 1)
{
NSZoneFree(self->_zone, self->_contents.c);
}
else
{
self->_flags.free = 1;
}
self->_contents.u = tmp; self->_contents.u = tmp;
self->_flags.wide = 1; self->_flags.wide = 1;
} }
@ -1456,8 +1427,6 @@ transmute(ivars self, NSString *aString)
if (sub != nil) if (sub != nil)
{ {
sub->_parent = RETAIN(self); sub->_parent = RETAIN(self);
if (_flags.ascii == 1)
((ivars)sub)->_flags.ascii = 1;
AUTORELEASE(sub); AUTORELEASE(sub);
} }
return sub; return sub;
@ -1726,8 +1695,6 @@ transmute(ivars self, NSString *aString)
if (sub != nil) if (sub != nil)
{ {
sub->_parent = RETAIN(self); sub->_parent = RETAIN(self);
if (_flags.ascii == 1)
((ivars)sub)->_flags.ascii = 1;
AUTORELEASE(sub); AUTORELEASE(sub);
} }
return sub; return sub;
@ -2281,10 +2248,7 @@ transmute(ivars self, NSString *aString)
{ {
if (_flags.wide == 1) if (_flags.wide == 1)
{ {
if (_flags.ascii == 1) return NSUnicodeStringEncoding;
return NSASCIIStringEncoding;
else
return NSUnicodeStringEncoding;
} }
else else
return defEnc; return defEnc;

View file

@ -72,7 +72,7 @@
#include <base/fast.x> #include <base/fast.x>
@class GSCString; @class GSString;
@class GSMString; @class GSMString;
@class GSUString; @class GSUString;
@ -80,8 +80,12 @@
* Cache classes for speed. * Cache classes for speed.
*/ */
static Class NSData_class; static Class NSData_class;
static Class NSString_class; static Class NSStringClass;
static Class NSMutableString_class; static Class NSMutableStringClass;
static Class GSStringClass;
static Class GSMStringClass;
static Class GSUStringClass;
/* /*
* Include sequence handling code with instructions to generate search * Include sequence handling code with instructions to generate search
@ -145,14 +149,6 @@ pathSepMember(unichar c)
@implementation NSString @implementation NSString
/* For unichar strings. */
static Class NSString_concrete_class;
static Class NSMutableString_concrete_class;
/* For CString's */
static Class NSString_c_concrete_class;
static Class NSMutableString_c_concrete_class;
static NSStringEncoding _DefaultStringEncoding; static NSStringEncoding _DefaultStringEncoding;
#if HAVE_REGISTER_PRINTF_FUNCTION #if HAVE_REGISTER_PRINTF_FUNCTION
@ -219,13 +215,12 @@ handle_printf_atsign (FILE *stream,
if (self == [NSString class]) if (self == [NSString class])
{ {
_DefaultStringEncoding = GetDefEncoding(); _DefaultStringEncoding = GetDefEncoding();
NSString_class = self; NSStringClass = self;
NSMutableString_class = [NSMutableString class]; NSMutableStringClass = [NSMutableString class];
NSData_class = [NSData class]; NSData_class = [NSData class];
NSString_concrete_class = [GSUString class]; GSStringClass = [GSString class];
NSString_c_concrete_class = [GSCString class]; GSMStringClass = [GSMString class];
NSMutableString_concrete_class = [GSMString class]; GSUStringClass = [GSUString class];
NSMutableString_c_concrete_class = [GSMString class];
#if HAVE_REGISTER_PRINTF_FUNCTION #if HAVE_REGISTER_PRINTF_FUNCTION
if (register_printf_function ('@', if (register_printf_function ('@',
@ -243,9 +238,9 @@ handle_printf_atsign (FILE *stream,
+ (id) allocWithZone: (NSZone*)z + (id) allocWithZone: (NSZone*)z
{ {
if (self == NSString_class) if (self == NSStringClass)
{ {
return NSAllocateObject (NSString_concrete_class, 0, z); return NSAllocateObject (GSStringClass, 0, z);
} }
else else
{ {
@ -275,15 +270,15 @@ handle_printf_atsign (FILE *stream,
+ (id) stringWithCString: (const char*) byteString + (id) stringWithCString: (const char*) byteString
{ {
return AUTORELEASE([[NSString_c_concrete_class allocWithZone: return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
NSDefaultMallocZone()] initWithCString: byteString]); initWithCString: byteString]);
} }
+ (id) stringWithCString: (const char*)byteString + (id) stringWithCString: (const char*)byteString
length: (unsigned)length length: (unsigned)length
{ {
return AUTORELEASE([[NSString_c_concrete_class allocWithZone: return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
NSDefaultMallocZone()] initWithCString: byteString length: length]); initWithCString: byteString length: length]);
} }
+ (id) stringWithUTF8String: (const char *)bytes + (id) stringWithUTF8String: (const char *)bytes
@ -1009,8 +1004,8 @@ handle_printf_atsign (FILE *stream,
[self getCharacters: s]; [self getCharacters: s];
[aString getCharacters: s + len]; [aString getCharacters: s + len];
tmp = [[NSString_concrete_class allocWithZone: z] initWithCharactersNoCopy: s tmp = [[GSStringClass allocWithZone: z] initWithCharactersNoCopy: s
length: len + otherLength freeWhenDone: YES]; length: len + otherLength freeWhenDone: YES];
return AUTORELEASE(tmp); return AUTORELEASE(tmp);
} }
@ -1073,7 +1068,7 @@ handle_printf_atsign (FILE *stream,
return @""; return @"";
buf = NSZoneMalloc(fastZone(self), sizeof(unichar)*aRange.length); buf = NSZoneMalloc(fastZone(self), sizeof(unichar)*aRange.length);
[self getCharacters: buf range: aRange]; [self getCharacters: buf range: aRange];
ret = [[NSString_concrete_class allocWithZone: NSDefaultMallocZone()] ret = [[GSStringClass allocWithZone: NSDefaultMallocZone()]
initWithCharactersNoCopy: buf length: aRange.length freeWhenDone: YES]; initWithCharactersNoCopy: buf length: aRange.length freeWhenDone: YES];
return AUTORELEASE(ret); return AUTORELEASE(ret);
} }
@ -1252,7 +1247,7 @@ handle_printf_atsign (FILE *stream,
if (c != nil) if (c != nil)
{ {
if (fastClassIsKindOfClass(c, NSString_class)) if (fastClassIsKindOfClass(c, NSStringClass))
{ {
return [self isEqualToString: anObject]; return [self isEqualToString: anObject];
} }
@ -1651,8 +1646,7 @@ handle_printf_atsign (FILE *stream,
{ {
s[count] = uni_tolower((*caiImp)(self, caiSel, count)); s[count] = uni_tolower((*caiImp)(self, caiSel, count));
} }
return AUTORELEASE([[NSString_concrete_class return AUTORELEASE([[GSStringClass allocWithZone: NSDefaultMallocZone()]
allocWithZone: NSDefaultMallocZone()]
initWithCharactersNoCopy: s length: len freeWhenDone: YES]); initWithCharactersNoCopy: s length: len freeWhenDone: YES]);
} }
@ -1673,8 +1667,7 @@ handle_printf_atsign (FILE *stream,
{ {
s[count] = uni_toupper((*caiImp)(self, caiSel, count)); s[count] = uni_toupper((*caiImp)(self, caiSel, count));
} }
return AUTORELEASE([[NSString_concrete_class return AUTORELEASE([[GSStringClass allocWithZone: NSDefaultMallocZone()]
allocWithZone: NSDefaultMallocZone()]
initWithCharactersNoCopy: s length: len freeWhenDone: YES]); initWithCharactersNoCopy: s length: len freeWhenDone: YES]);
} }
@ -1939,14 +1932,12 @@ handle_printf_atsign (FILE *stream,
- (NSStringEncoding) fastestEncoding - (NSStringEncoding) fastestEncoding
{ {
[self subclassResponsibility: _cmd]; return NSUnicodeStringEncoding;
return 0;
} }
- (NSStringEncoding) smallestEncoding - (NSStringEncoding) smallestEncoding
{ {
[self subclassResponsibility: _cmd]; return NSUnicodeStringEncoding;
return 0;
} }
@ -2123,7 +2114,7 @@ handle_printf_atsign (FILE *stream,
aLength--; aLength--;
} }
} }
return [NSString_class stringWithCharacters: buf length: length]; return [NSStringClass stringWithCharacters: buf length: length];
} }
/* Returns a new string with the path extension given in aString /* Returns a new string with the path extension given in aString
@ -2205,7 +2196,7 @@ handle_printf_atsign (FILE *stream,
homedir = NSHomeDirectory (); homedir = NSHomeDirectory ();
} }
return [NSString_class stringWithFormat: @"%@%@", homedir, return [NSStringClass stringWithFormat: @"%@%@", homedir,
[self substringFromIndex: first_slash_range.location]]; [self substringFromIndex: first_slash_range.location]];
} }
@ -2216,7 +2207,7 @@ handle_printf_atsign (FILE *stream,
if (![self hasPrefix: homedir]) if (![self hasPrefix: homedir])
return AUTORELEASE([self copy]); return AUTORELEASE([self copy]);
return [NSString_class stringWithFormat: @"~%c%@", (char)pathSepChar, return [NSStringClass stringWithFormat: @"~%c%@", (char)pathSepChar,
[self substringFromIndex: [homedir length] + 1]]; [self substringFromIndex: [homedir length] + 1]];
} }
@ -2730,7 +2721,7 @@ handle_printf_atsign (FILE *stream,
} }
*ptr++ = '"'; *ptr++ = '"';
*ptr = '\0'; *ptr = '\0';
[output appendString: [NSString_class stringWithCString: buf]]; [output appendString: [NSStringClass stringWithCString: buf]];
} }
} }
else else
@ -2745,17 +2736,15 @@ handle_printf_atsign (FILE *stream,
- (id) copyWithZone: (NSZone*)zone - (id) copyWithZone: (NSZone*)zone
{ {
if ([self isKindOfClass: [NSMutableString class]] || if ([self isKindOfClass: [NSMutableString class]] ||
NSShouldRetainWithZone(self, zone) == NO) NSShouldRetainWithZone(self, zone) == NO)
return [[NSString_concrete_class allocWithZone: zone] return [[GSStringClass allocWithZone: zone] initWithString: self];
initWithString: self];
else else
return RETAIN(self); return RETAIN(self);
} }
- (id) mutableCopyWithZone: (NSZone*)zone - (id) mutableCopyWithZone: (NSZone*)zone
{ {
return [[NSMutableString_concrete_class allocWithZone: zone] return [[GSMStringClass allocWithZone: zone] initWithString: self];
initWithString: self];
} }
/* NSCoding Protocol */ /* NSCoding Protocol */
@ -2858,7 +2847,7 @@ handle_printf_atsign (FILE *stream,
- (Class) classForCoder - (Class) classForCoder
{ {
return NSString_class; return NSStringClass;
} }
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder - (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
@ -2928,9 +2917,9 @@ handle_printf_atsign (FILE *stream,
+ (id) allocWithZone: (NSZone*)z + (id) allocWithZone: (NSZone*)z
{ {
if (self == NSMutableString_class) if (self == NSMutableStringClass)
{ {
return NSAllocateObject(NSMutableString_concrete_class, 0, z); return NSAllocateObject(GSMStringClass, 0, z);
} }
else else
{ {
@ -2942,13 +2931,13 @@ handle_printf_atsign (FILE *stream,
+ (NSMutableString*) string + (NSMutableString*) string
{ {
return AUTORELEASE([[NSMutableString_c_concrete_class allocWithZone: return AUTORELEASE([[GSMStringClass allocWithZone:
NSDefaultMallocZone()] initWithCapacity: 0]); NSDefaultMallocZone()] initWithCapacity: 0]);
} }
+ (NSMutableString*) stringWithCapacity: (unsigned)capacity + (NSMutableString*) stringWithCapacity: (unsigned)capacity
{ {
return AUTORELEASE([[NSMutableString_c_concrete_class allocWithZone: return AUTORELEASE([[GSMStringClass allocWithZone:
NSDefaultMallocZone()] initWithCapacity: capacity]); NSDefaultMallocZone()] initWithCapacity: capacity]);
} }
@ -2956,26 +2945,26 @@ handle_printf_atsign (FILE *stream,
+ (NSString*) stringWithCharacters: (const unichar*)characters + (NSString*) stringWithCharacters: (const unichar*)characters
length: (unsigned)length length: (unsigned)length
{ {
return AUTORELEASE([[NSMutableString_c_concrete_class allocWithZone: return AUTORELEASE([[GSMStringClass allocWithZone:
NSDefaultMallocZone()] initWithCharacters: characters length: length]); NSDefaultMallocZone()] initWithCharacters: characters length: length]);
} }
+ (id) stringWithContentsOfFile: (NSString *)path + (id) stringWithContentsOfFile: (NSString *)path
{ {
return AUTORELEASE([[NSMutableString_c_concrete_class allocWithZone: return AUTORELEASE([[GSMStringClass allocWithZone:
NSDefaultMallocZone()] initWithContentsOfFile: path]); NSDefaultMallocZone()] initWithContentsOfFile: path]);
} }
+ (NSString*) stringWithCString: (const char*)byteString + (NSString*) stringWithCString: (const char*)byteString
{ {
return AUTORELEASE([[NSMutableString_c_concrete_class allocWithZone: return AUTORELEASE([[GSMStringClass allocWithZone:
NSDefaultMallocZone()] initWithCString: byteString]); NSDefaultMallocZone()] initWithCString: byteString]);
} }
+ (NSString*) stringWithCString: (const char*)byteString + (NSString*) stringWithCString: (const char*)byteString
length: (unsigned)length length: (unsigned)length
{ {
return AUTORELEASE([[NSMutableString_c_concrete_class allocWithZone: return AUTORELEASE([[GSMStringClass allocWithZone:
NSDefaultMallocZone()] initWithCString: byteString length: length]); NSDefaultMallocZone()] initWithCString: byteString length: length]);
} }
@ -3023,7 +3012,7 @@ handle_printf_atsign (FILE *stream,
- (Class) classForCoder - (Class) classForCoder
{ {
return NSMutableString_class; return NSMutableStringClass;
} }
- (void) deleteCharactersInRange: (NSRange)range - (void) deleteCharactersInRange: (NSRange)range
@ -3177,7 +3166,7 @@ handle_printf_atsign (FILE *stream,
@end @end
@implementation NSString (GSString) @implementation NSString (GNUstep)
- (NSString*) stringWithoutSuffix: (NSString*)_suffix - (NSString*) stringWithoutSuffix: (NSString*)_suffix
{ {
@ -3214,7 +3203,7 @@ handle_printf_atsign (FILE *stream,
@end @end
@implementation NSMutableString (GSString) @implementation NSMutableString (GNUstep)
- (void) removeSuffix: (NSString*)_suffix - (void) removeSuffix: (NSString*)_suffix
{ {
NSCAssert2([self hasSuffix: _suffix], NSCAssert2([self hasSuffix: _suffix],