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>
This commit is contained in:
parent
34be7e1625
commit
20faf6408a
@ -4950,31 +4950,51 @@ QString QString::toLower() const
|
|||||||
*/
|
*/
|
||||||
QString QString::toCaseFolded() const
|
QString QString::toCaseFolded() const
|
||||||
{
|
{
|
||||||
if (!d->size)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
const ushort *p = d->data();
|
const ushort *p = d->data();
|
||||||
if (!p)
|
if (!p)
|
||||||
return *this;
|
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;
|
const QUnicodeTables::Properties *prop;
|
||||||
while (p < e) {
|
while (p != e) {
|
||||||
ushort folded = foldCase(*p, last);
|
if (QChar::isHighSurrogate(*p) && QChar::isLowSurrogate(p[1])) {
|
||||||
if (folded != *p) {
|
ushort high = *p++;
|
||||||
QString s(*this);
|
prop = qGetProp(QChar::surrogateToUcs4(high, *p));
|
||||||
s.detach();
|
} else {
|
||||||
ushort *pp = s.d->data() + (p - d->data());
|
prop = qGetProp(*p);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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());
|
||||||
|
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;
|
return s;
|
||||||
}
|
}
|
||||||
p++;
|
++p;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user