summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2011-10-18 19:12:19 +0200
committerQt by Nokia <qt-info@nokia.com>2012-02-21 22:31:00 +0100
commit20faf6408ac193b0bf11acd806f3b2eb52135b5d (patch)
tree81c20f72cef17d17fb8d53562a63ed9cd8c0ad8a /src
parent34be7e16255e7480bd0a8de3326d5173711de5da (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')
-rw-r--r--src/corelib/tools/qstring.cpp52
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;
}