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 <liang.qi@nokia.com>
This commit is contained in:
Liang Qi 2011-05-20 11:07:06 +02:00 committed by Qt Continuous Integration System
parent ddc9698079
commit 750f995fb2
2 changed files with 99 additions and 54 deletions

View File

@ -42,9 +42,97 @@
#include "quuid.h"
#include "qdatastream.h"
#include "qendian.h"
QT_BEGIN_NAMESPACE
#ifndef QT_NO_QUUID_STRING
template <class Char, class Integral>
void _q_toHex(Char *&dst, Integral value)
{
static const char digits[] = "0123456789abcdef";
if (sizeof(Integral) > 1)
value = qToBigEndian(value);
const char* p = reinterpret_cast<const char*>(&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 <class Char, class Integral>
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 <class Char>
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 <class Char>
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) {
const ushort *data = reinterpret_cast<const ushort *>(text.unicode());
if (*data == '{' && text.length() < 37) {
*this = QUuid();
return;
}
data3 = temp.mid(15, 4).toUInt(&ok, 16);
if (!ok) {
if (!_q_uuidFromHex(data, data1, data2, data3, data4)) {
*this = QUuid();
return;
}
data4[0] = temp.mid(20, 2).toUInt(&ok, 16);
if (!ok) {
*this = QUuid();
return;
}
data4[1] = temp.mid(22, 2).toUInt(&ok, 16);
if (!ok) {
*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;
QString result(38, Qt::Uninitialized);
ushort *data = (ushort *)result.unicode();
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);
_q_uuidToHex(data, data1, data2, data3, data4);
return result + QLatin1Char('}');
return result;
}
#endif

View File

@ -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;