From 46d818df26f3585f9261c735129a606837406875 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 21 Aug 2020 00:47:09 -0400 Subject: [PATCH] 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. --- src/fcstr.c | 86 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 24 deletions(-) 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 @@ FcStrCaseWalkerLong (FcCaseWalker *w, FcChar8 r) } static FcChar8 -FcStrCaseWalkerNext (FcCaseWalker *w, const char *delims) +FcStrCaseWalkerNextNonDelim (FcCaseWalker *w, const char *delims) { FcChar8 r; @@ -182,6 +182,50 @@ FcStrCaseWalkerNext (FcCaseWalker *w, const char *delims) 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 @@ FcStrDowncase (const FcChar8 *s) 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 @@ FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2) for (;;) { - c1 = FcStrCaseWalkerNext (&w1, NULL); - c2 = FcStrCaseWalkerNext (&w2, NULL); + c1 = FcStrCaseWalkerNext (&w1); + c2 = FcStrCaseWalkerNext (&w2); if (!c1 || (c1 != c2)) break; } @@ -223,12 +267,6 @@ FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2) 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 @@ FcStrCmpIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 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 @@ FcStrHashIgnoreCase (const FcChar8 *s) 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 @@ FcStrIsAtIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2) for (;;) { - c1 = FcStrCaseWalkerNext (&w1, " "); - c2 = FcStrCaseWalkerNext (&w2, " "); + c1 = FcStrCaseWalkerNextNonBlank (&w1); + c2 = FcStrCaseWalkerNextNonBlank (&w2); if (!c1 || (c1 != c2)) break; } @@ -356,8 +394,8 @@ FcStrIsAtIgnoreCase (const FcChar8 *s1, const FcChar8 *s2) for (;;) { - c1 = FcStrCaseWalkerNext (&w1, NULL); - c2 = FcStrCaseWalkerNext (&w2, NULL); + c1 = FcStrCaseWalkerNext (&w1); + c2 = FcStrCaseWalkerNext (&w2); if (!c1 || (c1 != c2)) break; } @@ -425,8 +463,8 @@ FcStrMatchIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcCha 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 @@ FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2) 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 @@ FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2) for (;;) { - c1t = FcStrCaseWalkerNext (&w1t, NULL); - c2t = FcStrCaseWalkerNext (&w2t, NULL); + c1t = FcStrCaseWalkerNext (&w1t); + c2t = FcStrCaseWalkerNext (&w2t); if (!c2t) return cur;