Support new MacOS-X unicode string encoding constants.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@26754 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2008-07-11 09:10:46 +00:00
parent b887ac8a7e
commit 49a2c6b3c6
2 changed files with 117 additions and 67 deletions

View file

@ -1,7 +1,8 @@
2008-07-11 Richard Frith-Macdonald <rfm@gnu.org> 2008-07-11 Richard Frith-Macdonald <rfm@gnu.org>
* Source/Additions/Unicode.m: Add support for byte order specific * Source/Additions/Unicode.m: Add support for byte order specific
unicode (including 32bit) via iconv. unicode (including 32bit) via iconv. Change encoding lookup
mechanism to cope with new Mac-OS-X encoding values.
2008-07-06 Richard Frith-Macdonald <rfm@gnu.org> 2008-07-06 Richard Frith-Macdonald <rfm@gnu.org>

View file

@ -85,9 +85,11 @@ typedef struct {unichar from; unsigned char to;} _ucc_;
*/ */
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
#define UNICODE_UTF16 "UTF-16BE" #define UNICODE_UTF16 "UTF-16BE"
#define UNICODE_UTF32 "UTF-32BE"
#define UNICODE_INT "UNICODEBIG" #define UNICODE_INT "UNICODEBIG"
#else #else
#define UNICODE_UTF16 "UTF-16LE" #define UNICODE_UTF16 "UTF-16LE"
#define UNICODE_UTF32 "UTF-32LE"
#define UNICODE_INT "UNICODELITTLE" #define UNICODE_INT "UNICODELITTLE"
#endif #endif
@ -250,16 +252,18 @@ static struct _strenc_ str_encoding_table[] = {
{NSKoreanEUCStringEncoding, {NSKoreanEUCStringEncoding,
"NSKoreanEUCStringEncoding","EUC-KR",0,0,0}, "NSKoreanEUCStringEncoding","EUC-KR",0,0,0},
/* Now Apple encodings which have high numeric values.
*/
{NSUTF16BigEndianStringEncoding, {NSUTF16BigEndianStringEncoding,
"NSUTF16BigEndianStringEncoding","UTF-16BE",0,1,0}, "NSUTF16BigEndianStringEncoding","UTF-16BE",0,0,0},
{NSUTF16LittleEndianStringEncoding, {NSUTF16LittleEndianStringEncoding,
"NSUTF16LittleEndianStringEncoding","UTF-16LE",0,1,0}, "NSUTF16LittleEndianStringEncoding","UTF-16LE",0,0,0},
{NSUTF32StringEncoding, {NSUTF32StringEncoding,
"NSUTF32StringEncoding","",0,1,0}, "NSUTF32StringEncoding",UNICODE_UTF32,0,0,0},
{NSUTF32BigEndianStringEncoding, {NSUTF32BigEndianStringEncoding,
"NSUTF32BigEndianStringEncoding","UTF-32BE",0,1,0}, "NSUTF32BigEndianStringEncoding","UTF-32BE",0,0,0},
{NSUTF32LittleEndianStringEncoding, {NSUTF32LittleEndianStringEncoding,
"NSUTF32LittleEndianStringEncoding","UTF-32LE",0,1,0}, "NSUTF32LittleEndianStringEncoding","UTF-32LE",0,0,0},
{0,"Unknown encoding","",0,0,0} {0,"Unknown encoding","",0,0,0}
}; };
@ -275,8 +279,8 @@ static void GSSetupEncodingTable(void)
if (encodingTable == 0) if (encodingTable == 0)
{ {
static struct _strenc_ **encTable = 0; static struct _strenc_ **encTable = 0;
unsigned count; unsigned count;
unsigned i; unsigned i;
/* /*
* We want to store pointers to our string encoding info in a * We want to store pointers to our string encoding info in a
@ -294,14 +298,12 @@ static void GSSetupEncodingTable(void)
{ {
unsigned tmp = str_encoding_table[i].enc; unsigned tmp = str_encoding_table[i].enc;
if (tmp >= MAX_ENCODING) if (tmp > encTableSize)
{ {
fprintf(stderr, "ERROR ... illegal NSStringEncoding " if (tmp < MAX_ENCODING)
"value in str_encoding_table. Ignored\n"); {
} encTableSize = tmp;
else if (tmp > encTableSize) }
{
encTableSize = tmp;
} }
} }
encTable = objc_malloc((encTableSize+1)*sizeof(struct _strenc_ *)); encTable = objc_malloc((encTableSize+1)*sizeof(struct _strenc_ *));
@ -312,36 +314,37 @@ static void GSSetupEncodingTable(void)
*/ */
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
unsigned tmp = str_encoding_table[i].enc; struct _strenc_ *entry = &str_encoding_table[i];
unsigned tmp = entry->enc;
if (tmp < MAX_ENCODING) if (tmp < MAX_ENCODING)
{ {
encTable[tmp] = &str_encoding_table[i]; encTable[tmp] = entry;
#ifdef HAVE_ICONV
if (encTable[tmp]->iconv != 0 && *(encTable[tmp]->iconv) != 0)
{
iconv_t c;
char *lossy;
/*
* See if we can do a lossy conversion.
*/
lossy = objc_malloc(strlen(encTable[tmp]->iconv) + 12);
strcpy(lossy, encTable[tmp]->iconv);
strcat(lossy, "//TRANSLIT");
c = iconv_open(UNICODE_ENC, encTable[tmp]->iconv);
if (c == (iconv_t)-1)
{
objc_free(lossy);
}
else
{
encTable[tmp]->lossy = lossy;
iconv_close(c);
}
}
#endif
} }
#ifdef HAVE_ICONV
if (entry->iconv != 0 && *(entry->iconv) != 0)
{
iconv_t c;
char *lossy;
/*
* See if we can do a lossy conversion.
*/
lossy = objc_malloc(strlen(entry->iconv) + 12);
strcpy(lossy, entry->iconv);
strcat(lossy, "//TRANSLIT");
c = iconv_open(UNICODE_ENC, entry->iconv);
if (c == (iconv_t)-1)
{
objc_free(lossy);
}
else
{
entry->lossy = lossy;
iconv_close(c);
}
}
#endif
} }
encodingTable = encTable; encodingTable = encTable;
} }
@ -349,61 +352,101 @@ static void GSSetupEncodingTable(void)
} }
} }
BOOL static struct _strenc_ *
GSPrivateIsEncodingSupported(NSStringEncoding enc) EntryForEncoding(NSStringEncoding enc)
{ {
GSSetupEncodingTable(); struct _strenc_ *entry = 0;
if (enc == 0 || enc > encTableSize || encodingTable[enc] == 0) if (enc > 0)
{
GSSetupEncodingTable();
if (enc <= encTableSize)
{
entry = encodingTable[enc];
}
else
{
unsigned i = 0;
while (i < sizeof(str_encoding_table) / sizeof(struct _strenc_))
{
if (str_encoding_table[i].enc == enc)
{
entry = &str_encoding_table[i];
break;
}
i++;
}
}
}
return entry;
}
static struct _strenc_ *
EntrySupported(NSStringEncoding enc)
{
struct _strenc_ *entry = EntryForEncoding(enc);
if (entry == 0)
{ {
return NO; return NO;
} }
#ifdef HAVE_ICONV #ifdef HAVE_ICONV
if (encodingTable[enc]->iconv != 0 && encodingTable[enc]->supported == 0) if (entry->iconv != 0 && entry->supported == 0)
{ {
if (enc == NSUnicodeStringEncoding) if (enc == NSUnicodeStringEncoding)
{ {
encodingTable[enc]->iconv = UNICODE_ENC; entry->iconv = UNICODE_ENC;
encodingTable[enc]->supported = 1; entry->supported = 1;
} }
else if (encodingTable[enc]->iconv[0] == 0) else if (entry->iconv[0] == 0)
{ {
/* explicitly check for empty encoding name since some systems /* explicitly check for empty encoding name since some systems
* have buggy iconv_open() code which succeeds on an empty name. * have buggy iconv_open() code which succeeds on an empty name.
*/ */
encodingTable[enc]->supported = -1; entry->supported = -1;
} }
else else
{ {
iconv_t c; iconv_t c;
c = iconv_open(UNICODE_ENC, encodingTable[enc]->iconv); c = iconv_open(UNICODE_ENC, entry->iconv);
if (c == (iconv_t)-1) if (c == (iconv_t)-1)
{ {
encodingTable[enc]->supported = -1; entry->supported = -1;
} }
else else
{ {
iconv_close(c); iconv_close(c);
c = iconv_open(encodingTable[enc]->iconv, UNICODE_ENC); c = iconv_open(entry->iconv, UNICODE_ENC);
if (c == (iconv_t)-1) if (c == (iconv_t)-1)
{ {
encodingTable[enc]->supported = -1; entry->supported = -1;
} }
else else
{ {
iconv_close(c); iconv_close(c);
encodingTable[enc]->supported = 1; entry->supported = 1;
} }
} }
} }
} }
#endif #endif
if (encodingTable[enc]->supported == 1) if (entry->supported == 1)
{ {
return YES; return entry;
} }
return NO; return 0;
}
BOOL
GSPrivateIsEncodingSupported(NSStringEncoding enc)
{
if (EntrySupported(enc) == 0)
{
return NO;
}
return YES;
} }
/** Returns the NSStringEncoding that matches the specified /** Returns the NSStringEncoding that matches the specified
@ -1091,6 +1134,7 @@ tables:
default: default:
#ifdef HAVE_ICONV #ifdef HAVE_ICONV
{ {
struct _strenc_ *encInfo;
unsigned char *inbuf; unsigned char *inbuf;
unsigned char *outbuf; unsigned char *outbuf;
size_t inbytesleft; size_t inbytesleft;
@ -1100,9 +1144,9 @@ tables:
const char *estr = 0; const char *estr = 0;
BOOL done = NO; BOOL done = NO;
if (GSPrivateIsEncodingSupported(enc) == YES) if ((encInfo = EntrySupported(enc)) != 0)
{ {
estr = encodingTable[enc]->iconv; estr = encInfo->iconv;
} }
/* explicitly check for empty encoding name since some systems /* explicitly check for empty encoding name since some systems
* have buggy iconv_open() code which succeeds on an empty name. * have buggy iconv_open() code which succeeds on an empty name.
@ -1780,6 +1824,7 @@ tables:
#ifdef HAVE_ICONV #ifdef HAVE_ICONV
iconv_start: iconv_start:
{ {
struct _strenc_ *encInfo;
iconv_t cd; iconv_t cd;
unsigned char *inbuf; unsigned char *inbuf;
unsigned char *outbuf; unsigned char *outbuf;
@ -1789,7 +1834,7 @@ iconv_start:
const char *estr = 0; const char *estr = 0;
BOOL done = NO; BOOL done = NO;
if (GSPrivateIsEncodingSupported(enc) == YES) if ((encInfo = EntrySupported(enc)) != 0)
{ {
if (strict == NO) if (strict == NO)
{ {
@ -1797,11 +1842,11 @@ iconv_start:
* Try to transliterate where no direct conversion * Try to transliterate where no direct conversion
* is available. * is available.
*/ */
estr = encodingTable[enc]->lossy; estr = encInfo->lossy;
} }
if (estr == 0) if (estr == 0)
{ {
estr = encodingTable[enc]->iconv; estr = encInfo->iconv;
} }
} }
@ -2209,21 +2254,25 @@ GSPrivateDefaultCStringEncoding()
NSString* NSString*
GSPrivateEncodingName(NSStringEncoding encoding) GSPrivateEncodingName(NSStringEncoding encoding)
{ {
if (GSPrivateIsEncodingSupported(encoding) == NO) struct _strenc_ *encInfo;
if ((encInfo = EntrySupported(encoding)) == NO)
{ {
return @"Unknown encoding"; return @"Unknown encoding";
} }
return [NSString stringWithUTF8String: encodingTable[encoding]->ename]; return [NSString stringWithUTF8String: encInfo->ename];
} }
BOOL BOOL
GSPrivateIsByteEncoding(NSStringEncoding encoding) GSPrivateIsByteEncoding(NSStringEncoding encoding)
{ {
if (GSPrivateIsEncodingSupported(encoding) == NO) struct _strenc_ *encInfo;
if ((encInfo = EntrySupported(encoding)) == NO)
{ {
return NO; return NO;
} }
return encodingTable[encoding]->eightBit; return encInfo->eightBit;
} }
NSStringEncoding NSStringEncoding