Use a binary search to find the range containing a character in
RuneRange arrays. This is much faster when there are hundreds of ranges (as is the case in UTF-8 locales) and was inspired by a similar change made by Apple in Darwin.
This commit is contained in:
parent
b17e85fede
commit
45a11576f3
@ -44,21 +44,25 @@ unsigned long
|
|||||||
___runetype(c)
|
___runetype(c)
|
||||||
__ct_rune_t c;
|
__ct_rune_t c;
|
||||||
{
|
{
|
||||||
int x;
|
size_t lim;
|
||||||
_RuneRange *rr = &_CurrentRuneLocale->runetype_ext;
|
_RuneRange *rr = &_CurrentRuneLocale->runetype_ext;
|
||||||
_RuneEntry *re = rr->ranges;
|
_RuneEntry *base, *re;
|
||||||
|
|
||||||
if (c < 0 || c == EOF)
|
if (c < 0 || c == EOF)
|
||||||
return(0L);
|
return(0L);
|
||||||
|
|
||||||
for (x = 0; x < rr->nranges; ++x, ++re) {
|
/* Binary search -- see bsearch.c for explanation. */
|
||||||
if (c < re->min)
|
base = rr->ranges;
|
||||||
return(0L);
|
for (lim = rr->nranges; lim != 0; lim >>= 1) {
|
||||||
if (c <= re->max) {
|
re = base + (lim >> 1);
|
||||||
|
if (re->min <= c && c <= re->max) {
|
||||||
if (re->types)
|
if (re->types)
|
||||||
return(re->types[c - re->min]);
|
return(re->types[c - re->min]);
|
||||||
else
|
else
|
||||||
return(re->map);
|
return(re->map);
|
||||||
|
} else if (c > re->max) {
|
||||||
|
base = re + 1;
|
||||||
|
lim--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,18 +44,23 @@ __ct_rune_t
|
|||||||
___tolower(c)
|
___tolower(c)
|
||||||
__ct_rune_t c;
|
__ct_rune_t c;
|
||||||
{
|
{
|
||||||
int x;
|
size_t lim;
|
||||||
_RuneRange *rr = &_CurrentRuneLocale->maplower_ext;
|
_RuneRange *rr = &_CurrentRuneLocale->maplower_ext;
|
||||||
_RuneEntry *re = rr->ranges;
|
_RuneEntry *base, *re;
|
||||||
|
|
||||||
if (c < 0 || c == EOF)
|
if (c < 0 || c == EOF)
|
||||||
return(c);
|
return(c);
|
||||||
|
|
||||||
for (x = 0; x < rr->nranges; ++x, ++re) {
|
/* Binary search -- see bsearch.c for explanation. */
|
||||||
if (c < re->min)
|
base = rr->ranges;
|
||||||
return(c);
|
for (lim = rr->nranges; lim != 0; lim >>= 1) {
|
||||||
if (c <= re->max)
|
re = base + (lim >> 1);
|
||||||
return(re->map + c - re->min);
|
if (re->min <= c && c <= re->max)
|
||||||
|
return (re->map + c - re->min);
|
||||||
|
else if (c > re->max) {
|
||||||
|
base = re + 1;
|
||||||
|
lim--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(c);
|
return(c);
|
||||||
|
@ -44,18 +44,23 @@ __ct_rune_t
|
|||||||
___toupper(c)
|
___toupper(c)
|
||||||
__ct_rune_t c;
|
__ct_rune_t c;
|
||||||
{
|
{
|
||||||
int x;
|
size_t lim;
|
||||||
_RuneRange *rr = &_CurrentRuneLocale->mapupper_ext;
|
_RuneRange *rr = &_CurrentRuneLocale->mapupper_ext;
|
||||||
_RuneEntry *re = rr->ranges;
|
_RuneEntry *base, *re;
|
||||||
|
|
||||||
if (c < 0 || c == EOF)
|
if (c < 0 || c == EOF)
|
||||||
return(c);
|
return(c);
|
||||||
|
|
||||||
for (x = 0; x < rr->nranges; ++x, ++re) {
|
/* Binary search -- see bsearch.c for explanation. */
|
||||||
if (c < re->min)
|
base = rr->ranges;
|
||||||
return(c);
|
for (lim = rr->nranges; lim != 0; lim >>= 1) {
|
||||||
if (c <= re->max)
|
re = base + (lim >> 1);
|
||||||
return(re->map + c - re->min);
|
if (re->min <= c && c <= re->max)
|
||||||
|
return (re->map + c - re->min);
|
||||||
|
else if (c > re->max) {
|
||||||
|
base = re + 1;
|
||||||
|
lim--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(c);
|
return(c);
|
||||||
|
Loading…
Reference in New Issue
Block a user