diff options
author | Liang Qi <liang.qi@theqtcompany.com> | 2016-01-26 14:35:50 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@theqtcompany.com> | 2016-01-26 16:27:28 +0100 |
commit | a15c3d086dafea83e4760f0b447be43d26b80697 (patch) | |
tree | fd224a3f83942ff4c432e1e3a3f8583d14d6a11c /src/corelib/tools/qstring.cpp | |
parent | 87abfd351af6309691d921ca0aef077d74df4732 (diff) | |
parent | 397061a6a92db9f962360d5db96f69b315f93074 (diff) |
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts:
src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
src/dbus/qdbusconnection_p.h
src/dbus/qdbusintegrator.cpp
src/dbus/qdbusintegrator_p.h
tests/auto/corelib/io/qdir/qdir.pro
tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp
Change-Id: I3d3fd07aed015c74b1f545f1327aa73d5f365fcc
Diffstat (limited to 'src/corelib/tools/qstring.cpp')
-rw-r--r-- | src/corelib/tools/qstring.cpp | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 9b98f4322b..24d43dad88 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -5733,37 +5733,42 @@ static QString detachAndConvertCase(T &str, QStringIterator it) Q_ASSERT(!str.isEmpty()); QString s = qMove(str); // will copy if T is const QString QChar *pp = s.begin() + it.index(); // will detach if necessary - uint uc = it.nextUnchecked(); - forever { + + do { + uint uc = it.nextUnchecked(); + const QUnicodeTables::Properties *prop = qGetProp(uc); signed short caseDiff = Traits::caseDiff(prop); if (Q_UNLIKELY(Traits::caseSpecial(prop))) { - // slow path: the string is growing const ushort *specialCase = specialCaseMap + caseDiff; ushort length = *specialCase++; - int inpos = it.index() - 1; - int outpos = pp - s.constBegin(); - - s.replace(outpos, 1, reinterpret_cast<const QChar *>(specialCase), length); - pp = const_cast<QChar *>(s.constBegin()) + outpos + length; - - // do we need to adjust the input iterator too? - // if it is pointing to s's data, str is empty - if (str.isEmpty()) - it = QStringIterator(s.constBegin(), inpos + length, s.constEnd()); - } else if (QChar::requiresSurrogates(uc)) { - *pp++ = QChar::highSurrogate(uc + caseDiff); + + if (Q_LIKELY(length == 1)) { + *pp++ = QChar(*specialCase); + } else { + // slow path: the string is growing + int inpos = it.index() - 1; + int outpos = pp - s.constBegin(); + + s.replace(outpos, 1, reinterpret_cast<const QChar *>(specialCase), length); + pp = const_cast<QChar *>(s.constBegin()) + outpos + length; + + // do we need to adjust the input iterator too? + // if it is pointing to s's data, str is empty + if (str.isEmpty()) + it = QStringIterator(s.constBegin(), inpos + length, s.constEnd()); + } + } else if (Q_UNLIKELY(QChar::requiresSurrogates(uc))) { + // so far, case convertion never changes planes (guaranteed by the qunicodetables generator) + pp++; *pp++ = QChar::lowSurrogate(uc + caseDiff); } else { *pp++ = QChar(uc + caseDiff); } + } while (it.hasNext()); - if (!it.hasNext()) - return s; - - uc = it.nextUnchecked(); - } + return s; } template <typename Traits, typename T> @@ -5776,12 +5781,13 @@ static QString convertCase(T &str) while (e != p && e[-1].isHighSurrogate()) --e; - const QUnicodeTables::Properties *prop; QStringIterator it(p, e); - for ( ; it.hasNext(); it.advanceUnchecked()) { - prop = qGetProp(it.peekNextUnchecked()); - if (Traits::caseDiff(prop)) + while (it.hasNext()) { + uint uc = it.nextUnchecked(); + if (Traits::caseDiff(qGetProp(uc))) { + it.recedeUnchecked(); return detachAndConvertCase<Traits>(str, it); + } } return qMove(str); } |