summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qstring.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qstring.cpp')
-rw-r--r--src/corelib/tools/qstring.cpp84
1 files changed, 51 insertions, 33 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index ca34096ec5..a14117923e 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -4071,6 +4071,7 @@ QString QString::simplified() const
if (from == fromEnd)
goto done;
} while (!ch.isSpace());
+
}
done:
*to++ = ch;
@@ -4891,29 +4892,33 @@ QString QString::toLower() const
const ushort *p = d->data();
if (!p)
return *this;
- if (!d->size)
- return *this;
- const ushort *e = d->data() + d->size;
-
- // this avoids one out of bounds check in the loop
- if (QChar(*p).isLowSurrogate())
- ++p;
+ const ushort *e = p + d->size;
+ // this avoids out of bounds check in the loop
+ while (e != p && QChar::isHighSurrogate(*(e - 1)))
+ --e;
+ const QUnicodeTables::Properties *prop;
while (p != e) {
- uint c = *p;
- if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
- c = QChar::surrogateToUcs4(*(p - 1), c);
- const QUnicodeTables::Properties *prop = qGetProp(c);
+ if (QChar::isHighSurrogate(*p) && QChar::isLowSurrogate(p[1])) {
+ ushort high = *p++;
+ prop = qGetProp(QChar::surrogateToUcs4(high, *p));
+ } else {
+ prop = qGetProp(*p);
+ }
if (prop->lowerCaseDiff || prop->lowerCaseSpecial) {
+ 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) {
- uint c = *p;
- if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
- c = QChar::surrogateToUcs4(*(p - 1), c);
- prop = qGetProp(c);
+ 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->lowerCaseSpecial) {
int pos = pp - s.d->data();
s.resize(s.d->size + SPECIAL_CASE_MAX_LEN);
@@ -4926,6 +4931,11 @@ QString QString::toLower() const
}
++p;
}
+
+ // this restores high surrogate parts eaten above, if any
+ while (e != d->data() + d->size)
+ *pp++ = *e++;
+
s.truncate(pp - s.d->data());
return s;
}
@@ -4979,35 +4989,38 @@ QString QString::toCaseFolded() const
\sa toLower(), QLocale::toLower()
*/
-
QString QString::toUpper() const
{
const ushort *p = d->data();
if (!p)
return *this;
- if (!d->size)
- return *this;
- const ushort *e = d->data() + d->size;
-
- // this avoids one out of bounds check in the loop
- if (QChar(*p).isLowSurrogate())
- ++p;
+ const ushort *e = p + d->size;
+ // this avoids out of bounds check in the loop
+ while (e != p && QChar::isHighSurrogate(*(e - 1)))
+ --e;
+ const QUnicodeTables::Properties *prop;
while (p != e) {
- uint c = *p;
- if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
- c = QChar::surrogateToUcs4(*(p - 1), c);
- const QUnicodeTables::Properties *prop = qGetProp(c);
+ if (QChar::isHighSurrogate(*p) && QChar::isLowSurrogate(p[1])) {
+ ushort high = *p++;
+ prop = qGetProp(QChar::surrogateToUcs4(high, *p));
+ } else {
+ prop = qGetProp(*p);
+ }
if (prop->upperCaseDiff || prop->upperCaseSpecial) {
+ 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) {
- uint c = *p;
- if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
- c = QChar::surrogateToUcs4(*(p - 1), c);
- prop = qGetProp(c);
+ 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->upperCaseSpecial) {
int pos = pp - s.d->data();
s.resize(s.d->size + SPECIAL_CASE_MAX_LEN);
@@ -5020,6 +5033,11 @@ QString QString::toUpper() const
}
++p;
}
+
+ // this restores high surrogate parts eaten above, if any
+ while (e != d->data() + d->size)
+ *pp++ = *e++;
+
s.truncate(pp - s.d->data());
return s;
}