From 750f995fb2e9e38f29e3ed0243b814b867d7d643 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Fri, 20 May 2011 11:07:06 +0200 Subject: Optimize QUuid::toString() and relevant QUuid::toString() and QUuid(const QString &) are too slow now. Task-number: QTBUG-19418 Reviewed-by: joao Reviewed-by: Denis Dzyubenko Reviewed-by: Ritt Konstantin Reviewed-by: Robin Burchell Reviewed-by: Richard J. Moore (cherry picked from commit 7ce566ed82666ac08f137f4d8590ce589d42c82a) Change-Id: I7e5bb4072f0941c20a7278a2d9766d4ef47be811 Reviewed-on: http://codereview.qt.nokia.com/166 Reviewed-by: Liang Qi --- src/corelib/plugin/quuid.cpp | 153 ++++++++++++++++++++++++++++--------------- src/corelib/plugin/quuid.h | 2 +- 2 files changed, 100 insertions(+), 55 deletions(-) diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 9cd353a7da..7ef8522411 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -42,9 +42,97 @@ #include "quuid.h" #include "qdatastream.h" +#include "qendian.h" QT_BEGIN_NAMESPACE +#ifndef QT_NO_QUUID_STRING +template +void _q_toHex(Char *&dst, Integral value) +{ + static const char digits[] = "0123456789abcdef"; + + if (sizeof(Integral) > 1) + value = qToBigEndian(value); + + const char* p = reinterpret_cast(&value); + + for (uint i = 0; i < sizeof(Integral); ++i, dst += 2) { + uint j = (p[i] >> 4) & 0xf; + dst[0] = Char(digits[j]); + j = p[i] & 0xf; + dst[1] = Char(digits[j]); + } +} + +template +bool _q_fromHex(const Char *&src, Integral &value) +{ + value = 0; + + for (uint i = 0; i < sizeof(Integral) * 2; ++i) { + int ch = *src++; + int tmp; + if (ch >= '0' && ch <= '9') + tmp = ch - '0'; + else if (ch >= 'a' && ch <= 'f') + tmp = ch - 'a' + 10; + else if (ch >= 'A' && ch <= 'F') + tmp = ch - 'A' + 10; + else + return false; + + value = value * 16 + tmp; + } + + return true; +} + +template +void _q_uuidToHex(Char *&dst, const uint &d1, const ushort &d2, const ushort &d3, const uchar (&d4)[8]) +{ + *dst++ = Char('{'); + _q_toHex(dst, d1); + *dst++ = Char('-'); + _q_toHex(dst, d2); + *dst++ = Char('-'); + _q_toHex(dst, d3); + *dst++ = Char('-'); + for (int i = 0; i < 2; i++) + _q_toHex(dst, d4[i]); + *dst++ = Char('-'); + for (int i = 2; i < 8; i++) + _q_toHex(dst, d4[i]); + *dst = Char('}'); +} + +template +bool _q_uuidFromHex(const Char *&src, uint &d1, ushort &d2, ushort &d3, uchar (&d4)[8]) +{ + if (*src == Char('{')) + src++; + if (!_q_fromHex(src, d1) + || *src++ != Char('-') + || !_q_fromHex(src, d2) + || *src++ != Char('-') + || !_q_fromHex(src, d3) + || *src++ != Char('-') + || !_q_fromHex(src, d4[0]) + || !_q_fromHex(src, d4[1]) + || *src++ != Char('-') + || !_q_fromHex(src, d4[2]) + || !_q_fromHex(src, d4[3]) + || !_q_fromHex(src, d4[4]) + || !_q_fromHex(src, d4[5]) + || !_q_fromHex(src, d4[6]) + || !_q_fromHex(src, d4[7])) { + return false; + } + + return true; +} +#endif + /*! \class QUuid \brief The QUuid class stores a Universally Unique Identifier (UUID). @@ -231,50 +319,22 @@ QT_BEGIN_NAMESPACE */ QUuid::QUuid(const QString &text) { - bool ok; - if (text.isEmpty()) { - *this = QUuid(); - return; - } - QString temp = text.toUpper(); - if (temp[0] != QLatin1Char('{')) - temp = QLatin1Char('{') + text; - if (text[(int)text.length()-1] != QLatin1Char('}')) - temp += QLatin1Char('}'); - - data1 = temp.mid(1, 8).toULongLong(&ok, 16); - if (!ok) { + if (text.length() < 36) { *this = QUuid(); return; } - data2 = temp.mid(10, 4).toUInt(&ok, 16); - if (!ok) { - *this = QUuid(); - return; - } - data3 = temp.mid(15, 4).toUInt(&ok, 16); - if (!ok) { - *this = QUuid(); - return; - } - data4[0] = temp.mid(20, 2).toUInt(&ok, 16); - if (!ok) { + const ushort *data = reinterpret_cast(text.unicode()); + + if (*data == '{' && text.length() < 37) { *this = QUuid(); return; } - data4[1] = temp.mid(22, 2).toUInt(&ok, 16); - if (!ok) { + + if (!_q_uuidFromHex(data, data1, data2, data3, data4)) { *this = QUuid(); return; } - for (int i = 2; i<8; i++) { - data4[i] = temp.mid(25 + (i-2)*2, 2).toUShort(&ok, 16); - if (!ok) { - *this = QUuid(); - return; - } - } } /*! @@ -308,11 +368,6 @@ QUuid::QUuid(const char *text) \sa toString() */ -static QString uuidhex(uint data, int digits) -{ - return QString::number(data, 16).rightJustified(digits, QLatin1Char('0')); -} - /*! Returns the string representation of this QUuid. The string is formatted as five hex fields separated by '-' and enclosed in @@ -349,22 +404,12 @@ static QString uuidhex(uint data, int digits) */ QString QUuid::toString() const { - QString result; - - QChar dash = QLatin1Char('-'); - result = QLatin1Char('{') + uuidhex(data1,8); - result += dash; - result += uuidhex(data2,4); - result += dash; - result += uuidhex(data3,4); - result += dash; - result += uuidhex(data4[0],2); - result += uuidhex(data4[1],2); - result += dash; - for (int i = 2; i < 8; i++) - result += uuidhex(data4[i],2); + QString result(38, Qt::Uninitialized); + ushort *data = (ushort *)result.unicode(); - return result + QLatin1Char('}'); + _q_uuidToHex(data, data1, data2, data3, data4); + + return result; } #endif diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h index f42ca91270..e9afacc560 100644 --- a/src/corelib/plugin/quuid.h +++ b/src/corelib/plugin/quuid.h @@ -108,7 +108,7 @@ struct Q_CORE_EXPORT QUuid QUuid(const QString &); QUuid(const char *); QString toString() const; - operator QString() const { return toString(); } + operator QString() const { return toString(); } // ### Qt5 remove #endif bool isNull() const; -- cgit v1.2.3