optimize QString::toCaseFolded()
authorKonstantin Ritt <ritt.ks@gmail.com>
Tue, 18 Oct 2011 17:12:19 +0000 (19:12 +0200)
committerQt by Nokia <qt-info@nokia.com>
Tue, 21 Feb 2012 21:31:00 +0000 (22:31 +0100)
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>
src/corelib/tools/qstring.cpp

index a141179..5bb8d5a 100644 (file)
@@ -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;
 }