mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 16:50:58 +00:00
Various improvements and bugfixes
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@7856 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
65241c052d
commit
4386ba0c61
5 changed files with 428 additions and 130 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2000-10-20 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/NSString.m: ([-initWithCharacters:length:]) use
|
||||||
|
([-initWithCStringNoCopy:length:freeWhenDone:]) if possible.
|
||||||
|
* Source/GSString.m: Much tidying up. Added two new concrete
|
||||||
|
classes for substrings.
|
||||||
|
* Source/NSCalendarDate.m: ([-initWithString:calendarFormat:locale:])
|
||||||
|
avoid any attempt to read beyond the supplied string.
|
||||||
|
|
||||||
2000-10-16 Richard Frith-Macdonald <rfm@gnu.org>
|
2000-10-16 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
Attempts to make sure that when members of a class cluster are encoded
|
Attempts to make sure that when members of a class cluster are encoded
|
||||||
|
|
|
@ -345,7 +345,8 @@ enum {
|
||||||
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 ascii: 1; // String contains only ascii?
|
||||||
unsigned int free: 1; // Should free memory?
|
unsigned int free: 1; // Should free memory?
|
||||||
unsigned int hash: 30;
|
unsigned int unused: 1;
|
||||||
|
unsigned int hash: 28;
|
||||||
} _flags;
|
} _flags;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -49,16 +49,48 @@
|
||||||
#include <base/fast.x>
|
#include <base/fast.x>
|
||||||
#include <base/Unicode.h>
|
#include <base/Unicode.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GSCString - concrete class for strings using 8-bit character sets.
|
||||||
|
*/
|
||||||
@interface GSCString : GSString
|
@interface GSCString : GSString
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GSCSubString - concrete subclass of GSCString, that relys on the
|
||||||
|
* data stored in a GSCString object.
|
||||||
|
*/
|
||||||
|
@interface GSCSubString : GSCString
|
||||||
|
{
|
||||||
|
@public
|
||||||
|
GSCString *_parent;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GSUString - concrete class for strings using 16-bit character sets.
|
||||||
|
*/
|
||||||
@interface GSUString : GSString
|
@interface GSUString : GSString
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GSUSubString - concrete subclass of GSUString, that relys on the
|
||||||
|
* data stored in a GSUString object.
|
||||||
|
*/
|
||||||
|
@interface GSUSubString : GSUString
|
||||||
|
{
|
||||||
|
@public
|
||||||
|
GSUString *_parent;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GSMString - concrete mutable string, capable of changing its storage
|
||||||
|
* from holding 8-bit to 16-bit character set.
|
||||||
|
*/
|
||||||
@interface GSMString : NSMutableString
|
@interface GSMString : NSMutableString
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
|
@ -70,7 +102,8 @@
|
||||||
unsigned int wide: 1;
|
unsigned int wide: 1;
|
||||||
unsigned int ascii: 1;
|
unsigned int ascii: 1;
|
||||||
unsigned int free: 1;
|
unsigned int free: 1;
|
||||||
unsigned int hash: 30;
|
unsigned int unused: 1;
|
||||||
|
unsigned int hash: 28;
|
||||||
} _flags;
|
} _flags;
|
||||||
NSZone *_zone;
|
NSZone *_zone;
|
||||||
unsigned int _capacity;
|
unsigned int _capacity;
|
||||||
|
@ -126,8 +159,11 @@ typedef struct {
|
||||||
|
|
||||||
static Class NSDataClass = 0;
|
static Class NSDataClass = 0;
|
||||||
static Class NSStringClass = 0;
|
static Class NSStringClass = 0;
|
||||||
|
static Class GSStringClass = 0;
|
||||||
static Class GSCStringClass = 0;
|
static Class GSCStringClass = 0;
|
||||||
|
static Class GSCSubStringClass = 0;
|
||||||
static Class GSUStringClass = 0;
|
static Class GSUStringClass = 0;
|
||||||
|
static Class GSUSubStringClass = 0;
|
||||||
static Class GSMStringClass = 0;
|
static Class GSMStringClass = 0;
|
||||||
static Class NXConstantStringClass = 0;
|
static Class NXConstantStringClass = 0;
|
||||||
|
|
||||||
|
@ -140,6 +176,10 @@ static unsigned (*hashImp)(id, SEL) = 0;
|
||||||
|
|
||||||
static NSStringEncoding defEnc = 0;
|
static NSStringEncoding defEnc = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The setup() function is called when any concrete string class is
|
||||||
|
* initialized, and cached classes and some method implementations.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
setup()
|
setup()
|
||||||
{
|
{
|
||||||
|
@ -151,8 +191,11 @@ setup()
|
||||||
|
|
||||||
NSDataClass = [NSData class];
|
NSDataClass = [NSData class];
|
||||||
NSStringClass = [NSString class];
|
NSStringClass = [NSString class];
|
||||||
|
GSStringClass = [GSString class];
|
||||||
GSCStringClass = [GSCString class];
|
GSCStringClass = [GSCString class];
|
||||||
GSUStringClass = [GSUString class];
|
GSUStringClass = [GSUString class];
|
||||||
|
GSCSubStringClass = [GSCSubString class];
|
||||||
|
GSUSubStringClass = [GSUSubString class];
|
||||||
GSMStringClass = [GSMString class];
|
GSMStringClass = [GSMString class];
|
||||||
NXConstantStringClass = [NXConstantString class];
|
NXConstantStringClass = [NXConstantString class];
|
||||||
|
|
||||||
|
@ -168,6 +211,19 @@ setup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 NXConstant inherit methods from GSCString.
|
||||||
|
* GSUString uses the functions with the _u suffix.
|
||||||
|
* GSUSubString inherits methods from GSUString.
|
||||||
|
* GSMString uses all the functions, selecting the _c or _u versions
|
||||||
|
* depending on whether its storage is 8-bit or 16-bit.
|
||||||
|
* In addition, GSMString uses a few functions without a suffix that are
|
||||||
|
* peculiar to its memory management (shrinking, growing, and converting).
|
||||||
|
*/
|
||||||
|
|
||||||
static inline BOOL
|
static inline BOOL
|
||||||
boolValue_c(ivars self)
|
boolValue_c(ivars self)
|
||||||
{
|
{
|
||||||
|
@ -230,14 +286,35 @@ 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
|
||||||
return (*convertImp)((id)self, convertSel, enc);
|
{
|
||||||
|
BOOL result = (*convertImp)((id)self, convertSel, enc);
|
||||||
|
|
||||||
|
if (enc == NSASCIIStringEncoding)
|
||||||
|
{
|
||||||
|
self->_flags.ascii = 1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline BOOL
|
static inline BOOL
|
||||||
canBeConvertedToEncoding_u(ivars self, NSStringEncoding enc)
|
canBeConvertedToEncoding_u(ivars self, NSStringEncoding enc)
|
||||||
{
|
{
|
||||||
return (*convertImp)((id)self, convertSel, enc);
|
if (self->_flags.ascii == 1)
|
||||||
|
return YES;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BOOL result = (*convertImp)((id)self, convertSel, enc);
|
||||||
|
|
||||||
|
if (enc == NSASCIIStringEncoding)
|
||||||
|
{
|
||||||
|
self->_flags.ascii = 1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unichar
|
static inline unichar
|
||||||
|
@ -270,13 +347,16 @@ compare_c(ivars self, NSString *aString, unsigned mask, NSRange aRange)
|
||||||
|
|
||||||
if (aString == nil)
|
if (aString == nil)
|
||||||
[NSException raise: NSInvalidArgumentException format: @"compare with nil"];
|
[NSException raise: NSInvalidArgumentException format: @"compare with nil"];
|
||||||
|
if (fastIsInstance(aString) == NO)
|
||||||
|
return strCompCsNs((id)self, aString, mask, aRange);
|
||||||
|
|
||||||
c = fastClass(aString);
|
c = fastClass(aString);
|
||||||
if (c == GSUStringClass
|
if (fastClassIsKindOfClass(c, GSUStringClass) == YES
|
||||||
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 1))
|
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 1))
|
||||||
return strCompCsUs((id)self, aString, mask, aRange);
|
return strCompCsUs((id)self, aString, mask, aRange);
|
||||||
else if (c == GSCStringClass
|
else if (fastClassIsKindOfClass(c, GSCStringClass) == YES
|
||||||
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 0)
|
|| c == NXConstantStringClass
|
||||||
|| c == NXConstantStringClass)
|
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 0))
|
||||||
return strCompCsCs((id)self, aString, mask, aRange);
|
return strCompCsCs((id)self, aString, mask, aRange);
|
||||||
else
|
else
|
||||||
return strCompCsNs((id)self, aString, mask, aRange);
|
return strCompCsNs((id)self, aString, mask, aRange);
|
||||||
|
@ -289,13 +369,16 @@ compare_u(ivars self, NSString *aString, unsigned mask, NSRange aRange)
|
||||||
|
|
||||||
if (aString == nil)
|
if (aString == nil)
|
||||||
[NSException raise: NSInvalidArgumentException format: @"compare with nil"];
|
[NSException raise: NSInvalidArgumentException format: @"compare with nil"];
|
||||||
|
if (fastIsInstance(aString) == NO)
|
||||||
|
return strCompUsNs((id)self, aString, mask, aRange);
|
||||||
|
|
||||||
c = fastClass(aString);
|
c = fastClass(aString);
|
||||||
if (c == GSUStringClass
|
if (fastClassIsKindOfClass(c, GSUStringClass)
|
||||||
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 1))
|
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 1))
|
||||||
return strCompUsUs((id)self, aString, mask, aRange);
|
return strCompUsUs((id)self, aString, mask, aRange);
|
||||||
else if (c == GSCStringClass
|
else if (fastClassIsKindOfClass(c, GSCStringClass)
|
||||||
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 0)
|
|| c == NXConstantStringClass
|
||||||
|| c == NXConstantStringClass)
|
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 0))
|
||||||
return strCompUsCs((id)self, aString, mask, aRange);
|
return strCompUsCs((id)self, aString, mask, aRange);
|
||||||
else
|
else
|
||||||
return strCompUsNs((id)self, aString, mask, aRange);
|
return strCompUsNs((id)self, aString, mask, aRange);
|
||||||
|
@ -386,11 +469,11 @@ dataUsingEncoding_c(ivars self, NSStringEncoding encoding, BOOL flag)
|
||||||
return [NSDataClass dataWithBytesNoCopy: buff length: t+2];
|
return [NSDataClass dataWithBytesNoCopy: buff length: t+2];
|
||||||
}
|
}
|
||||||
else if ((encoding == defEnc)
|
else if ((encoding == defEnc)
|
||||||
||((defEnc == NSASCIIStringEncoding)
|
|| ((defEnc == NSASCIIStringEncoding)
|
||||||
&& ((encoding == NSISOLatin1StringEncoding)
|
&& ((encoding == NSISOLatin1StringEncoding)
|
||||||
|| (encoding == NSISOLatin2StringEncoding)
|
|| (encoding == NSISOLatin2StringEncoding)
|
||||||
|| (encoding == NSNEXTSTEPStringEncoding)
|
|| (encoding == NSNEXTSTEPStringEncoding)
|
||||||
|| (encoding == NSNonLossyASCIIStringEncoding))))
|
|| (encoding == NSNonLossyASCIIStringEncoding))))
|
||||||
{
|
{
|
||||||
unsigned char *buff;
|
unsigned char *buff;
|
||||||
|
|
||||||
|
@ -621,16 +704,6 @@ getCString_u(ivars self, char *buffer, unsigned int maxLength,
|
||||||
buffer[len] = '\0';
|
buffer[len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned
|
|
||||||
hash(ivars self)
|
|
||||||
{
|
|
||||||
if (self->_flags.hash == 0)
|
|
||||||
{
|
|
||||||
self->_flags.hash = (*hashImp)((id)self, hashSel);
|
|
||||||
}
|
|
||||||
return self->_flags.hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
intValue_c(ivars self)
|
intValue_c(ivars self)
|
||||||
{
|
{
|
||||||
|
@ -668,7 +741,7 @@ intValue_u(ivars self)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline BOOL
|
static inline BOOL
|
||||||
isEqual(ivars self, id anObject)
|
isEqual_c(ivars self, id anObject)
|
||||||
{
|
{
|
||||||
Class c;
|
Class c;
|
||||||
|
|
||||||
|
@ -680,8 +753,21 @@ isEqual(ivars self, id anObject)
|
||||||
{
|
{
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
if (fastIsInstance(anObject) == NO)
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
c = fastClassOfInstance(anObject);
|
c = fastClassOfInstance(anObject);
|
||||||
if (c == GSCStringClass || c == GSUStringClass || c == GSMStringClass)
|
if (c == NXConstantStringClass)
|
||||||
|
{
|
||||||
|
ivars other = (ivars)anObject;
|
||||||
|
NSRange r = {0, self->_count};
|
||||||
|
|
||||||
|
if (strCompCsCs((id)self, (id)other, 0, r) == NSOrderedSame)
|
||||||
|
return YES;
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
else if (fastClassIsKindOfClass(c, GSStringClass) == YES)
|
||||||
{
|
{
|
||||||
ivars other = (ivars)anObject;
|
ivars other = (ivars)anObject;
|
||||||
NSRange r = {0, self->_count};
|
NSRange r = {0, self->_count};
|
||||||
|
@ -701,40 +787,7 @@ isEqual(ivars self, id anObject)
|
||||||
*/
|
*/
|
||||||
if (other->_flags.wide == 1)
|
if (other->_flags.wide == 1)
|
||||||
{
|
{
|
||||||
if (self->_flags.wide == 1)
|
if (strCompCsUs((id)self, (id)other, 0, r) == NSOrderedSame)
|
||||||
{
|
|
||||||
if (strCompUsUs((id)self, (id)other, 0, r) == NSOrderedSame)
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (strCompCsUs((id)self, (id)other, 0, r) == NSOrderedSame)
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (self->_flags.wide == 1)
|
|
||||||
{
|
|
||||||
if (strCompUsCs((id)self, (id)other, 0, r) == NSOrderedSame)
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (strCompCsCs((id)self, (id)other, 0, r) == NSOrderedSame)
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
else if (c == NXConstantStringClass)
|
|
||||||
{
|
|
||||||
ivars other = (ivars)anObject;
|
|
||||||
NSRange r = {0, self->_count};
|
|
||||||
|
|
||||||
if (self->_flags.wide == 1)
|
|
||||||
{
|
|
||||||
if (strCompUsCs((id)self, (id)other, 0, r) == NSOrderedSame)
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -744,8 +797,71 @@ isEqual(ivars self, id anObject)
|
||||||
}
|
}
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
else if (c == nil)
|
else if (fastClassIsKindOfClass(c, NSStringClass))
|
||||||
{
|
{
|
||||||
|
return (*equalImp)((id)self, equalSel, anObject);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline BOOL
|
||||||
|
isEqual_u(ivars self, id anObject)
|
||||||
|
{
|
||||||
|
Class c;
|
||||||
|
|
||||||
|
if (anObject == (id)self)
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
if (anObject == nil)
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
if (fastIsInstance(anObject) == NO)
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
c = fastClassOfInstance(anObject);
|
||||||
|
if (c == NXConstantStringClass)
|
||||||
|
{
|
||||||
|
ivars other = (ivars)anObject;
|
||||||
|
NSRange r = {0, self->_count};
|
||||||
|
|
||||||
|
if (strCompUsCs((id)self, (id)other, 0, r) == NSOrderedSame)
|
||||||
|
return YES;
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
else if (fastClassIsKindOfClass(c, GSStringClass) == YES)
|
||||||
|
{
|
||||||
|
ivars other = (ivars)anObject;
|
||||||
|
NSRange r = {0, self->_count};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First see if the hash is the same - if not, we can't be equal.
|
||||||
|
*/
|
||||||
|
if (self->_flags.hash == 0)
|
||||||
|
self->_flags.hash = (*hashImp)((id)self, hashSel);
|
||||||
|
if (other->_flags.hash == 0)
|
||||||
|
other->_flags.hash = (*hashImp)((id)other, hashSel);
|
||||||
|
if (self->_flags.hash != other->_flags.hash)
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do a compare depending on the type of the other string.
|
||||||
|
*/
|
||||||
|
if (other->_flags.wide == 1)
|
||||||
|
{
|
||||||
|
if (strCompUsUs((id)self, (id)other, 0, r) == NSOrderedSame)
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (strCompUsCs((id)self, (id)other, 0, r) == NSOrderedSame)
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
else if (fastClassIsKindOfClass(c, NSStringClass))
|
else if (fastClassIsKindOfClass(c, NSStringClass))
|
||||||
|
@ -925,13 +1041,16 @@ rangeOfString_c(ivars self, NSString *aString, unsigned mask, NSRange aRange)
|
||||||
|
|
||||||
if (aString == nil)
|
if (aString == nil)
|
||||||
[NSException raise: NSInvalidArgumentException format: @"range of nil"];
|
[NSException raise: NSInvalidArgumentException format: @"range of nil"];
|
||||||
|
if (fastIsInstance(aString) == NO)
|
||||||
|
return strRangeCsNs((id)self, aString, mask, aRange);
|
||||||
|
|
||||||
c = fastClass(aString);
|
c = fastClass(aString);
|
||||||
if (c == GSUStringClass
|
if (fastClassIsKindOfClass(c, GSUStringClass) == YES
|
||||||
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 1))
|
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 1))
|
||||||
return strRangeCsUs((id)self, aString, mask, aRange);
|
return strRangeCsUs((id)self, aString, mask, aRange);
|
||||||
else if (c == GSCStringClass
|
else if (fastClassIsKindOfClass(c, GSCStringClass) == YES
|
||||||
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 0)
|
|| c == NXConstantStringClass
|
||||||
|| c == NXConstantStringClass)
|
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 0))
|
||||||
return strRangeCsCs((id)self, aString, mask, aRange);
|
return strRangeCsCs((id)self, aString, mask, aRange);
|
||||||
else
|
else
|
||||||
return strRangeCsNs((id)self, aString, mask, aRange);
|
return strRangeCsNs((id)self, aString, mask, aRange);
|
||||||
|
@ -944,32 +1063,21 @@ rangeOfString_u(ivars self, NSString *aString, unsigned mask, NSRange aRange)
|
||||||
|
|
||||||
if (aString == nil)
|
if (aString == nil)
|
||||||
[NSException raise: NSInvalidArgumentException format: @"range of nil"];
|
[NSException raise: NSInvalidArgumentException format: @"range of nil"];
|
||||||
|
if (fastIsInstance(aString) == NO)
|
||||||
|
return strRangeUsNs((id)self, aString, mask, aRange);
|
||||||
|
|
||||||
c = fastClass(aString);
|
c = fastClass(aString);
|
||||||
if (c == GSUStringClass
|
if (fastClassIsKindOfClass(c, GSUStringClass) == YES
|
||||||
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 1))
|
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 1))
|
||||||
return strRangeUsUs((id)self, aString, mask, aRange);
|
return strRangeUsUs((id)self, aString, mask, aRange);
|
||||||
else if (c == GSCStringClass
|
else if (fastClassIsKindOfClass(c, GSCStringClass) == YES
|
||||||
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 0)
|
|| c == NXConstantStringClass
|
||||||
|| c == NXConstantStringClass)
|
|| (c == GSMStringClass && ((ivars)aString)->_flags.wide == 0))
|
||||||
return strRangeUsCs((id)self, aString, mask, aRange);
|
return strRangeUsCs((id)self, aString, mask, aRange);
|
||||||
else
|
else
|
||||||
return strRangeUsNs((id)self, aString, mask, aRange);
|
return strRangeUsNs((id)self, aString, mask, aRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline NSString*
|
|
||||||
substringFromRange_c(ivars self, NSRange aRange)
|
|
||||||
{
|
|
||||||
return [GSCStringClass stringWithCString:
|
|
||||||
self->_contents.c + aRange.location length: aRange.length];
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline NSString*
|
|
||||||
substringFromRange_u(ivars self, NSRange aRange)
|
|
||||||
{
|
|
||||||
return [GSUStringClass stringWithCharacters:
|
|
||||||
self->_contents.u + aRange.location length: aRange.length];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function to examine the given string and see if it is one of our concrete
|
* Function to examine the given string and see if it is one of our concrete
|
||||||
* string classes. Converts the mutable string (self) from 8-bit to 16-bit
|
* string classes. Converts the mutable string (self) from 8-bit to 16-bit
|
||||||
|
@ -987,8 +1095,24 @@ 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)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* This is already a unicode string, so we don't need to transmute,
|
||||||
|
* but we still need to know if the other string is a unicode
|
||||||
|
* string whose ivars we can access directly.
|
||||||
|
*/
|
||||||
transmute = NO;
|
transmute = NO;
|
||||||
if ((c != GSMStringClass || other->_flags.wide != 1)
|
if ((c != GSMStringClass || other->_flags.wide != 1)
|
||||||
&& c != GSUStringClass)
|
&& c != GSUStringClass)
|
||||||
|
@ -1001,20 +1125,39 @@ transmute(ivars self, NSString *aString)
|
||||||
if (c == GSCStringClass || c == NXConstantStringClass
|
if (c == GSCStringClass || c == NXConstantStringClass
|
||||||
|| (c == GSMStringClass && other->_flags.wide == 0))
|
|| (c == GSMStringClass && other->_flags.wide == 0))
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* This is a C string, but the other string is also a C string
|
||||||
|
* so we don't need to transmute, and we can use its ivars.
|
||||||
|
*/
|
||||||
transmute = NO;
|
transmute = NO;
|
||||||
}
|
}
|
||||||
else if ([aString canBeConvertedToEncoding: defEnc] == YES)
|
else if ([aString canBeConvertedToEncoding: defEnc] == YES)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* This is a C string, but the other string can be converted to
|
||||||
|
* a C string, so we don't need to transmute, but we can not use
|
||||||
|
* its ivars.
|
||||||
|
*/
|
||||||
transmute = NO;
|
transmute = NO;
|
||||||
other = 0;
|
other = 0;
|
||||||
}
|
}
|
||||||
else if ((c == GSMStringClass && other->_flags.wide == 1)
|
else if ((c == GSMStringClass && other->_flags.wide == 1)
|
||||||
|| c == GSUStringClass)
|
|| c == GSUStringClass)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* This is a C string, and the other string can not be converted
|
||||||
|
* to a C string, so we need to transmute, and will then be able
|
||||||
|
* to use its ivars.
|
||||||
|
*/
|
||||||
transmute = YES;
|
transmute = YES;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* This is a C string, and the other string can not be converted
|
||||||
|
* to a C string, so we need to transmute, but even then we will
|
||||||
|
* not be able to use the other strings ivars.
|
||||||
|
*/
|
||||||
other = 0;
|
other = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1235,7 +1378,11 @@ transmute(ivars self, NSString *aString)
|
||||||
|
|
||||||
- (unsigned) hash
|
- (unsigned) hash
|
||||||
{
|
{
|
||||||
return hash((ivars)self);
|
if (self->_flags.hash == 0)
|
||||||
|
{
|
||||||
|
self->_flags.hash = (*hashImp)((id)self, hashSel);
|
||||||
|
}
|
||||||
|
return self->_flags.hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int) intValue
|
- (int) intValue
|
||||||
|
@ -1245,7 +1392,12 @@ transmute(ivars self, NSString *aString)
|
||||||
|
|
||||||
- (BOOL) isEqual: (id)anObject
|
- (BOOL) isEqual: (id)anObject
|
||||||
{
|
{
|
||||||
return isEqual((ivars)self, anObject);
|
return isEqual_c((ivars)self, anObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) isEqualToString: (NSString*)anObject
|
||||||
|
{
|
||||||
|
return isEqual_c((ivars)self, anObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned int) length
|
- (unsigned int) length
|
||||||
|
@ -1293,8 +1445,22 @@ transmute(ivars self, NSString *aString)
|
||||||
|
|
||||||
- (NSString*) substringFromRange: (NSRange)aRange
|
- (NSString*) substringFromRange: (NSRange)aRange
|
||||||
{
|
{
|
||||||
|
GSCSubString *sub;
|
||||||
|
|
||||||
GS_RANGE_CHECK(aRange, _count);
|
GS_RANGE_CHECK(aRange, _count);
|
||||||
return substringFromRange_c((ivars)self, aRange);
|
|
||||||
|
sub = [GSCSubStringClass allocWithZone: NSDefaultMallocZone()];
|
||||||
|
sub = [sub initWithCStringNoCopy: self->_contents.c + aRange.location
|
||||||
|
length: aRange.length
|
||||||
|
freeWhenDone: NO];
|
||||||
|
if (sub != nil)
|
||||||
|
{
|
||||||
|
sub->_parent = RETAIN(self);
|
||||||
|
if (_flags.ascii == 1)
|
||||||
|
((ivars)sub)->_flags.ascii = 1;
|
||||||
|
AUTORELEASE(sub);
|
||||||
|
}
|
||||||
|
return sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private method for Unicode level 3 implementation
|
// private method for Unicode level 3 implementation
|
||||||
|
@ -1307,6 +1473,16 @@ transmute(ivars self, NSString *aString)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@implementation GSCSubString
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
RELEASE(_parent);
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@implementation GSUString
|
@implementation GSUString
|
||||||
|
|
||||||
+ (id) alloc
|
+ (id) alloc
|
||||||
|
@ -1472,7 +1648,11 @@ transmute(ivars self, NSString *aString)
|
||||||
|
|
||||||
- (unsigned) hash
|
- (unsigned) hash
|
||||||
{
|
{
|
||||||
return hash((ivars)self);
|
if (self->_flags.hash == 0)
|
||||||
|
{
|
||||||
|
self->_flags.hash = (*hashImp)((id)self, hashSel);
|
||||||
|
}
|
||||||
|
return self->_flags.hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int) intValue
|
- (int) intValue
|
||||||
|
@ -1482,7 +1662,12 @@ transmute(ivars self, NSString *aString)
|
||||||
|
|
||||||
- (BOOL) isEqual: (id)anObject
|
- (BOOL) isEqual: (id)anObject
|
||||||
{
|
{
|
||||||
return isEqual((ivars)self, anObject);
|
return isEqual_u((ivars)self, anObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) isEqualToString: (NSString*)anObject
|
||||||
|
{
|
||||||
|
return isEqual_u((ivars)self, anObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned int) length
|
- (unsigned int) length
|
||||||
|
@ -1530,8 +1715,22 @@ transmute(ivars self, NSString *aString)
|
||||||
|
|
||||||
- (NSString*) substringFromRange: (NSRange)aRange
|
- (NSString*) substringFromRange: (NSRange)aRange
|
||||||
{
|
{
|
||||||
|
GSUSubString *sub;
|
||||||
|
|
||||||
GS_RANGE_CHECK(aRange, _count);
|
GS_RANGE_CHECK(aRange, _count);
|
||||||
return substringFromRange_u((ivars)self, aRange);
|
|
||||||
|
sub = [GSUStringClass allocWithZone: NSDefaultMallocZone()];
|
||||||
|
sub = [sub initWithCharactersNoCopy: self->_contents.u + aRange.location
|
||||||
|
length: aRange.length
|
||||||
|
freeWhenDone: NO];
|
||||||
|
if (sub != nil)
|
||||||
|
{
|
||||||
|
sub->_parent = RETAIN(self);
|
||||||
|
if (_flags.ascii == 1)
|
||||||
|
((ivars)sub)->_flags.ascii = 1;
|
||||||
|
AUTORELEASE(sub);
|
||||||
|
}
|
||||||
|
return sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private method for Unicode level 3 implementation
|
// private method for Unicode level 3 implementation
|
||||||
|
@ -1550,6 +1749,16 @@ transmute(ivars self, NSString *aString)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@implementation GSUSubString
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
RELEASE(_parent);
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@implementation GSMString
|
@implementation GSMString
|
||||||
|
|
||||||
+ (id) alloc
|
+ (id) alloc
|
||||||
|
@ -1783,7 +1992,11 @@ transmute(ivars self, NSString *aString)
|
||||||
|
|
||||||
- (unsigned) hash
|
- (unsigned) hash
|
||||||
{
|
{
|
||||||
return hash((ivars)self);
|
if (self->_flags.hash == 0)
|
||||||
|
{
|
||||||
|
self->_flags.hash = (*hashImp)((id)self, hashSel);
|
||||||
|
}
|
||||||
|
return self->_flags.hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) init
|
- (id) init
|
||||||
|
@ -1868,7 +2081,18 @@ transmute(ivars self, NSString *aString)
|
||||||
|
|
||||||
- (BOOL) isEqual: (id)anObject
|
- (BOOL) isEqual: (id)anObject
|
||||||
{
|
{
|
||||||
return isEqual((ivars)self, anObject);
|
if (_flags.wide == 1)
|
||||||
|
return isEqual_u((ivars)self, anObject);
|
||||||
|
else
|
||||||
|
return isEqual_c((ivars)self, anObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) isEqualToString: (NSString*)anObject
|
||||||
|
{
|
||||||
|
if (_flags.wide == 1)
|
||||||
|
return isEqual_u((ivars)self, anObject);
|
||||||
|
else
|
||||||
|
return isEqual_c((ivars)self, anObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned int) length
|
- (unsigned int) length
|
||||||
|
@ -2071,9 +2295,15 @@ transmute(ivars self, NSString *aString)
|
||||||
GS_RANGE_CHECK(aRange, _count);
|
GS_RANGE_CHECK(aRange, _count);
|
||||||
|
|
||||||
if (_flags.wide == 1)
|
if (_flags.wide == 1)
|
||||||
return substringFromRange_u((ivars)self, aRange);
|
{
|
||||||
|
return [GSUStringClass stringWithCharacters:
|
||||||
|
self->_contents.u + aRange.location length: aRange.length];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return substringFromRange_c((ivars)self, aRange);
|
{
|
||||||
|
return [GSCStringClass stringWithCString:
|
||||||
|
self->_contents.c + aRange.location length: aRange.length];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private method for Unicode level 3 implementation
|
// private method for Unicode level 3 implementation
|
||||||
|
@ -2246,9 +2476,14 @@ transmute(ivars self, NSString *aString)
|
||||||
{
|
{
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
if (fastIsInstance(anObject) == NO)
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
c = fastClassOfInstance(anObject);
|
c = fastClassOfInstance(anObject);
|
||||||
|
|
||||||
if (c == GSCStringClass || c == NXConstantStringClass
|
if (fastClassIsKindOfClass(c, GSCStringClass) == YES
|
||||||
|
|| c == NXConstantStringClass
|
||||||
|| (c == GSMStringClass && ((ivars)anObject)->_flags.wide == 0))
|
|| (c == GSMStringClass && ((ivars)anObject)->_flags.wide == 0))
|
||||||
{
|
{
|
||||||
ivars other = (ivars)anObject;
|
ivars other = (ivars)anObject;
|
||||||
|
@ -2259,16 +2494,13 @@ transmute(ivars self, NSString *aString)
|
||||||
return NO;
|
return NO;
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
else if (c == GSUStringClass || c == GSMStringClass)
|
else if (fastClassIsKindOfClass(c, GSUStringClass) == YES
|
||||||
|
|| c == GSMStringClass)
|
||||||
{
|
{
|
||||||
if (strCompCsUs(self, anObject, 0, (NSRange){0,_count}) == NSOrderedSame)
|
if (strCompCsUs(self, anObject, 0, (NSRange){0,_count}) == NSOrderedSame)
|
||||||
return YES;
|
return YES;
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
else if (c == nil)
|
|
||||||
{
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
else if (fastClassIsKindOfClass(c, NSStringClass))
|
else if (fastClassIsKindOfClass(c, NSStringClass))
|
||||||
{
|
{
|
||||||
return (*equalImp)(self, equalSel, anObject);
|
return (*equalImp)(self, equalSel, anObject);
|
||||||
|
@ -2291,9 +2523,14 @@ transmute(ivars self, NSString *aString)
|
||||||
{
|
{
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
if (fastIsInstance(anObject) == NO)
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
c = fastClassOfInstance(anObject);
|
c = fastClassOfInstance(anObject);
|
||||||
|
|
||||||
if (c == GSCStringClass || c == NXConstantStringClass
|
if (fastClassIsKindOfClass(c, GSCStringClass) == YES
|
||||||
|
|| c == NXConstantStringClass
|
||||||
|| (c == GSMStringClass && ((ivars)anObject)->_flags.wide == 0))
|
|| (c == GSMStringClass && ((ivars)anObject)->_flags.wide == 0))
|
||||||
{
|
{
|
||||||
ivars other = (ivars)anObject;
|
ivars other = (ivars)anObject;
|
||||||
|
@ -2304,16 +2541,13 @@ transmute(ivars self, NSString *aString)
|
||||||
return NO;
|
return NO;
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
else if (c == GSUStringClass || c == GSMStringClass)
|
else if (fastClassIsKindOfClass(c, GSUStringClass) == YES
|
||||||
|
|| c == GSMStringClass)
|
||||||
{
|
{
|
||||||
if (strCompCsUs(self, anObject, 0, (NSRange){0,_count}) == NSOrderedSame)
|
if (strCompCsUs(self, anObject, 0, (NSRange){0,_count}) == NSOrderedSame)
|
||||||
return YES;
|
return YES;
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
else if (c == nil)
|
|
||||||
{
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
else if (fastClassIsKindOfClass(c, NSStringClass))
|
else if (fastClassIsKindOfClass(c, NSStringClass))
|
||||||
{
|
{
|
||||||
return (*equalImp)(self, equalSel, anObject);
|
return (*equalImp)(self, equalSel, anObject);
|
||||||
|
|
|
@ -354,12 +354,15 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (source[sourceIdx] != format[formatIdx])
|
if (sourceIdx < sourceLen)
|
||||||
{
|
{
|
||||||
NSLog(@"Expected literal '%c' but got '%c'",
|
if (source[sourceIdx] != format[formatIdx])
|
||||||
format[formatIdx], source[sourceIdx]);
|
{
|
||||||
|
NSLog(@"Expected literal '%c' but gmtt '%c'",
|
||||||
|
format[formatIdx], source[sourceIdx]);
|
||||||
|
}
|
||||||
|
sourceIdx++;
|
||||||
}
|
}
|
||||||
sourceIdx++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -371,19 +374,28 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
{
|
{
|
||||||
case '%':
|
case '%':
|
||||||
// skip literal %
|
// skip literal %
|
||||||
if (source[sourceIdx] != '%')
|
if (sourceIdx < sourceLen)
|
||||||
{
|
{
|
||||||
NSLog(@"Expected literal '%' but got '%c'",
|
if (source[sourceIdx] != '%')
|
||||||
source[sourceIdx]);
|
{
|
||||||
|
NSLog(@"Expected literal '%' but got '%c'",
|
||||||
|
source[sourceIdx]);
|
||||||
|
}
|
||||||
|
sourceIdx++;
|
||||||
}
|
}
|
||||||
sourceIdx++;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
// Are Short names three chars in all locales?????
|
// Are Short names three chars in all locales?????
|
||||||
tmpStr[0] = toupper(source[sourceIdx++]);
|
tmpStr[0] = toupper(source[sourceIdx]);
|
||||||
tmpStr[1] = tolower(source[sourceIdx++]);
|
if (sourceIdx < sourceLen)
|
||||||
tmpStr[2] = tolower(source[sourceIdx++]);
|
sourceIdx++;
|
||||||
|
tmpStr[1] = tolower(source[sourceIdx]);
|
||||||
|
if (sourceIdx < sourceLen)
|
||||||
|
sourceIdx++;
|
||||||
|
tmpStr[2] = tolower(source[sourceIdx]);
|
||||||
|
if (sourceIdx < sourceLen)
|
||||||
|
sourceIdx++;
|
||||||
tmpStr[3] = '\0';
|
tmpStr[3] = '\0';
|
||||||
{
|
{
|
||||||
NSString *currDay;
|
NSString *currDay;
|
||||||
|
@ -437,9 +449,15 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
// Are Short names three chars in all locales?????
|
// Are Short names three chars in all locales?????
|
||||||
tmpStr[0] = toupper(source[sourceIdx++]);
|
tmpStr[0] = toupper(source[sourceIdx]);
|
||||||
tmpStr[1] = tolower(source[sourceIdx++]);
|
if (sourceIdx < sourceLen)
|
||||||
tmpStr[2] = tolower(source[sourceIdx++]);
|
sourceIdx++;
|
||||||
|
tmpStr[1] = tolower(source[sourceIdx]);
|
||||||
|
if (sourceIdx < sourceLen)
|
||||||
|
sourceIdx++;
|
||||||
|
tmpStr[2] = tolower(source[sourceIdx]);
|
||||||
|
if (sourceIdx < sourceLen)
|
||||||
|
sourceIdx++;
|
||||||
tmpStr[3] = '\0';
|
tmpStr[3] = '\0';
|
||||||
{
|
{
|
||||||
NSString *currMonth;
|
NSString *currMonth;
|
||||||
|
@ -530,8 +548,12 @@ static inline int getDigits(const char *from, char *to, int limit)
|
||||||
case 'p':
|
case 'p':
|
||||||
// Questionable assumption that all am/pm indicators are 2
|
// Questionable assumption that all am/pm indicators are 2
|
||||||
// characters and in upper case....
|
// characters and in upper case....
|
||||||
tmpStr[0] = toupper(source[sourceIdx++]);
|
tmpStr[0] = toupper(source[sourceIdx]);
|
||||||
tmpStr[1] = toupper(source[sourceIdx++]);
|
if (sourceIdx < sourceLen)
|
||||||
|
sourceIdx++;
|
||||||
|
tmpStr[1] = toupper(source[sourceIdx]);
|
||||||
|
if (sourceIdx < sourceLen)
|
||||||
|
sourceIdx++;
|
||||||
tmpStr[2] = '\0';
|
tmpStr[2] = '\0';
|
||||||
{
|
{
|
||||||
NSString *currAMPM;
|
NSString *currAMPM;
|
||||||
|
|
|
@ -343,15 +343,47 @@ handle_printf_atsign (FILE *stream,
|
||||||
{
|
{
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
{
|
{
|
||||||
unichar *s = NSZoneMalloc(fastZone(self), sizeof(unichar)*length);
|
int i;
|
||||||
|
BOOL isAscii = YES;
|
||||||
|
|
||||||
if (chars != 0)
|
if (chars == 0)
|
||||||
{
|
{
|
||||||
memcpy(s, chars, sizeof(unichar)*length);
|
[NSException raise: NSInvalidArgumentException
|
||||||
|
format: @"nul pointer but non-zero length"];
|
||||||
|
}
|
||||||
|
for (i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
if (chars[i] >= 128)
|
||||||
|
{
|
||||||
|
isAscii = NO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isAscii == YES)
|
||||||
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
s = NSZoneMalloc(fastZone(self), length);
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
s[i] = (unsigned char)chars[i];
|
||||||
|
}
|
||||||
|
self = [self initWithCStringNoCopy: s
|
||||||
|
length: length
|
||||||
|
freeWhenDone: YES];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unichar *s;
|
||||||
|
|
||||||
|
s = NSZoneMalloc(fastZone(self), sizeof(unichar)*length);
|
||||||
|
|
||||||
|
memcpy(s, chars, sizeof(unichar)*length);
|
||||||
|
self = [self initWithCharactersNoCopy: s
|
||||||
|
length: length
|
||||||
|
freeWhenDone: YES];
|
||||||
}
|
}
|
||||||
self = [self initWithCharactersNoCopy: s
|
|
||||||
length: length
|
|
||||||
freeWhenDone: YES];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue