Special-case some of the string walking code

Make variants of FcStrCaseWalkerNext for the two
common cases, delim == NULL and delim == " ", to
speed things up.

These are inner loops, and having the conditions
as simple as possible helps.
This commit is contained in:
Matthias Clasen 2020-08-21 00:47:09 -04:00
parent abbd87ac2c
commit 46d818df26
1 changed files with 62 additions and 24 deletions

View File

@ -160,7 +160,7 @@ FcStrCaseWalkerLong (FcCaseWalker *w, FcChar8 r)
} }
static FcChar8 static FcChar8
FcStrCaseWalkerNext (FcCaseWalker *w, const char *delims) FcStrCaseWalkerNextNonDelim (FcCaseWalker *w, const char *delims)
{ {
FcChar8 r; FcChar8 r;
@ -182,6 +182,50 @@ FcStrCaseWalkerNext (FcCaseWalker *w, const char *delims)
return r; return r;
} }
static FcChar8
FcStrCaseWalkerNextNonBlank (FcCaseWalker *w)
{
FcChar8 r;
if (w->read)
{
if ((r = *w->read++))
return r;
w->read = 0;
}
do
{
r = *w->src++;
} while (r == ' ');
if ((r & 0xc0) == 0xc0)
return FcStrCaseWalkerLong (w, r);
if ('A' <= r && r <= 'Z')
r = r - 'A' + 'a';
return r;
}
static FcChar8
FcStrCaseWalkerNext (FcCaseWalker *w)
{
FcChar8 r;
if (w->read)
{
if ((r = *w->read++))
return r;
w->read = 0;
}
r = *w->src++;
if ((r & 0xc0) == 0xc0)
return FcStrCaseWalkerLong (w, r);
if ('A' <= r && r <= 'Z')
r = r - 'A' + 'a';
return r;
}
FcChar8 * FcChar8 *
FcStrDowncase (const FcChar8 *s) FcStrDowncase (const FcChar8 *s)
{ {
@ -190,13 +234,13 @@ FcStrDowncase (const FcChar8 *s)
FcChar8 *dst, *d; FcChar8 *dst, *d;
FcStrCaseWalkerInit (s, &w); FcStrCaseWalkerInit (s, &w);
while (FcStrCaseWalkerNext (&w, NULL)) while (FcStrCaseWalkerNext (&w))
len++; len++;
d = dst = malloc (len + 1); d = dst = malloc (len + 1);
if (!d) if (!d)
return 0; return 0;
FcStrCaseWalkerInit (s, &w); FcStrCaseWalkerInit (s, &w);
while ((*d++ = FcStrCaseWalkerNext (&w, NULL))); while ((*d++ = FcStrCaseWalkerNext (&w)));
return dst; return dst;
} }
@ -213,8 +257,8 @@ FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;) for (;;)
{ {
c1 = FcStrCaseWalkerNext (&w1, NULL); c1 = FcStrCaseWalkerNext (&w1);
c2 = FcStrCaseWalkerNext (&w2, NULL); c2 = FcStrCaseWalkerNext (&w2);
if (!c1 || (c1 != c2)) if (!c1 || (c1 != c2))
break; break;
} }
@ -223,12 +267,6 @@ FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
int int
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2) FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
{
return FcStrCmpIgnoreCaseAndDelims (s1, s2, (const FcChar8 *)" ");
}
int
FcStrCmpIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *delims)
{ {
FcCaseWalker w1, w2; FcCaseWalker w1, w2;
FcChar8 c1, c2; FcChar8 c1, c2;
@ -240,8 +278,8 @@ FcStrCmpIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8
for (;;) for (;;)
{ {
c1 = FcStrCaseWalkerNext (&w1, (const char *)delims); c1 = FcStrCaseWalkerNextNonBlank (&w1);
c2 = FcStrCaseWalkerNext (&w2, (const char *)delims); c2 = FcStrCaseWalkerNextNonBlank (&w2);
if (!c1 || (c1 != c2)) if (!c1 || (c1 != c2))
break; break;
} }
@ -277,7 +315,7 @@ FcStrHashIgnoreCase (const FcChar8 *s)
FcChar8 c; FcChar8 c;
FcStrCaseWalkerInit (s, &w); FcStrCaseWalkerInit (s, &w);
while ((c = FcStrCaseWalkerNext (&w, NULL))) while ((c = FcStrCaseWalkerNext (&w)))
h = ((h << 3) ^ (h >> 3)) ^ c; h = ((h << 3) ^ (h >> 3)) ^ c;
return h; return h;
} }
@ -297,8 +335,8 @@ FcStrIsAtIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;) for (;;)
{ {
c1 = FcStrCaseWalkerNext (&w1, " "); c1 = FcStrCaseWalkerNextNonBlank (&w1);
c2 = FcStrCaseWalkerNext (&w2, " "); c2 = FcStrCaseWalkerNextNonBlank (&w2);
if (!c1 || (c1 != c2)) if (!c1 || (c1 != c2))
break; break;
} }
@ -356,8 +394,8 @@ FcStrIsAtIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;) for (;;)
{ {
c1 = FcStrCaseWalkerNext (&w1, NULL); c1 = FcStrCaseWalkerNext (&w1);
c2 = FcStrCaseWalkerNext (&w2, NULL); c2 = FcStrCaseWalkerNext (&w2);
if (!c1 || (c1 != c2)) if (!c1 || (c1 != c2))
break; break;
} }
@ -425,8 +463,8 @@ FcStrMatchIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcCha
for (;;) for (;;)
{ {
c1 = FcStrCaseWalkerNext (&w1, (const char *)delims); c1 = FcStrCaseWalkerNextNonDelim (&w1, (const char *)delims);
c2 = FcStrCaseWalkerNext (&w2, (const char *)delims); c2 = FcStrCaseWalkerNextNonDelim (&w2, (const char *)delims);
if (!c1 || (c1 != c2)) if (!c1 || (c1 != c2))
break; break;
} }
@ -493,12 +531,12 @@ FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
FcStrCaseWalkerInit (s1, &w1); FcStrCaseWalkerInit (s1, &w1);
FcStrCaseWalkerInit (s2, &w2); FcStrCaseWalkerInit (s2, &w2);
c2 = FcStrCaseWalkerNext (&w2, NULL); c2 = FcStrCaseWalkerNext (&w2);
for (;;) for (;;)
{ {
cur = w1.src; cur = w1.src;
c1 = FcStrCaseWalkerNext (&w1, NULL); c1 = FcStrCaseWalkerNext (&w1);
if (!c1) if (!c1)
break; break;
if (c1 == c2) if (c1 == c2)
@ -509,8 +547,8 @@ FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;) for (;;)
{ {
c1t = FcStrCaseWalkerNext (&w1t, NULL); c1t = FcStrCaseWalkerNext (&w1t);
c2t = FcStrCaseWalkerNext (&w2t, NULL); c2t = FcStrCaseWalkerNext (&w2t);
if (!c2t) if (!c2t)
return cur; return cur;