diff options
author | Konstantin Ritt <ritt.ks@gmail.com> | 2011-10-18 19:12:19 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-21 22:31:00 +0100 |
commit | 20faf6408ac193b0bf11acd806f3b2eb52135b5d (patch) | |
tree | 81c20f72cef17d17fb8d53562a63ed9cd8c0ad8a /src/corelib/tools/qstring.cpp | |
parent | 34be7e16255e7480bd0a8de3326d5173711de5da (diff) |
optimize QString::toCaseFolded()
use the codepath similar to QString::toLower()
Change-Id: Ica1948c5e9c82199307d9f823e07d42b50d59480
Merge-request: 70
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
Reviewed-by: Olivier
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib/tools/qstring.cpp')
-rw-r--r-- | src/corelib/tools/qstring.cpp | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index a14117923e..5bb8d5a5a1 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -4950,31 +4950,51 @@ QString QString::toLower() const */ QString QString::toCaseFolded() const { - if (!d->size) - return *this; - const ushort *p = d->data(); if (!p) return *this; - const ushort *e = d->data() + d->size; + const ushort *e = p + d->size; + // this avoids out of bounds check in the loop + while (e != p && QChar::isHighSurrogate(*(e - 1))) + --e; - uint last = 0; - while (p < e) { - ushort folded = foldCase(*p, last); - if (folded != *p) { - QString s(*this); - s.detach(); + const QUnicodeTables::Properties *prop; + while (p != e) { + if (QChar::isHighSurrogate(*p) && QChar::isLowSurrogate(p[1])) { + ushort high = *p++; + prop = qGetProp(QChar::surrogateToUcs4(high, *p)); + } else { + prop = qGetProp(*p); + } + if (prop->caseFoldDiff || prop->caseFoldSpecial) { + if (QChar::isLowSurrogate(*p)) + --p; // safe; diff is 0 for surrogates + QString s(d->size, Qt::Uninitialized); + memcpy(s.d->data(), d->data(), (p - d->data())*sizeof(ushort)); ushort *pp = s.d->data() + (p - d->data()); - const ushort *ppe = s.d->data() + s.d->size; - last = pp > s.d->data() ? *(pp - 1) : 0; - while (pp < ppe) { - *pp = foldCase(*pp, last); - ++pp; + while (p != e) { + if (QChar::isHighSurrogate(*p) && QChar::isLowSurrogate(p[1])) { + *pp = *p++; + prop = qGetProp(QChar::surrogateToUcs4(*pp++, *p)); + } else { + prop = qGetProp(*p); + } + if (prop->caseFoldSpecial) { + //### we currently don't support full case foldings + } else { + *pp++ = *p + prop->caseFoldDiff; + } + ++p; } + + // this restores high surrogate parts eaten above, if any + while (e != d->data() + d->size) + *pp++ = *e++; + return s; } - p++; + ++p; } return *this; } |