diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/arch/qatomic_armv5.h | 8 | ||||
-rw-r--r-- | src/corelib/codecs/qicucodec.cpp | 3 | ||||
-rw-r--r-- | src/corelib/global/qlogging.cpp | 87 | ||||
-rw-r--r-- | src/corelib/global/qnamespace.h | 2 | ||||
-rw-r--r-- | src/corelib/global/qnamespace.qdoc | 2 | ||||
-rw-r--r-- | src/corelib/io/qabstractfileengine_p.h | 6 | ||||
-rw-r--r-- | src/corelib/kernel/qobject_p.h | 77 | ||||
-rw-r--r-- | src/corelib/plugin/qlibrary.cpp | 11 | ||||
-rw-r--r-- | src/corelib/plugin/qlibrary_p.h | 2 | ||||
-rw-r--r-- | src/corelib/tools/qcryptographichash.cpp | 60 | ||||
-rw-r--r-- | src/corelib/tools/qstring.cpp | 15 |
11 files changed, 223 insertions, 50 deletions
diff --git a/src/corelib/arch/qatomic_armv5.h b/src/corelib/arch/qatomic_armv5.h index 445379a99c..92e2b02e5b 100644 --- a/src/corelib/arch/qatomic_armv5.h +++ b/src/corelib/arch/qatomic_armv5.h @@ -163,12 +163,20 @@ __asm T QBasicAtomicOps<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL template<> template <typename T> inline T QBasicAtomicOps<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW { +#if defined(__thumb__) + register T originalValue; + do { + originalValue = _q_value; + } while (_q_cmpxchg(originalValue, newValue, &_q_value) != 0); + return originalValue; +#else T originalValue; asm volatile("swp %0,%2,[%3]" : "=&r"(originalValue), "=m" (_q_value) : "r"(newValue), "r"(&_q_value) : "cc", "memory"); return originalValue; +#endif } #endif // Q_CC_RVCT diff --git a/src/corelib/codecs/qicucodec.cpp b/src/corelib/codecs/qicucodec.cpp index 000f6872b5..9afae8c0ee 100644 --- a/src/corelib/codecs/qicucodec.cpp +++ b/src/corelib/codecs/qicucodec.cpp @@ -457,7 +457,8 @@ QTextCodec *QIcuCodec::codecForNameUnlocked(const char *name) if (!qstrcmp(name, "windows-874-2000") || !qstrcmp(name, "windows-874") || !qstrcmp(name, "MS874") - || !qstrcmp(name, "x-windows-874")) + || !qstrcmp(name, "x-windows-874") + || !qstrcmp(name, "ISO 8859-11")) name = "TIS-620"; UErrorCode error = U_ZERO_ERROR; diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index c3ce405156..7204efc752 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -523,6 +523,11 @@ static const char functionTokenC[] = "%{function}"; static const char pidTokenC[] = "%{pid}"; static const char appnameTokenC[] = "%{appname}"; static const char threadidTokenC[] = "%{threadid}"; +static const char ifDebugTokenC[] = "%{if-debug}"; +static const char ifWarningTokenC[] = "%{if-warning}"; +static const char ifCriticalTokenC[] = "%{if-critical}"; +static const char ifFatalTokenC[] = "%{if-fatal}"; +static const char endifTokenC[] = "%{endif}"; static const char emptyTokenC[] = ""; static const char defaultPattern[] = "%{message}"; @@ -609,6 +614,10 @@ void QMessagePattern::setPattern(const QString &pattern) tokens = new const char*[lexemes.size() + 1]; tokens[lexemes.size()] = 0; + bool nestedIfError = false; + bool inIf = false; + QString error; + for (int i = 0; i < lexemes.size(); ++i) { const QString lexeme = lexemes.at(i); if (lexeme.startsWith(QLatin1String("%{")) @@ -632,23 +641,28 @@ void QMessagePattern::setPattern(const QString &pattern) tokens[i] = appnameTokenC; else if (lexeme == QLatin1String(threadidTokenC)) tokens[i] = threadidTokenC; - else { - tokens[i] = emptyTokenC; - QString error = QStringLiteral("QT_MESSAGE_PATTERN: Unknown placeholder %1\n") +#define IF_TOKEN(LEVEL) \ + else if (lexeme == QLatin1String(LEVEL)) { \ + if (inIf) \ + nestedIfError = true; \ + tokens[i] = LEVEL; \ + inIf = true; \ + } + IF_TOKEN(ifDebugTokenC) + IF_TOKEN(ifWarningTokenC) + IF_TOKEN(ifCriticalTokenC) + IF_TOKEN(ifFatalTokenC) +#undef IF_TOKEN + else if (lexeme == QLatin1String(endifTokenC)) { + tokens[i] = endifTokenC; + if (!inIf && !nestedIfError) + error += QStringLiteral("QT_MESSAGE_PATTERN: %{endif} without an %{if-*}\n"); + inIf = false; + } else { + tokens[i] = emptyTokenC; + error += QStringLiteral("QT_MESSAGE_PATTERN: Unknown placeholder %1\n") .arg(lexeme); - -#if defined(Q_OS_WINCE) - OutputDebugString(reinterpret_cast<const wchar_t*>(error.utf16())); - continue; -#elif defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB) - if (usingWinMain) { - OutputDebugString(reinterpret_cast<const wchar_t*>(error.utf16())); - continue; - } -#endif - fprintf(stderr, "%s", error.toLocal8Bit().constData()); - fflush(stderr); } } else { char *literal = new char[lexeme.size() + 1]; @@ -658,6 +672,24 @@ void QMessagePattern::setPattern(const QString &pattern) tokens[i] = literal; } } + if (nestedIfError) + error += QStringLiteral("QT_MESSAGE_PATTERN: %{if-*} cannot be nested\n"); + else if (inIf) + error += QStringLiteral("QT_MESSAGE_PATTERN: missing %{endif}\n"); + if (!error.isEmpty()) { +#if defined(Q_OS_WINCE) + OutputDebugString(reinterpret_cast<const wchar_t*>(error.utf16())); + if (0) +#elif defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB) + if (usingWinMain) { + OutputDebugString(reinterpret_cast<const wchar_t*>(error.utf16())); + } else +#endif + { + fprintf(stderr, "%s", error.toLocal8Bit().constData()); + fflush(stderr); + } + } literals = new const char*[literalsVar.size() + 1]; literals[literalsVar.size()] = 0; memcpy(literals, literalsVar.constData(), literalsVar.size() * sizeof(const char*)); @@ -737,10 +769,16 @@ Q_CORE_EXPORT QString qMessageFormatString(QtMsgType type, const QMessageLogCont if (pattern->tokens[0] == 0) return message; + bool skip = false; + // we do not convert file, function, line literals to local encoding due to overhead for (int i = 0; pattern->tokens[i] != 0; ++i) { const char *token = pattern->tokens[i]; - if (token == messageTokenC) { + if (token == endifTokenC) { + skip = false; + } else if (skip) { + // do nothing + } else if (token == messageTokenC) { message.append(str); } else if (token == categoryTokenC) { message.append(QLatin1String(context.category)); @@ -772,6 +810,14 @@ Q_CORE_EXPORT QString qMessageFormatString(QtMsgType type, const QMessageLogCont message.append(QLatin1String("0x")); message.append(QString::number(qlonglong(QThread::currentThread()->currentThread()), 16)); #endif +#define HANDLE_IF_TOKEN(LEVEL) \ + } else if (token == if##LEVEL##TokenC) { \ + skip = type != Qt##LEVEL##Msg; + HANDLE_IF_TOKEN(Debug) + HANDLE_IF_TOKEN(Warning) + HANDLE_IF_TOKEN(Critical) + HANDLE_IF_TOKEN(Fatal) +#undef HANDLE_IF_TOKEN } else { message.append(QLatin1String(token)); } @@ -1011,6 +1057,15 @@ void qErrnoWarning(int code, const char *msg, ...) \row \li \c %{type} \li "debug", "warning", "critical" or "fatal" \endtable + You can also use conditionals on the type of the message using \c %{if-debug}, + \c %{if-warning}, \c %{if-critical} or \c %{if-fatal} followed by an \c %{endif}. + What is inside the \c %{if-*} and \c %{endif} will only be printed if the type matches. + + Example: + \code + QT_MESSAGE_PATTERN="[%{if-debug}D%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}" + \endcode + The default \a pattern is "%{message}". The \a pattern can also be changed at runtime by setting the QT_MESSAGE_PATTERN diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index c8a615a1f7..6f977d847d 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1305,6 +1305,8 @@ public: ImhPreferLatin = 0x200, + ImhMultiLine = 0x400, + ImhDigitsOnly = 0x10000, ImhFormattedNumbersOnly = 0x20000, ImhUppercaseOnly = 0x40000, diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 248cdbce96..e1c64aab94 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2330,6 +2330,8 @@ \value ImhTime The text editor functions as a time field. \value ImhPreferLatin Latin characters are preferred (but not required). + \value ImhMultiLine Multiple lines can be entered into the text field. + Flags that restrict input (exclusive flags): \value ImhDigitsOnly Only digits are allowed. diff --git a/src/corelib/io/qabstractfileengine_p.h b/src/corelib/io/qabstractfileengine_p.h index bdc4b5c123..dd64e3d71f 100644 --- a/src/corelib/io/qabstractfileengine_p.h +++ b/src/corelib/io/qabstractfileengine_p.h @@ -66,7 +66,7 @@ class QVariant; class QAbstractFileEngineIterator; class QAbstractFileEnginePrivate; -class Q_AUTOTEST_EXPORT QAbstractFileEngine +class Q_CORE_EXPORT QAbstractFileEngine { public: enum FileFlag { @@ -210,7 +210,7 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractFileEngine::FileFlags) -class Q_AUTOTEST_EXPORT QAbstractFileEngineHandler +class Q_CORE_EXPORT QAbstractFileEngineHandler { public: QAbstractFileEngineHandler(); @@ -219,7 +219,7 @@ public: }; class QAbstractFileEngineIteratorPrivate; -class Q_AUTOTEST_EXPORT QAbstractFileEngineIterator +class Q_CORE_EXPORT QAbstractFileEngineIterator { public: QAbstractFileEngineIterator(QDir::Filters filters, const QStringList &nameFilters); diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index e4b4ce8b42..e849ec1599 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Olivier Goffart <ogoffart@woboq.com> ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -198,6 +199,14 @@ public: inline void connectNotify(const QMetaMethod &signal); inline void disconnectNotify(const QMetaMethod &signal); + template <typename Func1, typename Func2> + static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, + const typename QtPrivate::FunctionPointer<Func2>::Object *receiverPrivate, Func2 slot, + Qt::ConnectionType type = Qt::AutoConnection); + + template <typename Func1, typename Func2> + static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, + const typename QtPrivate::FunctionPointer<Func2>::Object *receiverPrivate, Func2 slot); public: ExtraData *extraData; // extra data set by the user QThreadData *threadData; // id of the thread that owns the object @@ -267,6 +276,74 @@ inline void QObjectPrivate::disconnectNotify(const QMetaMethod &signal) q_ptr->disconnectNotify(signal); } +namespace QtPrivate { +template<typename Func, typename Args, typename R> class QPrivateSlotObject : public QSlotObjectBase +{ + typedef QtPrivate::FunctionPointer<Func> FuncType; + Func function; + static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret) + { + switch (which) { + case Destroy: + delete static_cast<QPrivateSlotObject*>(this_); + break; + case Call: + FuncType::template call<Args, R>(static_cast<QPrivateSlotObject*>(this_)->function, + static_cast<typename FuncType::Object *>(QObjectPrivate::get(r)), a); + break; + case Compare: + *ret = *reinterpret_cast<Func *>(a) == static_cast<QPrivateSlotObject*>(this_)->function; + break; + case NumOperations: ; + } + } +public: + explicit QPrivateSlotObject(Func f) : QSlotObjectBase(&impl), function(f) {} +}; +} //namespace QtPrivate + +template <typename Func1, typename Func2> +inline QMetaObject::Connection QObjectPrivate::connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, + const typename QtPrivate::FunctionPointer<Func2>::Object *receiverPrivate, Func2 slot, + Qt::ConnectionType type) +{ + typedef QtPrivate::FunctionPointer<Func1> SignalType; + typedef QtPrivate::FunctionPointer<Func2> SlotType; + reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0)); + + //compilation error if the arguments does not match. + Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount), + "The slot requires more arguments than the signal provides."); + Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value), + "Signal and slot arguments are not compatible."); + Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible<typename SlotType::ReturnType, typename SignalType::ReturnType>::value), + "Return type of the slot is not compatible with the return type of the signal."); + + const int *types = 0; + if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection) + types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types(); + + return QObject::connectImpl(sender, reinterpret_cast<void **>(&signal), + receiverPrivate->q_func(), reinterpret_cast<void **>(&slot), + new QtPrivate::QPrivateSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value, + typename SignalType::ReturnType>(slot), + type, types, &SignalType::Object::staticMetaObject); +} + +template <typename Func1, typename Func2> +bool QObjectPrivate::disconnect(const typename QtPrivate::FunctionPointer< Func1 >::Object* sender, Func1 signal, + const typename QtPrivate::FunctionPointer< Func2 >::Object* receiverPrivate, Func2 slot) +{ + typedef QtPrivate::FunctionPointer<Func1> SignalType; + typedef QtPrivate::FunctionPointer<Func2> SlotType; + reinterpret_cast<typename SignalType::Object *>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<typename SignalType::Object *>(0)); + //compilation error if the arguments does not match. + Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value), + "Signal and slot arguments are not compatible."); + return QObject::disconnectImpl(sender, reinterpret_cast<void **>(&signal), + receiverPrivate->q_func(), reinterpret_cast<void **>(&slot), + &SignalType::Object::staticMetaObject); +} Q_DECLARE_TYPEINFO(QObjectPrivate::Connection, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QObjectPrivate::Sender, Q_MOVABLE_TYPE); diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 236832097a..3432f9619d 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -502,7 +502,7 @@ bool QLibraryPrivate::unload(UnloadFlag flag) { if (!pHnd) return false; - if (!libraryUnloadCount.deref()) { // only unload if ALL QLibrary instance wanted to + if (libraryUnloadCount.load() > 0 && !libraryUnloadCount.deref()) { // only unload if ALL QLibrary instance wanted to delete inst.data(); if (flag == NoUnloadSys || unload_sys()) { if (qt_debug_component()) @@ -711,7 +711,7 @@ void QLibraryPrivate::updatePluginState() hTempModule = ::LoadLibraryEx((wchar_t*)QDir::toNativeSeparators(fileName).utf16(), 0, dwFlags); SetErrorMode(oldmode); #else - temporary_load = load_sys(); + temporary_load = load(); #endif } QtPluginQueryVerificationDataFunction getMetaData = NULL; @@ -736,11 +736,10 @@ void QLibraryPrivate::updatePluginState() if (getMetaData) ret = qt_get_metadata(getMetaData, this, &exceptionThrown); + if (temporary_load) + unload(); if (!exceptionThrown) { - if (!ret) { - if (temporary_load) - unload_sys(); - } else { + if (ret) { success = true; } retryLoadLibrary = false; diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h index b425e0d590..abf11be9f7 100644 --- a/src/corelib/plugin/qlibrary_p.h +++ b/src/corelib/plugin/qlibrary_p.h @@ -127,7 +127,9 @@ private: bool unload_sys(); QFunctionPointer resolve_sys(const char *); + /// counts how many QLibrary or QPluginLoader are attached to us, plus 1 if it's loaded QAtomicInt libraryRefCount; + /// counts how many times load() or loadPlugin() were called QAtomicInt libraryUnloadCount; enum { IsAPlugin, IsNotAPlugin, MightBeAPlugin } pluginState; diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp index 6704f14eb1..fdf2d1a620 100644 --- a/src/corelib/tools/qcryptographichash.cpp +++ b/src/corelib/tools/qcryptographichash.cpp @@ -41,12 +41,16 @@ ****************************************************************************/ #include <qcryptographichash.h> +#include <qiodevice.h> + +#include "../../3rdparty/sha1/sha1.cpp" +#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 +// qdoc only needs SHA-1 #include "../../3rdparty/md5/md5.h" #include "../../3rdparty/md5/md5.cpp" #include "../../3rdparty/md4/md4.h" #include "../../3rdparty/md4/md4.cpp" -#include "../../3rdparty/sha1/sha1.cpp" typedef unsigned char BitSequence; typedef unsigned long long DataLength; @@ -124,8 +128,6 @@ static int SHA384_512AddLength(SHA512Context *context, unsigned int length); #undef uint68_t #undef int_least16_t -#include <qiodevice.h> - static inline int SHA224_256AddLength(SHA256Context *context, unsigned int length) { QT_PREPEND_NAMESPACE(quint32) addTemp; @@ -136,6 +138,7 @@ static inline int SHA384_512AddLength(SHA512Context *context, unsigned int lengt QT_PREPEND_NAMESPACE(quint64) addTemp; return SHA384_512AddLengthM(context, length); } +#endif // QT_CRYPTOGRAPHICHASH_ONLY_SHA1 QT_BEGIN_NAMESPACE @@ -144,14 +147,16 @@ class QCryptographicHashPrivate public: QCryptographicHash::Algorithm method; union { + Sha1State sha1Context; +#ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 MD5Context md5Context; md4_context md4Context; - Sha1State sha1Context; SHA224Context sha224Context; SHA256Context sha256Context; SHA384Context sha384Context; SHA512Context sha512Context; SHA3Context sha3Context; +#endif }; QByteArray result; }; @@ -212,15 +217,21 @@ QCryptographicHash::~QCryptographicHash() void QCryptographicHash::reset() { switch (d->method) { + case Sha1: + sha1InitState(&d->sha1Context); + break; +#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 + default: + Q_ASSERT_X(false, "QCryptographicHash", "Method not compiled in"); + Q_UNREACHABLE(); + break; +#else case Md4: md4_init(&d->md4Context); break; case Md5: MD5Init(&d->md5Context); break; - case Sha1: - sha1InitState(&d->sha1Context); - break; case Sha224: SHA224Reset(&d->sha224Context); break; @@ -245,6 +256,7 @@ void QCryptographicHash::reset() case Sha3_512: sha3Init(&d->sha3Context, 512); break; +#endif } d->result.clear(); } @@ -256,15 +268,21 @@ void QCryptographicHash::reset() void QCryptographicHash::addData(const char *data, int length) { switch (d->method) { + case Sha1: + sha1Update(&d->sha1Context, (const unsigned char *)data, length); + break; +#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 + default: + Q_ASSERT_X(false, "QCryptographicHash", "Method not compiled in"); + Q_UNREACHABLE(); + break; +#else case Md4: md4_update(&d->md4Context, (const unsigned char *)data, length); break; case Md5: MD5Update(&d->md5Context, (const unsigned char *)data, length); break; - case Sha1: - sha1Update(&d->sha1Context, (const unsigned char *)data, length); - break; case Sha224: SHA224Input(&d->sha224Context, reinterpret_cast<const unsigned char *>(data), length); break; @@ -289,6 +307,7 @@ void QCryptographicHash::addData(const char *data, int length) case Sha3_512: sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8); break; +#endif } d->result.clear(); } @@ -335,6 +354,19 @@ QByteArray QCryptographicHash::result() const return d->result; switch (d->method) { + case Sha1: { + Sha1State copy = d->sha1Context; + d->result.resize(20); + sha1FinalizeState(©); + sha1ToHash(©, (unsigned char *)d->result.data()); + break; + } +#ifdef QT_CRYPTOGRAPHICHASH_ONLY_SHA1 + default: + Q_ASSERT_X(false, "QCryptographicHash", "Method not compiled in"); + Q_UNREACHABLE(); + break; +#else case Md4: { md4_context copy = d->md4Context; d->result.resize(MD4_RESULTLEN); @@ -347,13 +379,6 @@ QByteArray QCryptographicHash::result() const MD5Final(©, (unsigned char *)d->result.data()); break; } - case Sha1: { - Sha1State copy = d->sha1Context; - d->result.resize(20); - sha1FinalizeState(©); - sha1ToHash(©, (unsigned char *)d->result.data()); - break; - } case Sha224: { SHA224Context copy = d->sha224Context; d->result.resize(SHA224HashSize); @@ -402,6 +427,7 @@ QByteArray QCryptographicHash::result() const sha3Final(©, reinterpret_cast<BitSequence *>(d->result.data())); break; } +#endif } return d->result; } diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index bbe7628d38..3089cfef8b 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -966,20 +966,21 @@ const QString::Null QString::null = { }; \sa utf16(), toLatin1(), toUtf8(), toLocal8Bit() */ -// ### replace with QCharIterator int QString::toUcs4_helper(const ushort *uc, int length, uint *out) { int i = 0; - for (; i < length; ++i) { - uint u = uc[i]; - if (QChar::isHighSurrogate(u) && i + 1 < length) { - ushort low = uc[i+1]; + const ushort *const e = uc + length; + while (uc < e) { + uint u = *uc; + if (QChar::isHighSurrogate(u) && uc + 1 < e) { + ushort low = uc[1]; if (QChar::isLowSurrogate(low)) { - ++i; + ++uc; u = QChar::surrogateToUcs4(u, low); } } - *out++ = u; + out[i++] = u; + ++uc; } return i; } |