mirror of
https://github.com/gnustep/libs-base.git
synced 2025-06-02 01:21:08 +00:00
Attempted workaround for bug in old compilers, plus a fix for converting string
contents to data for a custom string class. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@23291 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
961ec429c4
commit
12b806d369
3 changed files with 50 additions and 160 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2006-08-15 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/GSString.m: substring_c(), substring_u() move structure type
|
||||||
|
declaration out of function to help old (pre-gcc-3) compiler, as
|
||||||
|
suggested by Adam.
|
||||||
|
* Source/NSString: ([dataUsingEncoding:allowLossyConversion:]}
|
||||||
|
replace implementation with call to concrete subclass so that we only
|
||||||
|
have one version of this large, complex method to maintain, as
|
||||||
|
suggested by David.
|
||||||
|
|
||||||
2006-08-14 Richard Frith-Macdonald <rfm@gnu.org>
|
2006-08-14 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/NSKeyedArchiver.m: make a guess at how MacOS-X decides to
|
* Source/NSKeyedArchiver.m: make a guess at how MacOS-X decides to
|
||||||
|
|
|
@ -158,17 +158,20 @@ instance.
|
||||||
@interface GSCSubString : GSCString
|
@interface GSCSubString : GSCString
|
||||||
{
|
{
|
||||||
@public
|
@public
|
||||||
GSCString *_parent;
|
GSString *_parent;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface GSUnicodeSubString : GSUnicodeString
|
@interface GSUnicodeSubString : GSUnicodeString
|
||||||
{
|
{
|
||||||
@public
|
@public
|
||||||
GSUnicodeString *_parent;
|
GSString *_parent;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
@defs(GSCSubString)
|
||||||
|
} GSSubstringStruct;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Include sequence handling code with instructions to generate search
|
* Include sequence handling code with instructions to generate search
|
||||||
|
@ -1304,7 +1307,9 @@ cString_u(GSStr self, NSStringEncoding enc)
|
||||||
tmp = (unichar*)NSZoneMalloc(NSDefaultMallocZone(), (c + 1)*2);
|
tmp = (unichar*)NSZoneMalloc(NSDefaultMallocZone(), (c + 1)*2);
|
||||||
memcpy(tmp, self->_contents.u, c*2);
|
memcpy(tmp, self->_contents.u, c*2);
|
||||||
tmp[c] = 0;
|
tmp[c] = 0;
|
||||||
[NSData dataWithBytesNoCopy: tmp length: (c + 1)*2 freeWhenDone: YES];
|
[NSDataClass dataWithBytesNoCopy: tmp
|
||||||
|
length: (c + 1)*2
|
||||||
|
freeWhenDone: YES];
|
||||||
return (char*)tmp;
|
return (char*)tmp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1496,7 +1501,7 @@ dataUsingEncoding_u(GSStr self, NSStringEncoding encoding, BOOL lossy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [NSData dataWithBytesNoCopy: buff
|
return [NSDataClass dataWithBytesNoCopy: buff
|
||||||
length: sizeof(unichar)*to];
|
length: sizeof(unichar)*to];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2545,9 +2550,7 @@ rangeOfString_u(GSStr self, NSString *aString, unsigned mask, NSRange aRange)
|
||||||
static inline NSString*
|
static inline NSString*
|
||||||
substring_c(GSStr self, NSRange aRange)
|
substring_c(GSStr self, NSRange aRange)
|
||||||
{
|
{
|
||||||
struct {
|
GSSubstringStruct *o;
|
||||||
@defs(GSCSubString)
|
|
||||||
} *o;
|
|
||||||
|
|
||||||
if (aRange.length == 0)
|
if (aRange.length == 0)
|
||||||
{
|
{
|
||||||
|
@ -2567,9 +2570,7 @@ substring_c(GSStr self, NSRange aRange)
|
||||||
static inline NSString*
|
static inline NSString*
|
||||||
substring_u(GSStr self, NSRange aRange)
|
substring_u(GSStr self, NSRange aRange)
|
||||||
{
|
{
|
||||||
struct {
|
GSSubstringStruct *o;
|
||||||
@defs(GSUnicodeSubString)
|
|
||||||
} *o;
|
|
||||||
|
|
||||||
if (aRange.length == 0)
|
if (aRange.length == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -464,11 +464,6 @@ static BOOL _ByteEncodingOk;
|
||||||
static const unichar byteOrderMark = 0xFEFF;
|
static const unichar byteOrderMark = 0xFEFF;
|
||||||
static const unichar byteOrderMarkSwapped = 0xFFFE;
|
static const unichar byteOrderMarkSwapped = 0xFFFE;
|
||||||
|
|
||||||
/* UTF-16 Surrogate Ranges */
|
|
||||||
static NSRange highSurrogateRange = {0xD800, 1024};
|
|
||||||
static NSRange lowSurrogateRange = {0xDC00, 1024};
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_REGISTER_PRINTF_FUNCTION
|
#ifdef HAVE_REGISTER_PRINTF_FUNCTION
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <printf.h>
|
#include <printf.h>
|
||||||
|
@ -2765,161 +2760,45 @@ handle_printf_atsign (FILE *stream,
|
||||||
- (NSData*) dataUsingEncoding: (NSStringEncoding)encoding
|
- (NSData*) dataUsingEncoding: (NSStringEncoding)encoding
|
||||||
allowLossyConversion: (BOOL)flag
|
allowLossyConversion: (BOOL)flag
|
||||||
{
|
{
|
||||||
unsigned int count = 0;
|
unsigned len = [self length];
|
||||||
unsigned int len = [self length];
|
NSData *d;
|
||||||
unichar (*caiImp)(NSString*, SEL, unsigned int);
|
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
return [NSDataClass data];
|
d = [NSDataClass data];
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unichar buf[8192];
|
||||||
|
unichar *u = buf;
|
||||||
|
GSStr_t s;
|
||||||
|
|
||||||
caiImp = (unichar (*)())[self methodForSelector: caiSel];
|
/* Build a fake object on the stack and copy unicode characters
|
||||||
if ((encoding == NSASCIIStringEncoding)
|
* into its buffer from the receiver.
|
||||||
|| (encoding == NSISOLatin1StringEncoding)
|
* We can then use our concrete subclass implementation to do the
|
||||||
|| (encoding == NSISOLatin2StringEncoding)
|
* work of converting to the desired encoding.
|
||||||
|| (encoding == NSNEXTSTEPStringEncoding)
|
|
||||||
|| (encoding == NSNonLossyASCIIStringEncoding)
|
|
||||||
|| (encoding == NSSymbolStringEncoding)
|
|
||||||
|| (encoding == NSISOCyrillicStringEncoding)
|
|
||||||
|| (encoding == NSISOThaiStringEncoding))
|
|
||||||
{
|
|
||||||
unsigned char *buff;
|
|
||||||
|
|
||||||
buff = (unsigned char*)NSZoneMalloc(NSDefaultMallocZone(), len+1);
|
|
||||||
if (!flag)
|
|
||||||
{
|
|
||||||
for (count = 0; count < len; count++)
|
|
||||||
{
|
|
||||||
unichar u = (*caiImp)(self, caiSel, count);
|
|
||||||
unsigned size = 1;
|
|
||||||
unsigned char *dst = buff + count;
|
|
||||||
|
|
||||||
// We know this is a single byte encoding
|
|
||||||
if (GSFromUnicode(&dst, &size, &u, 1, encoding, 0, GSUniStrict)
|
|
||||||
== NO)
|
|
||||||
{
|
|
||||||
NSZoneFree(NSDefaultMallocZone(), buff);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else /* lossy */
|
|
||||||
{
|
|
||||||
for (count = 0; count < len; count++)
|
|
||||||
{
|
|
||||||
unichar u = (*caiImp)(self, caiSel, count);
|
|
||||||
unsigned size = 1;
|
|
||||||
unsigned char *dst = buff + count;
|
|
||||||
|
|
||||||
// We know this is a single byte encoding
|
|
||||||
if (GSFromUnicode(&dst, &size, &u, 1, encoding, 0, 0) == NO)
|
|
||||||
{
|
|
||||||
NSZoneFree(NSDefaultMallocZone(), buff);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buff[count] = '\0';
|
|
||||||
return [NSDataClass dataWithBytesNoCopy: buff length: count];
|
|
||||||
}
|
|
||||||
else if (encoding == NSUTF8StringEncoding)
|
|
||||||
{
|
|
||||||
unsigned char *buff;
|
|
||||||
unsigned i, j;
|
|
||||||
unichar ch, ch2;
|
|
||||||
uint32_t cp;
|
|
||||||
|
|
||||||
buff = (unsigned char *)NSZoneMalloc(NSDefaultMallocZone(), len*3);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Each UTF-16 character maps to at most 3 bytes of UTF-8, so we simply
|
|
||||||
* allocate three times as many bytes as UTF-16 characters, then use
|
|
||||||
* NSZoneRealloc() later to trim the excess. Most Unix virtual memory
|
|
||||||
* implementations allocate address space, and actual memory pages are
|
|
||||||
* not actually allocated until used, so this method shouldn't cause
|
|
||||||
* memory problems on most Unix systems. On other systems, it may prove
|
|
||||||
* advantageous to scan the UTF-16 string to determine the UTF-8 string
|
|
||||||
* length before allocating memory.
|
|
||||||
*/
|
*/
|
||||||
for (i = j = 0; i < len; i++)
|
if (len >= 4096)
|
||||||
{
|
{
|
||||||
ch = (*caiImp)(self, caiSel, i);
|
u = objc_malloc(len * sizeof(unichar));
|
||||||
if (NSLocationInRange(ch, highSurrogateRange) && ((i+1) < len))
|
}
|
||||||
|
[self getCharacters: u];
|
||||||
|
s.isa = GSMutableStringClass;
|
||||||
|
s._zone = 0;
|
||||||
|
s._contents.u = u;
|
||||||
|
s._capacity = len;
|
||||||
|
s._count = len;
|
||||||
|
s._flags.wide = 1;
|
||||||
|
s._flags.free = 0;
|
||||||
|
d = [(NSString*)&s dataUsingEncoding: encoding
|
||||||
|
allowLossyConversion: flag];
|
||||||
|
if (u != buf)
|
||||||
{
|
{
|
||||||
ch2 = (*caiImp)(self, caiSel, i+1);
|
objc_free(u);
|
||||||
if (NSLocationInRange(ch2, lowSurrogateRange))
|
|
||||||
{
|
|
||||||
cp = surrogatePairValue(ch, ch2);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cp = (uint32_t)ch;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cp = (uint32_t)ch;
|
|
||||||
|
|
||||||
if (cp < 0x80)
|
|
||||||
{
|
|
||||||
buff[j++] = cp;
|
|
||||||
}
|
|
||||||
else if (cp < 0x800)
|
|
||||||
{
|
|
||||||
buff[j++] = 0xC0 | ch>>6;
|
|
||||||
buff[j++] = 0x80 | (ch & 0x3F);
|
|
||||||
}
|
|
||||||
else if (cp < 0x10000)
|
|
||||||
{
|
|
||||||
buff[j++] = 0xE0 | ch>>12;
|
|
||||||
buff[j++] = 0x80 | (ch>>6 & 0x3F);
|
|
||||||
buff[j++] = 0x80 | (ch & 0x3F);
|
|
||||||
}
|
|
||||||
else if (cp < 0x200000)
|
|
||||||
{
|
|
||||||
buff[j++] = 0xF0 | ch>>18;
|
|
||||||
buff[j++] = 0x80 | (ch>>12 & 0x3F);
|
|
||||||
buff[j++] = 0x80 | (ch>>6 & 0x3F);
|
|
||||||
buff[j++] = 0x80 | (ch & 0x3F);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return d;
|
||||||
buff = NSZoneRealloc(NSDefaultMallocZone(), buff, j);
|
|
||||||
|
|
||||||
return [NSDataClass dataWithBytesNoCopy: buff
|
|
||||||
length: j];
|
|
||||||
}
|
}
|
||||||
else if (encoding == NSUnicodeStringEncoding)
|
|
||||||
{
|
|
||||||
unichar *buff;
|
|
||||||
|
|
||||||
buff = (unichar*)NSZoneMalloc(NSDefaultMallocZone(),
|
|
||||||
sizeof(unichar)*(len+1));
|
|
||||||
buff[0] = byteOrderMark;
|
|
||||||
[self getCharacters: &buff[1] range: ((NSRange){0, len})];
|
|
||||||
return [NSDataClass dataWithBytesNoCopy: buff
|
|
||||||
length: sizeof(unichar)*(len+1)];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned char *b = 0;
|
|
||||||
unsigned l = 0;
|
|
||||||
unichar *u;
|
|
||||||
|
|
||||||
u = (unichar*)NSZoneMalloc(NSDefaultMallocZone(), len*sizeof(unichar));
|
|
||||||
[self getCharacters: u range: ((NSRange){0, len})];
|
|
||||||
if (GSFromUnicode(&b, &l, u, len, encoding, NSDefaultMallocZone(),
|
|
||||||
(flag == NO) ? GSUniStrict : 0)
|
|
||||||
== NO)
|
|
||||||
{
|
|
||||||
NSZoneFree(NSDefaultMallocZone(), u);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
NSZoneFree(NSDefaultMallocZone(), u);
|
|
||||||
return [NSDataClass dataWithBytesNoCopy: b length: l];
|
|
||||||
}
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the encoding with which this string can be converted without
|
* Returns the encoding with which this string can be converted without
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue