optimise and fix string precision formatting bug.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@23266 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2006-08-13 05:52:48 +00:00
parent b109605b16
commit 8094f44311
2 changed files with 54 additions and 27 deletions

View file

@ -1,3 +1,9 @@
2006-08-13 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSFormat.m: optimise a bit and fix bug where utf8 (and other
multibyte encodings) strings could be truncated at the wrong
precision.
2006-08-12 Richard Frith-Macdonald <rfm@gnu.org> 2006-08-12 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSString.m: getCString_c() call getCString_u() to do the * Source/GSString.m: getCString_c() call getCString_u() to do the

View file

@ -1751,47 +1751,68 @@ NSDictionary *locale)
/* This is complicated. We have to transform the multibyte /* This is complicated. We have to transform the multibyte
string into a unicode string. */ string into a unicode string. */
const char *str = (const char*)string; const char *str = (const char*)string;
unsigned slen; unsigned blen;
NSStringEncoding enc = GetDefEncoding(); static NSStringEncoding enc = GSUndefinedEncoding;
static BOOL byteEncoding = NO;
if (enc == GSUndefinedEncoding)
{
enc = GetDefEncoding();
byteEncoding = GSIsByteEncoding(enc);
}
len = strlen(str); // Number of bytes to convert.
blen = len; // Size of unichar output buffer.
if (prec != -1) if (prec != -1)
{ {
len = (unsigned)prec; if (prec < len)
/*
* If the actual length is less than the precision,
* we use the actual length.
*/
for (slen = 0; slen < len; slen++)
{ {
if (str[slen] == 0) /* We don't neeed an output buffer bigger than the
* precision specifies.
*/
blen = prec;
}
if (byteEncoding == YES)
{
/* Where the external encoding is one byte per character,
* we know we don't need to convert more bytes than the
* precision required for output.
*/
if (prec < len)
{ {
len = slen; len = prec;
} }
} }
} else if (prec * 4 < len)
else {
{ /* We assume no multibyte encoding is going to use more
len = strlen(str); * than the maximum four bytes used by utf-8 for any
* unicode code point. So we do not need to convert
* more than four times the precision.
*/
len = prec * 4;
}
} }
/* Allocate dynamically an array which definitely is long /* Allocate dynamically an array which definitely is long
enough for the wide character version. */ * enough for the unichar version.
if (len < 8192 */
|| ((string = (unichar *) NSZoneMalloc(s->_zone, len * sizeof (unichar))) if (blen < 8192 || ((string = (unichar *)
== NULL)) NSZoneMalloc(s->_zone, blen * sizeof(unichar))) == NULL))
string = (unichar *) alloca (len * sizeof (unichar)); string = (unichar *) alloca (blen * sizeof(unichar));
else else
string_malloced = 1; string_malloced = 1;
for (slen = 0; slen < len; slen++) GSToUnicode(&string, &blen, (unsigned char*)str, len, enc, 0, 0);
{
unsigned int size = 1;
unsigned char c = str[slen];
unichar u = 0;
unichar *dst = &u;
GSToUnicode(&dst, &size, &c, 1, enc, 0, 0); /* get the number of unichars produced and truncate to the
string[slen] = u; * required output precision if necessary.
*/
len = blen;
if (prec != -1 && prec < len)
{
len = prec;
} }
} }
else else