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.
diff --git a/src/fcstr.c b/src/fcstr.c
index 864d4aa..39ecbbb 100644
--- a/src/fcstr.c
+++ b/src/fcstr.c
@@ -160,7 +160,7 @@
}
static FcChar8
-FcStrCaseWalkerNext (FcCaseWalker *w, const char *delims)
+FcStrCaseWalkerNextNonDelim (FcCaseWalker *w, const char *delims)
{
FcChar8 r;
@@ -182,6 +182,50 @@
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 *
FcStrDowncase (const FcChar8 *s)
{
@@ -190,13 +234,13 @@
FcChar8 *dst, *d;
FcStrCaseWalkerInit (s, &w);
- while (FcStrCaseWalkerNext (&w, NULL))
+ while (FcStrCaseWalkerNext (&w))
len++;
d = dst = malloc (len + 1);
if (!d)
return 0;
FcStrCaseWalkerInit (s, &w);
- while ((*d++ = FcStrCaseWalkerNext (&w, NULL)));
+ while ((*d++ = FcStrCaseWalkerNext (&w)));
return dst;
}
@@ -213,8 +257,8 @@
for (;;)
{
- c1 = FcStrCaseWalkerNext (&w1, NULL);
- c2 = FcStrCaseWalkerNext (&w2, NULL);
+ c1 = FcStrCaseWalkerNext (&w1);
+ c2 = FcStrCaseWalkerNext (&w2);
if (!c1 || (c1 != c2))
break;
}
@@ -224,12 +268,6 @@
int
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;
FcChar8 c1, c2;
@@ -240,8 +278,8 @@
for (;;)
{
- c1 = FcStrCaseWalkerNext (&w1, (const char *)delims);
- c2 = FcStrCaseWalkerNext (&w2, (const char *)delims);
+ c1 = FcStrCaseWalkerNextNonBlank (&w1);
+ c2 = FcStrCaseWalkerNextNonBlank (&w2);
if (!c1 || (c1 != c2))
break;
}
@@ -277,7 +315,7 @@
FcChar8 c;
FcStrCaseWalkerInit (s, &w);
- while ((c = FcStrCaseWalkerNext (&w, NULL)))
+ while ((c = FcStrCaseWalkerNext (&w)))
h = ((h << 3) ^ (h >> 3)) ^ c;
return h;
}
@@ -297,8 +335,8 @@
for (;;)
{
- c1 = FcStrCaseWalkerNext (&w1, " ");
- c2 = FcStrCaseWalkerNext (&w2, " ");
+ c1 = FcStrCaseWalkerNextNonBlank (&w1);
+ c2 = FcStrCaseWalkerNextNonBlank (&w2);
if (!c1 || (c1 != c2))
break;
}
@@ -356,8 +394,8 @@
for (;;)
{
- c1 = FcStrCaseWalkerNext (&w1, NULL);
- c2 = FcStrCaseWalkerNext (&w2, NULL);
+ c1 = FcStrCaseWalkerNext (&w1);
+ c2 = FcStrCaseWalkerNext (&w2);
if (!c1 || (c1 != c2))
break;
}
@@ -425,8 +463,8 @@
for (;;)
{
- c1 = FcStrCaseWalkerNext (&w1, (const char *)delims);
- c2 = FcStrCaseWalkerNext (&w2, (const char *)delims);
+ c1 = FcStrCaseWalkerNextNonDelim (&w1, (const char *)delims);
+ c2 = FcStrCaseWalkerNextNonDelim (&w2, (const char *)delims);
if (!c1 || (c1 != c2))
break;
}
@@ -493,12 +531,12 @@
FcStrCaseWalkerInit (s1, &w1);
FcStrCaseWalkerInit (s2, &w2);
- c2 = FcStrCaseWalkerNext (&w2, NULL);
+ c2 = FcStrCaseWalkerNext (&w2);
for (;;)
{
cur = w1.src;
- c1 = FcStrCaseWalkerNext (&w1, NULL);
+ c1 = FcStrCaseWalkerNext (&w1);
if (!c1)
break;
if (c1 == c2)
@@ -509,8 +547,8 @@
for (;;)
{
- c1t = FcStrCaseWalkerNext (&w1t, NULL);
- c2t = FcStrCaseWalkerNext (&w2t, NULL);
+ c1t = FcStrCaseWalkerNext (&w1t);
+ c2t = FcStrCaseWalkerNext (&w2t);
if (!c2t)
return cur;