mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 16:30:41 +00:00
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:
parent
8be710069a
commit
667b539a1b
3 changed files with 104 additions and 64 deletions
|
@ -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>
|
2002-08-27 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/Additions/GSXML.m: Integrated GSXPath code by Nicola Pero
|
* Source/Additions/GSXML.m: Integrated GSXPath code by Nicola Pero
|
||||||
|
|
155
Source/Unicode.m
155
Source/Unicode.m
|
@ -113,11 +113,14 @@ struct _strenc_ {
|
||||||
* and the first 128 are identical to
|
* and the first 128 are identical to
|
||||||
* the ASCII character set.
|
* the ASCII character set.
|
||||||
*/
|
*/
|
||||||
BOOL supported; /* Is this supported? Some encodings
|
char supported; /* Is this supported? Some encodings
|
||||||
* have builtin conversion to/from
|
* have builtin conversion to/from
|
||||||
* unicode, but for others we must
|
* unicode, but for others we must
|
||||||
* check with iconv to see if it
|
* check with iconv to see if it
|
||||||
* supports them on this platform.
|
* 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 struct _strenc_ **encodingTable = 0;
|
||||||
static unsigned encTableSize = 0;
|
static unsigned encTableSize = 0;
|
||||||
|
|
||||||
NSStringEncoding *GetAvailableEncodings()
|
static void GSSetupEncodingTable()
|
||||||
{
|
{
|
||||||
if (_availableEncodings == 0)
|
if (encodingTable == 0)
|
||||||
{
|
{
|
||||||
[gnustep_global_lock lock];
|
[gnustep_global_lock lock];
|
||||||
if (_availableEncodings == 0)
|
if (encodingTable == 0)
|
||||||
{
|
{
|
||||||
NSStringEncoding *encodings;
|
static struct _strenc_ **encTable = 0;
|
||||||
unsigned count;
|
unsigned count;
|
||||||
unsigned pos;
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -207,8 +209,8 @@ NSStringEncoding *GetAvailableEncodings()
|
||||||
encTableSize = tmp;
|
encTableSize = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
encodingTable = malloc((encTableSize+1)*sizeof(struct _strenc_ *));
|
encTable = malloc((encTableSize+1)*sizeof(struct _strenc_ *));
|
||||||
memset(encodingTable, 0, (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.
|
* Now set up the pointers at the correct location in the table.
|
||||||
|
@ -219,65 +221,91 @@ NSStringEncoding *GetAvailableEncodings()
|
||||||
|
|
||||||
if (tmp < MAX_ENCODING)
|
if (tmp < MAX_ENCODING)
|
||||||
{
|
{
|
||||||
encodingTable[tmp] = &str_encoding_table[i];
|
encTable[tmp] = &str_encoding_table[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
encodingTable = encTable;
|
||||||
|
}
|
||||||
|
[gnustep_global_lock unlock];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL GSEncodingSupported(NSStringEncoding enc)
|
||||||
|
{
|
||||||
|
GSSetupEncodingTable();
|
||||||
|
|
||||||
|
if (enc == 0 || enc > encTableSize || encodingTable[enc] == 0)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iconv_t c;
|
||||||
|
|
||||||
|
c = iconv_open(UNICODE_ENC, encodingTable[enc]->iconv);
|
||||||
|
if (c == (iconv_t)-1)
|
||||||
|
{
|
||||||
|
encodingTable[enc]->supported = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iconv_close(c);
|
||||||
|
c = iconv_open(encodingTable[enc]->iconv, UNICODE_ENC);
|
||||||
|
if (c == (iconv_t)-1)
|
||||||
|
{
|
||||||
|
encodingTable[enc]->supported = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iconv_close(c);
|
||||||
|
encodingTable[enc]->supported = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
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
|
* Now build up a list of supported encodings ... in the
|
||||||
* format needed to support [NSStirng+availableStringEncodings]
|
* format needed to support [NSString+availableStringEncodings]
|
||||||
* Check to see what iconv support we have as we go along.
|
* Check to see what iconv support we have as we go along.
|
||||||
* This is also the palce where we determine the name we use
|
* This is also the place where we determine the name we use
|
||||||
* for iconv to support unicode.
|
* for iconv to support unicode.
|
||||||
*/
|
*/
|
||||||
encodings = objc_malloc(sizeof(NSStringEncoding) * count);
|
GSSetupEncodingTable();
|
||||||
|
encodings = objc_malloc(sizeof(NSStringEncoding) * encTableSize);
|
||||||
pos = 0;
|
pos = 0;
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < encTableSize; i++)
|
||||||
{
|
{
|
||||||
NSStringEncoding enc = str_encoding_table[i].enc;
|
if (GSEncodingSupported(i) == YES)
|
||||||
|
|
||||||
if (enc == 0 || enc >= MAX_ENCODING)
|
|
||||||
{
|
{
|
||||||
continue;
|
encodings[pos++] = i;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_ICONV
|
|
||||||
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;
|
|
||||||
|
|
||||||
c = iconv_open(UNICODE_ENC, encodingTable[enc]->iconv);
|
|
||||||
if (c == (iconv_t)-1)
|
|
||||||
{
|
|
||||||
continue; // Can't convert to unicode
|
|
||||||
}
|
|
||||||
iconv_close(c);
|
|
||||||
c = iconv_open(encodingTable[enc]->iconv, UNICODE_ENC);
|
|
||||||
if (c == (iconv_t)-1)
|
|
||||||
{
|
|
||||||
continue; // Can't convert from unicode
|
|
||||||
}
|
|
||||||
iconv_close(c);
|
|
||||||
encodingTable[enc]->supported = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (encodingTable[enc]->supported == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
encodings[pos++] = enc;
|
|
||||||
}
|
}
|
||||||
encodings[pos] = 0;
|
encodings[pos] = 0;
|
||||||
_availableEncodings = encodings;
|
_availableEncodings = encodings;
|
||||||
|
@ -287,6 +315,9 @@ NSStringEncoding *GetAvailableEncodings()
|
||||||
return _availableEncodings;
|
return _availableEncodings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the default encoding
|
||||||
|
*/
|
||||||
NSStringEncoding
|
NSStringEncoding
|
||||||
GetDefEncoding()
|
GetDefEncoding()
|
||||||
{
|
{
|
||||||
|
@ -294,7 +325,6 @@ GetDefEncoding()
|
||||||
{
|
{
|
||||||
char *encoding;
|
char *encoding;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
NSStringEncoding *availableEncodings;
|
|
||||||
|
|
||||||
[gnustep_global_lock lock];
|
[gnustep_global_lock lock];
|
||||||
if (defEnc != GSUndefinedEncoding)
|
if (defEnc != GSUndefinedEncoding)
|
||||||
|
@ -303,7 +333,7 @@ GetDefEncoding()
|
||||||
return defEnc;
|
return defEnc;
|
||||||
}
|
}
|
||||||
|
|
||||||
availableEncodings = GetAvailableEncodings();
|
GSSetupEncodingTable();
|
||||||
|
|
||||||
encoding = getenv("GNUSTEP_STRING_ENCODING");
|
encoding = getenv("GNUSTEP_STRING_ENCODING");
|
||||||
if (encoding != 0)
|
if (encoding != 0)
|
||||||
|
@ -317,7 +347,7 @@ GetDefEncoding()
|
||||||
if (str_encoding_table[count].enc)
|
if (str_encoding_table[count].enc)
|
||||||
{
|
{
|
||||||
defEnc = 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 "
|
fprintf(stderr, "WARNING: %s - encoding not implemented as "
|
||||||
"default c string encoding.\n", encoding);
|
"default c string encoding.\n", encoding);
|
||||||
|
@ -350,8 +380,7 @@ GetDefEncoding()
|
||||||
BOOL
|
BOOL
|
||||||
GSIsByteEncoding(NSStringEncoding encoding)
|
GSIsByteEncoding(NSStringEncoding encoding)
|
||||||
{
|
{
|
||||||
GetAvailableEncodings();
|
if (GSEncodingSupported(encoding) == NO)
|
||||||
if (encoding == 0 || encoding > encTableSize || encodingTable[encoding] == 0)
|
|
||||||
{
|
{
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
@ -361,8 +390,7 @@ GSIsByteEncoding(NSStringEncoding encoding)
|
||||||
NSString*
|
NSString*
|
||||||
GSEncodingName(NSStringEncoding encoding)
|
GSEncodingName(NSStringEncoding encoding)
|
||||||
{
|
{
|
||||||
GetAvailableEncodings();
|
if (GSEncodingSupported(encoding) == NO)
|
||||||
if (encoding == 0 || encoding > encTableSize || encodingTable[encoding] == 0)
|
|
||||||
{
|
{
|
||||||
return @"Unknown encoding";
|
return @"Unknown encoding";
|
||||||
}
|
}
|
||||||
|
@ -378,8 +406,7 @@ GetEncodingName(NSStringEncoding encoding)
|
||||||
static const char *
|
static const char *
|
||||||
iconv_stringforencoding(NSStringEncoding encoding)
|
iconv_stringforencoding(NSStringEncoding encoding)
|
||||||
{
|
{
|
||||||
GetAvailableEncodings();
|
if (GSEncodingSupported(encoding) == NO)
|
||||||
if (encoding == 0 || encoding > encTableSize || encodingTable[encoding] == 0)
|
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ int main()
|
||||||
NSString *us2 = [NSString stringWithCharacters: u2 length: 7];
|
NSString *us2 = [NSString stringWithCharacters: u2 length: 7];
|
||||||
NSMutableString *fo = [NSMutableString stringWithString: @"abcdef"];
|
NSMutableString *fo = [NSMutableString stringWithString: @"abcdef"];
|
||||||
NSMutableString *f1 = [NSMutableString stringWithString: @"ab"];
|
NSMutableString *f1 = [NSMutableString stringWithString: @"ab"];
|
||||||
|
NSStringEncoding *encs;
|
||||||
|
|
||||||
NS_DURING
|
NS_DURING
|
||||||
[fo replaceCharactersInRange: [fo rangeOfString: @"xx"] withString: us1];
|
[fo replaceCharactersInRange: [fo rangeOfString: @"xx"] withString: us1];
|
||||||
|
@ -98,6 +99,10 @@ int main()
|
||||||
for (i = 0; i < 1000; i++)
|
for (i = 0; i < 1000; i++)
|
||||||
[base appendString: want];
|
[base appendString: want];
|
||||||
print_string(base);
|
print_string(base);
|
||||||
|
|
||||||
|
encs = [NSString availableStringEncodings];
|
||||||
|
while (*encs != 0)
|
||||||
|
printf("Encoding %x\n", *encs++);
|
||||||
}
|
}
|
||||||
[arp release];
|
[arp release];
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue