Improve startup time by doing lazy checks for available encodings.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@14359 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2002-08-28 13:41:54 +00:00
parent 8be710069a
commit 667b539a1b
3 changed files with 104 additions and 64 deletions

View file

@ -1,3 +1,11 @@
2002-08-28 Richard Frith-Macdonald <rfm@gnu.org>
* Source/Unicode.m: Rewritten the way that iconv is used to decide
upon the available encodings ... lazy evaluation so that we don't
try to lookup an encoding until we have to. This should improve
process startup time (especially in gdb) since the iconv operations
seem to be very slow.
2002-08-27 Richard Frith-Macdonald <rfm@gnu.org>
* Source/Additions/GSXML.m: Integrated GSXPath code by Nicola Pero

View file

@ -113,11 +113,14 @@ struct _strenc_ {
* and the first 128 are identical to
* the ASCII character set.
*/
BOOL supported; /* Is this supported? Some encodings
char supported; /* Is this supported? Some encodings
* have builtin conversion to/from
* unicode, but for others we must
* check with iconv to see if it
* supports them on this platform.
* A one means supported.
* A negative means unsupported.
* A zero means not yet checked.
*/
};
@ -169,16 +172,15 @@ static struct _strenc_ str_encoding_table[] = {
static struct _strenc_ **encodingTable = 0;
static unsigned encTableSize = 0;
NSStringEncoding *GetAvailableEncodings()
static void GSSetupEncodingTable()
{
if (_availableEncodings == 0)
if (encodingTable == 0)
{
[gnustep_global_lock lock];
if (_availableEncodings == 0)
if (encodingTable == 0)
{
NSStringEncoding *encodings;
static struct _strenc_ **encTable = 0;
unsigned count;
unsigned pos;
unsigned i;
/*
@ -207,8 +209,8 @@ NSStringEncoding *GetAvailableEncodings()
encTableSize = tmp;
}
}
encodingTable = malloc((encTableSize+1)*sizeof(struct _strenc_ *));
memset(encodingTable, 0, (encTableSize+1)*sizeof(struct _strenc_ *));
encTable = malloc((encTableSize+1)*sizeof(struct _strenc_ *));
memset(encTable, 0, (encTableSize+1)*sizeof(struct _strenc_ *));
/*
* Now set up the pointers at the correct location in the table.
@ -219,39 +221,31 @@ NSStringEncoding *GetAvailableEncodings()
if (tmp < MAX_ENCODING)
{
encodingTable[tmp] = &str_encoding_table[i];
encTable[tmp] = &str_encoding_table[i];
}
}
encodingTable = encTable;
}
[gnustep_global_lock unlock];
}
}
/*
* Now build up a list of supported encodings ... in the
* format needed to support [NSStirng+availableStringEncodings]
* Check to see what iconv support we have as we go along.
* This is also the palce where we determine the name we use
* for iconv to support unicode.
*/
encodings = objc_malloc(sizeof(NSStringEncoding) * count);
pos = 0;
for (i = 0; i < count; i++)
static BOOL GSEncodingSupported(NSStringEncoding enc)
{
NSStringEncoding enc = str_encoding_table[i].enc;
GSSetupEncodingTable();
if (enc == 0 || enc >= MAX_ENCODING)
if (enc == 0 || enc > encTableSize || encodingTable[enc] == 0)
{
continue;
return NO;
}
#ifdef HAVE_ICONV
if (encodingTable[enc]->iconv != 0 && encodingTable[enc]->supported == 0)
{
if (enc == NSUnicodeStringEncoding)
{
encodingTable[enc]->iconv = UNICODE_ENC;
encodingTable[enc]->supported = 1;
}
if (encodingTable[enc]->supported == 0)
{
if (encodingTable[enc]->iconv == 0)
{
continue; // Not handled by iconv.
}
else
{
iconv_t c;
@ -259,25 +253,59 @@ NSStringEncoding *GetAvailableEncodings()
c = iconv_open(UNICODE_ENC, encodingTable[enc]->iconv);
if (c == (iconv_t)-1)
{
continue; // Can't convert to unicode
encodingTable[enc]->supported = -1;
}
else
{
iconv_close(c);
c = iconv_open(encodingTable[enc]->iconv, UNICODE_ENC);
if (c == (iconv_t)-1)
{
continue; // Can't convert from unicode
encodingTable[enc]->supported = -1;
}
else
{
iconv_close(c);
encodingTable[enc]->supported = 1;
}
}
#else
if (encodingTable[enc]->supported == 0)
{
continue;
}
}
#endif
encodings[pos++] = enc;
if (encodingTable[enc]->supported == 1)
{
return YES;
}
return NO;
}
NSStringEncoding *GetAvailableEncodings()
{
if (_availableEncodings == 0)
{
[gnustep_global_lock lock];
if (_availableEncodings == 0)
{
NSStringEncoding *encodings;
unsigned pos;
unsigned i;
/*
* Now build up a list of supported encodings ... in the
* format needed to support [NSString+availableStringEncodings]
* Check to see what iconv support we have as we go along.
* This is also the place where we determine the name we use
* for iconv to support unicode.
*/
GSSetupEncodingTable();
encodings = objc_malloc(sizeof(NSStringEncoding) * encTableSize);
pos = 0;
for (i = 0; i < encTableSize; i++)
{
if (GSEncodingSupported(i) == YES)
{
encodings[pos++] = i;
}
}
encodings[pos] = 0;
_availableEncodings = encodings;
@ -287,6 +315,9 @@ NSStringEncoding *GetAvailableEncodings()
return _availableEncodings;
}
/**
* Return the default encoding
*/
NSStringEncoding
GetDefEncoding()
{
@ -294,7 +325,6 @@ GetDefEncoding()
{
char *encoding;
unsigned int count;
NSStringEncoding *availableEncodings;
[gnustep_global_lock lock];
if (defEnc != GSUndefinedEncoding)
@ -303,7 +333,7 @@ GetDefEncoding()
return defEnc;
}
availableEncodings = GetAvailableEncodings();
GSSetupEncodingTable();
encoding = getenv("GNUSTEP_STRING_ENCODING");
if (encoding != 0)
@ -317,7 +347,7 @@ GetDefEncoding()
if (str_encoding_table[count].enc)
{
defEnc = str_encoding_table[count].enc;
if (str_encoding_table[count].supported == 0)
if (GSEncodingSupported(defEnc) == NO)
{
fprintf(stderr, "WARNING: %s - encoding not implemented as "
"default c string encoding.\n", encoding);
@ -350,8 +380,7 @@ GetDefEncoding()
BOOL
GSIsByteEncoding(NSStringEncoding encoding)
{
GetAvailableEncodings();
if (encoding == 0 || encoding > encTableSize || encodingTable[encoding] == 0)
if (GSEncodingSupported(encoding) == NO)
{
return NO;
}
@ -361,8 +390,7 @@ GSIsByteEncoding(NSStringEncoding encoding)
NSString*
GSEncodingName(NSStringEncoding encoding)
{
GetAvailableEncodings();
if (encoding == 0 || encoding > encTableSize || encodingTable[encoding] == 0)
if (GSEncodingSupported(encoding) == NO)
{
return @"Unknown encoding";
}
@ -378,8 +406,7 @@ GetEncodingName(NSStringEncoding encoding)
static const char *
iconv_stringforencoding(NSStringEncoding encoding)
{
GetAvailableEncodings();
if (encoding == 0 || encoding > encTableSize || encodingTable[encoding] == 0)
if (GSEncodingSupported(encoding) == NO)
{
return "";
}

View file

@ -32,6 +32,7 @@ int main()
NSString *us2 = [NSString stringWithCharacters: u2 length: 7];
NSMutableString *fo = [NSMutableString stringWithString: @"abcdef"];
NSMutableString *f1 = [NSMutableString stringWithString: @"ab"];
NSStringEncoding *encs;
NS_DURING
[fo replaceCharactersInRange: [fo rangeOfString: @"xx"] withString: us1];
@ -98,6 +99,10 @@ int main()
for (i = 0; i < 1000; i++)
[base appendString: want];
print_string(base);
encs = [NSString availableStringEncodings];
while (*encs != 0)
printf("Encoding %x\n", *encs++);
}
[arp release];
exit(0);