mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-12 00:51:08 +00:00
NSString restructuring and bugfixes
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22924 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
849e0b2af3
commit
60878d7d2c
5 changed files with 579 additions and 952 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2006-05-14 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/NSString.m:
|
||||||
|
* Source/GSString.m:
|
||||||
|
Change to use ([initWithBytesNoCopy:length:encoding:freeWhenDone:])
|
||||||
|
as the primary/designated initialiser for strings and update code
|
||||||
|
to fix character encoding errors when copying mutable strings in
|
||||||
|
a UTF8 locale (ie where the internal encoding for 8bit strings is
|
||||||
|
not the same as the external encoding).
|
||||||
|
WARNING ... this is a restructuring of functionality which is core
|
||||||
|
to the library. Please use with care and report any bugs found.
|
||||||
|
|
||||||
2006-05-12 Richard Frith-Macdonald <rfm@gnu.org>
|
2006-05-12 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/GSString.m: validate UTF-16 data when producing a Cstring
|
* Source/GSString.m: validate UTF-16 data when producing a Cstring
|
||||||
|
|
|
@ -329,7 +329,7 @@ static void GSSetupEncodingTable(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL GSEncodingSupported(NSStringEncoding enc)
|
BOOL GSEncodingSupported(NSStringEncoding enc)
|
||||||
{
|
{
|
||||||
GSSetupEncodingTable();
|
GSSetupEncodingTable();
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -261,14 +261,19 @@ static NSString *ExecutablePath()
|
||||||
really needs it (So far only needed if using GNU dld library) */
|
really needs it (So far only needed if using GNU dld library) */
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
const unichar *
|
const unichar *
|
||||||
#else
|
|
||||||
const char *
|
|
||||||
#endif
|
|
||||||
objc_executable_location (void)
|
objc_executable_location (void)
|
||||||
{
|
{
|
||||||
return [[ExecutablePath() stringByDeletingLastPathComponent]
|
return [[ExecutablePath() stringByDeletingLastPathComponent]
|
||||||
fileSystemRepresentation];
|
fileSystemRepresentation];
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
const char *
|
||||||
|
objc_executable_location (void)
|
||||||
|
{
|
||||||
|
return [[ExecutablePath() stringByDeletingLastPathComponent]
|
||||||
|
fileSystemRepresentation];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
bundle_directory_readable(NSString *path)
|
bundle_directory_readable(NSString *path)
|
||||||
|
|
|
@ -819,7 +819,7 @@ handle_printf_atsign (FILE *stream,
|
||||||
* <p>In MacOS-X class clusters do not have designated initialisers,
|
* <p>In MacOS-X class clusters do not have designated initialisers,
|
||||||
* and there is a general rule that -init is treated as the designated
|
* and there is a general rule that -init is treated as the designated
|
||||||
* initialiser of the class cluster, but that other intitialisers
|
* initialiser of the class cluster, but that other intitialisers
|
||||||
* may not work s expected an would need to be individually overridden
|
* may not work as expected and would need to be individually overridden
|
||||||
* in any subclass.
|
* in any subclass.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>GNUstep tries to make it easier to subclass a class cluster,
|
* <p>GNUstep tries to make it easier to subclass a class cluster,
|
||||||
|
@ -838,6 +838,11 @@ handle_printf_atsign (FILE *stream,
|
||||||
* <em>all</em> the class cluster initialisers you might use in conjunction
|
* <em>all</em> the class cluster initialisers you might use in conjunction
|
||||||
* with your subclass.
|
* with your subclass.
|
||||||
* </p>
|
* </p>
|
||||||
|
* <p>NB. The GNUstep designated initialiser for the NSString class cluster
|
||||||
|
* has changed to -initWithBytesNoCopy:length:encoding:freeWhenDone:
|
||||||
|
* from -initWithCharactersNoCopy:length:freeWhenDone: and older code
|
||||||
|
* subclassing NSString will need to be updated.
|
||||||
|
* </p>
|
||||||
*/
|
*/
|
||||||
- (id) init
|
- (id) init
|
||||||
{
|
{
|
||||||
|
@ -859,147 +864,24 @@ handle_printf_atsign (FILE *stream,
|
||||||
{
|
{
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
{
|
{
|
||||||
self = [self initWithCharactersNoCopy: (unichar*)0
|
return [self initWithBytesNoCopy: (const void *)0
|
||||||
length: 0
|
length: 0
|
||||||
freeWhenDone: NO];
|
encoding: encoding
|
||||||
}
|
freeWhenDone: NO];
|
||||||
else if (_ByteEncodingOk == YES
|
|
||||||
&& (encoding==_DefaultStringEncoding || encoding==NSASCIIStringEncoding))
|
|
||||||
{
|
|
||||||
self = [self initWithCString: bytes
|
|
||||||
length: length];
|
|
||||||
}
|
|
||||||
else if (encoding == NSUTF8StringEncoding)
|
|
||||||
{
|
|
||||||
unsigned char *b = (unsigned char*)bytes;
|
|
||||||
unsigned i = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the data begins with the UTF8 Byte Order Marker (as a
|
|
||||||
* signature for UTF8 data) we must remove it.
|
|
||||||
*/
|
|
||||||
if (length > 2 && b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF)
|
|
||||||
{
|
|
||||||
length -= 3;
|
|
||||||
bytes += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_ByteEncodingOk)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If it's ok to store ascii strings as internal C strings,
|
|
||||||
* check to see if we have in fact got an ascii string.
|
|
||||||
*/
|
|
||||||
while (i < length)
|
|
||||||
{
|
|
||||||
if (b[i] > 127)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == length)
|
|
||||||
{
|
|
||||||
self = [self initWithCString: bytes length: length];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unichar *u = 0;
|
|
||||||
unsigned int l = 0;
|
|
||||||
|
|
||||||
if (GSToUnicode(&u, &l, bytes, length, NSUTF8StringEncoding,
|
|
||||||
GSObjCZone(self), 0) == NO)
|
|
||||||
{
|
|
||||||
DESTROY(self);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: u
|
|
||||||
length: l
|
|
||||||
freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (encoding == NSUnicodeStringEncoding)
|
|
||||||
{
|
|
||||||
if (length%2 != 0)
|
|
||||||
{
|
|
||||||
DESTROY(self); // Not valid unicode data.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BOOL swapped = NO;
|
|
||||||
unsigned char *b;
|
|
||||||
unichar *uptr;
|
|
||||||
|
|
||||||
b = (unsigned char*)bytes;
|
|
||||||
uptr = (unichar*)b;
|
|
||||||
if (*uptr == byteOrderMark)
|
|
||||||
{
|
|
||||||
b = (unsigned char*)++uptr;
|
|
||||||
length -= sizeof(unichar);
|
|
||||||
}
|
|
||||||
else if (*uptr == byteOrderMarkSwapped)
|
|
||||||
{
|
|
||||||
b = (unsigned char*)++uptr;
|
|
||||||
length -= sizeof(unichar);
|
|
||||||
swapped = YES;
|
|
||||||
}
|
|
||||||
if (length == 0)
|
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: (unichar*)0
|
|
||||||
length: 0
|
|
||||||
freeWhenDone: NO];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned char *u;
|
|
||||||
|
|
||||||
u = (unsigned char*)NSZoneMalloc(GSObjCZone(self), length);
|
|
||||||
if (swapped == YES)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < length; i += 2)
|
|
||||||
{
|
|
||||||
u[i] = b[i + 1];
|
|
||||||
u[i + 1] = b[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(u, b, length);
|
|
||||||
}
|
|
||||||
self = [self initWithCharactersNoCopy: (unichar*)u
|
|
||||||
length: length/2
|
|
||||||
freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned char *b;
|
void *buf = NSZoneMalloc(GSObjCZone(self), length);
|
||||||
unichar *u = 0;
|
|
||||||
unsigned l = 0;
|
|
||||||
|
|
||||||
b = (unsigned char*)bytes;
|
memcpy(buf, bytes, length);
|
||||||
if (GSToUnicode(&u, &l, b, length, encoding, GSObjCZone(self), 0) == NO)
|
return [self initWithBytesNoCopy: buf
|
||||||
{
|
length: length
|
||||||
DESTROY(self);
|
encoding: encoding
|
||||||
}
|
freeWhenDone: YES];
|
||||||
else
|
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: u
|
|
||||||
length: l
|
|
||||||
freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** <init /> <override-subclass />
|
||||||
* Initialises the receiver with the supplied length of bytes, using the
|
* Initialises the receiver with the supplied length of bytes, using the
|
||||||
* specified encoding.<br />
|
* specified encoding.<br />
|
||||||
* For NSUnicodeStringEncoding and NSUTF8String encoding, a Byte Order
|
* For NSUnicodeStringEncoding and NSUTF8String encoding, a Byte Order
|
||||||
|
@ -1010,194 +892,32 @@ handle_printf_atsign (FILE *stream,
|
||||||
* needed.<br />
|
* needed.<br />
|
||||||
* If the data can not be interpreted using the encoding, the receiver
|
* If the data can not be interpreted using the encoding, the receiver
|
||||||
* is released and nil is returned.
|
* is released and nil is returned.
|
||||||
|
* <p>Note, this is the most basic initialiser for strings.
|
||||||
|
* In the GNUstep implementation, your subclasses may override
|
||||||
|
* this initialiser in order to have all others function.</p>
|
||||||
*/
|
*/
|
||||||
- (id) initWithBytesNoCopy: (const void*)bytes
|
- (id) initWithBytesNoCopy: (const void*)bytes
|
||||||
length: (unsigned int)length
|
length: (unsigned int)length
|
||||||
encoding: (NSStringEncoding)encoding
|
encoding: (NSStringEncoding)encoding
|
||||||
freeWhenDone: (BOOL)flag
|
freeWhenDone: (BOOL)flag
|
||||||
{
|
{
|
||||||
BOOL bytesNeeded = NO;
|
self = [self init];
|
||||||
|
|
||||||
if (flag == NO)
|
|
||||||
{
|
|
||||||
bytesNeeded = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length == 0)
|
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: (unichar*)0
|
|
||||||
length: 0
|
|
||||||
freeWhenDone: NO];
|
|
||||||
}
|
|
||||||
else if (_ByteEncodingOk == YES
|
|
||||||
&& (encoding==_DefaultStringEncoding || encoding==NSASCIIStringEncoding))
|
|
||||||
{
|
|
||||||
self = [self initWithCStringNoCopy: (void*)bytes
|
|
||||||
length: length
|
|
||||||
freeWhenDone: YES];
|
|
||||||
bytesNeeded = YES;
|
|
||||||
}
|
|
||||||
else if (encoding == NSUTF8StringEncoding)
|
|
||||||
{
|
|
||||||
unsigned char *b =(unsigned char*)bytes;
|
|
||||||
unsigned i = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the data begins with the UTF8 Byte Order Marker (as a
|
|
||||||
* signature for UTF8 data) we must remove it.
|
|
||||||
*/
|
|
||||||
if (length > 2 && b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF)
|
|
||||||
{
|
|
||||||
length -= 3;
|
|
||||||
bytes += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_ByteEncodingOk)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If it's ok to store ascii strings as internal C strings,
|
|
||||||
* check to see if we have in fact got an ascii string.
|
|
||||||
*/
|
|
||||||
while (i < length)
|
|
||||||
{
|
|
||||||
if (b[i] > 127)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == length)
|
|
||||||
{
|
|
||||||
self = [self initWithCString: bytes length: length];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unichar *u = 0;
|
|
||||||
unsigned int l = 0;
|
|
||||||
|
|
||||||
if (GSToUnicode(&u, &l, bytes, length, NSUTF8StringEncoding,
|
|
||||||
GSObjCZone(self), 0) == NO)
|
|
||||||
{
|
|
||||||
DESTROY(self);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: u
|
|
||||||
length: l
|
|
||||||
freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (encoding == NSUnicodeStringEncoding)
|
|
||||||
{
|
|
||||||
if (length%2 != 0)
|
|
||||||
{
|
|
||||||
DESTROY(self); // Not valid unicode data.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BOOL swapped = NO;
|
|
||||||
BOOL copy = NO;
|
|
||||||
unsigned char *b;
|
|
||||||
unichar *uptr;
|
|
||||||
|
|
||||||
b = (unsigned char*)bytes;
|
|
||||||
uptr = (unichar*)b;
|
|
||||||
if (*uptr == byteOrderMark)
|
|
||||||
{
|
|
||||||
b = (unsigned char*)++uptr;
|
|
||||||
length -= sizeof(unichar);
|
|
||||||
copy = YES;
|
|
||||||
flag = YES;
|
|
||||||
}
|
|
||||||
else if (*uptr == byteOrderMarkSwapped)
|
|
||||||
{
|
|
||||||
b = (unsigned char*)++uptr;
|
|
||||||
length -= sizeof(unichar);
|
|
||||||
swapped = YES;
|
|
||||||
copy = YES;
|
|
||||||
flag = YES;
|
|
||||||
}
|
|
||||||
if (length == 0)
|
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: (unichar*)0
|
|
||||||
length: 0
|
|
||||||
freeWhenDone: NO];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned char *u;
|
|
||||||
|
|
||||||
if (copy == YES)
|
|
||||||
{
|
|
||||||
u = (unsigned char*)NSZoneMalloc(GSObjCZone(self), length);
|
|
||||||
if (swapped == YES)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < length; i += 2)
|
|
||||||
{
|
|
||||||
u[i] = b[i + 1];
|
|
||||||
u[i + 1] = b[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(u, b, length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
u = (unsigned char *)bytes;
|
|
||||||
bytesNeeded = YES;
|
|
||||||
}
|
|
||||||
self = [self initWithCharactersNoCopy: (unichar*)u
|
|
||||||
length: length/2
|
|
||||||
freeWhenDone: flag];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned char *b;
|
|
||||||
unichar *u = 0;
|
|
||||||
unsigned l = 0;
|
|
||||||
|
|
||||||
b = (unsigned char*)bytes;
|
|
||||||
if (GSToUnicode(&u, &l, b, length, encoding, GSObjCZone(self), 0) == NO)
|
|
||||||
{
|
|
||||||
DESTROY(self);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: u
|
|
||||||
length: l
|
|
||||||
freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (bytesNeeded == NO && bytes != 0)
|
|
||||||
{
|
|
||||||
NSZoneFree(NSZoneFromPointer((void*)bytes), (void*)bytes);
|
|
||||||
}
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** <init /> <override-subclass />
|
/**
|
||||||
* <p>Initialize with given unicode chars up to length, regardless of presence
|
* <p>Initialize with given unicode chars up to length, regardless of presence
|
||||||
* of null bytes. Does not copy the string. If flag, frees its storage when
|
* of null bytes. Does not copy the string. If flag, frees its storage when
|
||||||
* this instance is deallocated.</p>
|
* this instance is deallocated.</p>
|
||||||
* <p>Note, this is the most basic initialiser for unicode strings.
|
|
||||||
* In the GNUstep implementation, your subclasses may override
|
|
||||||
* this initialiser in order to have all others function.</p>
|
|
||||||
*/
|
*/
|
||||||
- (id) initWithCharactersNoCopy: (unichar*)chars
|
- (id) initWithCharactersNoCopy: (unichar*)chars
|
||||||
length: (unsigned int)length
|
length: (unsigned int)length
|
||||||
freeWhenDone: (BOOL)flag
|
freeWhenDone: (BOOL)flag
|
||||||
{
|
{
|
||||||
self = [self init];
|
return [self initWithBytesNoCopy: chars
|
||||||
return self;
|
length: length * sizeof(unichar)
|
||||||
|
encoding: NSUnicodeStringEncoding
|
||||||
|
freeWhenDone: flag];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1207,58 +927,9 @@ handle_printf_atsign (FILE *stream,
|
||||||
- (id) initWithCharacters: (const unichar*)chars
|
- (id) initWithCharacters: (const unichar*)chars
|
||||||
length: (unsigned int)length
|
length: (unsigned int)length
|
||||||
{
|
{
|
||||||
if (length > 0)
|
return [self initWithBytes: chars
|
||||||
{
|
length: length * sizeof(unichar)
|
||||||
unsigned int i;
|
encoding: NSUnicodeStringEncoding];
|
||||||
BOOL isAscii = YES;
|
|
||||||
|
|
||||||
if (chars == 0)
|
|
||||||
{
|
|
||||||
[NSException raise: NSInvalidArgumentException
|
|
||||||
format: @"null 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(GSObjCZone(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(GSObjCZone(self), sizeof(unichar)*length);
|
|
||||||
|
|
||||||
memcpy(s, chars, sizeof(unichar)*length);
|
|
||||||
self = [self initWithCharactersNoCopy: s
|
|
||||||
length: length
|
|
||||||
freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: (unichar*)0
|
|
||||||
length: 0
|
|
||||||
freeWhenDone: NO];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1271,23 +942,10 @@ handle_printf_atsign (FILE *stream,
|
||||||
length: (unsigned int)length
|
length: (unsigned int)length
|
||||||
freeWhenDone: (BOOL)flag
|
freeWhenDone: (BOOL)flag
|
||||||
{
|
{
|
||||||
unichar *buf = 0;
|
return [self initWithBytesNoCopy: byteString
|
||||||
unsigned int l = 0;
|
length: length
|
||||||
|
encoding: _DefaultStringEncoding
|
||||||
if (GSToUnicode(&buf, &l, (unsigned char*)byteString, length,
|
freeWhenDone: flag];
|
||||||
_DefaultStringEncoding, [self zone], 0) == NO)
|
|
||||||
{
|
|
||||||
DESTROY(self);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (flag == YES && byteString != 0)
|
|
||||||
{
|
|
||||||
NSZoneFree(NSZoneFromPointer(byteString), byteString);
|
|
||||||
}
|
|
||||||
self = [self initWithCharactersNoCopy: buf length: l freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1310,22 +968,9 @@ handle_printf_atsign (FILE *stream,
|
||||||
*/
|
*/
|
||||||
- (id) initWithCString: (const char*)byteString length: (unsigned int)length
|
- (id) initWithCString: (const char*)byteString length: (unsigned int)length
|
||||||
{
|
{
|
||||||
if (length > 0)
|
return [self initWithBytes: byteString
|
||||||
{
|
length: length
|
||||||
char *s = NSZoneMalloc(GSObjCZone(self), length);
|
encoding: _DefaultStringEncoding];
|
||||||
|
|
||||||
if (byteString != 0)
|
|
||||||
{
|
|
||||||
memcpy(s, byteString, length);
|
|
||||||
}
|
|
||||||
self = [self initWithCStringNoCopy: s length: length freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self = [self initWithCStringNoCopy: 0 length: 0 freeWhenDone: NO];
|
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1335,8 +980,9 @@ handle_printf_atsign (FILE *stream,
|
||||||
*/
|
*/
|
||||||
- (id) initWithCString: (const char*)byteString
|
- (id) initWithCString: (const char*)byteString
|
||||||
{
|
{
|
||||||
return [self initWithCString: byteString
|
return [self initWithBytes: byteString
|
||||||
length: (byteString ? strlen(byteString) : 0)];
|
length: (byteString ? strlen(byteString) : 0)
|
||||||
|
encoding: _DefaultStringEncoding];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1369,66 +1015,9 @@ handle_printf_atsign (FILE *stream,
|
||||||
*/
|
*/
|
||||||
- (id) initWithUTF8String: (const char *)bytes
|
- (id) initWithUTF8String: (const char *)bytes
|
||||||
{
|
{
|
||||||
unsigned length = 0;
|
return [self initWithBytes: bytes
|
||||||
|
length: (bytes ? strlen(bytes) : 0)
|
||||||
if (bytes == NULL)
|
encoding: NSUTF8StringEncoding];
|
||||||
{
|
|
||||||
NSDebugMLog(@"bytes is NULL");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = strlen(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length > 0)
|
|
||||||
{
|
|
||||||
unsigned i = 0;
|
|
||||||
|
|
||||||
if (_ByteEncodingOk)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If it's ok to store ascii strings as internal C strings,
|
|
||||||
* check to see if we have in fact got an ascii string.
|
|
||||||
*/
|
|
||||||
while (i < length)
|
|
||||||
{
|
|
||||||
if (((unsigned char*)bytes)[i] > 127)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == length)
|
|
||||||
{
|
|
||||||
self = [self initWithCString: bytes length: length];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unichar *u = 0;
|
|
||||||
unsigned int l = 0;
|
|
||||||
|
|
||||||
if (GSToUnicode(&u, &l, (unsigned char*)bytes, length,
|
|
||||||
NSUTF8StringEncoding, GSObjCZone(self), 0) == NO)
|
|
||||||
{
|
|
||||||
DESTROY(self);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: u
|
|
||||||
length: l
|
|
||||||
freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: (unichar*)0
|
|
||||||
length: 0
|
|
||||||
freeWhenDone: NO];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1551,155 +1140,9 @@ handle_printf_atsign (FILE *stream,
|
||||||
- (id) initWithData: (NSData*)data
|
- (id) initWithData: (NSData*)data
|
||||||
encoding: (NSStringEncoding)encoding
|
encoding: (NSStringEncoding)encoding
|
||||||
{
|
{
|
||||||
unsigned len = [data length];
|
return [self initWithBytes: [data bytes]
|
||||||
|
length: [data length]
|
||||||
if (len == 0)
|
encoding: encoding];
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: (unichar*)0
|
|
||||||
length: 0
|
|
||||||
freeWhenDone: NO];
|
|
||||||
}
|
|
||||||
else if (_ByteEncodingOk == YES
|
|
||||||
&& (encoding==_DefaultStringEncoding || encoding==NSASCIIStringEncoding))
|
|
||||||
{
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We can only create an internal C string if the default C string
|
|
||||||
* encoding is Ok, and the specified encoding matches it.
|
|
||||||
*/
|
|
||||||
s = NSZoneMalloc(GSObjCZone(self), len);
|
|
||||||
[data getBytes: s];
|
|
||||||
self = [self initWithCStringNoCopy: s length: len freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
else if (encoding == NSUTF8StringEncoding)
|
|
||||||
{
|
|
||||||
const unsigned char *bytes = [data bytes];
|
|
||||||
unsigned i = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the data begins with the UTF8 Byte Order Marker (as a
|
|
||||||
* signature for UTF8 data) we must remove it.
|
|
||||||
*/
|
|
||||||
if (len > 2 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF)
|
|
||||||
{
|
|
||||||
len -= 3;
|
|
||||||
bytes += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_ByteEncodingOk)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If it's ok to store ascii strings as internal C strings,
|
|
||||||
* check to see if we have in fact got an ascii string.
|
|
||||||
*/
|
|
||||||
while (i < len)
|
|
||||||
{
|
|
||||||
if ((bytes)[i] > 127)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == len)
|
|
||||||
{
|
|
||||||
self = [self initWithCString: (char*)bytes length: len];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unichar *u = 0;
|
|
||||||
unsigned int l = 0;
|
|
||||||
|
|
||||||
if (GSToUnicode(&u, &l, bytes, len, NSUTF8StringEncoding,
|
|
||||||
GSObjCZone(self), 0) == NO)
|
|
||||||
{
|
|
||||||
DESTROY(self);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: u
|
|
||||||
length: l
|
|
||||||
freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (encoding == NSUnicodeStringEncoding)
|
|
||||||
{
|
|
||||||
if (len%2 != 0)
|
|
||||||
{
|
|
||||||
DESTROY(self); // Not valid unicode data.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BOOL swapped = NO;
|
|
||||||
unsigned char *b;
|
|
||||||
unichar *uptr;
|
|
||||||
|
|
||||||
b = (unsigned char*)[data bytes];
|
|
||||||
uptr = (unichar*)b;
|
|
||||||
if (*uptr == byteOrderMark)
|
|
||||||
{
|
|
||||||
b = (unsigned char*)++uptr;
|
|
||||||
len -= sizeof(unichar);
|
|
||||||
}
|
|
||||||
else if (*uptr == byteOrderMarkSwapped)
|
|
||||||
{
|
|
||||||
b = (unsigned char*)++uptr;
|
|
||||||
len -= sizeof(unichar);
|
|
||||||
swapped = YES;
|
|
||||||
}
|
|
||||||
if (len == 0)
|
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: (unichar*)0
|
|
||||||
length: 0
|
|
||||||
freeWhenDone: NO];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned char *u;
|
|
||||||
|
|
||||||
u = (unsigned char*)NSZoneMalloc(GSObjCZone(self), len);
|
|
||||||
if (swapped == YES)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i += 2)
|
|
||||||
{
|
|
||||||
u[i] = b[i + 1];
|
|
||||||
u[i + 1] = b[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(u, b, len);
|
|
||||||
}
|
|
||||||
self = [self initWithCharactersNoCopy: (unichar*)u
|
|
||||||
length: len/2
|
|
||||||
freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned char *b;
|
|
||||||
unichar *u = 0;
|
|
||||||
unsigned l = 0;
|
|
||||||
|
|
||||||
b = (unsigned char*)[data bytes];
|
|
||||||
if (GSToUnicode(&u, &l, b, len, encoding, GSObjCZone(self), 0) == NO)
|
|
||||||
{
|
|
||||||
DESTROY(self);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self = [self initWithCharactersNoCopy: u
|
|
||||||
length: l
|
|
||||||
freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5053,49 +4496,26 @@ static NSFileManager *fm = nil;
|
||||||
length: count
|
length: count
|
||||||
freeWhenDone: YES];
|
freeWhenDone: YES];
|
||||||
}
|
}
|
||||||
else if (enc == NSASCIIStringEncoding
|
|
||||||
|| enc == _DefaultStringEncoding)
|
|
||||||
{
|
|
||||||
char *chars;
|
|
||||||
|
|
||||||
chars = NSZoneMalloc(zone, count+1);
|
|
||||||
[aCoder decodeArrayOfObjCType: @encode(unsigned char)
|
|
||||||
count: count
|
|
||||||
at: chars];
|
|
||||||
self = [self initWithCStringNoCopy: chars
|
|
||||||
length: count
|
|
||||||
freeWhenDone: YES];
|
|
||||||
}
|
|
||||||
else if (enc == NSUTF8StringEncoding)
|
|
||||||
{
|
|
||||||
unsigned char *chars;
|
|
||||||
|
|
||||||
chars = NSZoneMalloc(zone, count+1);
|
|
||||||
[aCoder decodeArrayOfObjCType: @encode(unsigned char)
|
|
||||||
count: count
|
|
||||||
at: chars];
|
|
||||||
chars[count] = '\0';
|
|
||||||
self = [self initWithUTF8String: (char*)chars];
|
|
||||||
NSZoneFree(zone, chars);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned char *chars;
|
unsigned char *chars;
|
||||||
NSData *data;
|
|
||||||
|
|
||||||
chars = NSZoneMalloc(zone, count);
|
chars = NSZoneMalloc(zone, count+1);
|
||||||
[aCoder decodeArrayOfObjCType: @encode(unsigned char)
|
[aCoder decodeArrayOfObjCType: @encode(unsigned char)
|
||||||
count: count
|
count: count
|
||||||
at: chars];
|
at: chars];
|
||||||
data = [NSDataClass allocWithZone: zone];
|
self = [self initWithBytesNoCopy: chars
|
||||||
data = [data initWithBytesNoCopy: chars length: count];
|
length: count
|
||||||
self = [self initWithData: data encoding: enc];
|
encoding: enc
|
||||||
RELEASE(data);
|
freeWhenDone: YES];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self = [self initWithCStringNoCopy: "" length: 0 freeWhenDone: NO];
|
self = [self initWithBytesNoCopy: ""
|
||||||
|
length: 0
|
||||||
|
encoding: NSASCIIStringEncoding
|
||||||
|
freeWhenDone: NO];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|
Loading…
Reference in a new issue