Add QUuid::toRfc4122() and fromRfc4122()

Following the RFC4122, provide the interfaces between QUuid
and QByteArray, they are simpler then toByteArray() and
relevant.

Thanks for the suggestion and brief code from Robin Burchell.

Task-number: QTBUG-19420
Reviewed-by: joao
(cherry picked from commit 06873e467d98ad60d827afae29500bf2ff783c03)

Change-Id: I4623ae3363f1d5affa45de73fac616bb67a9eaa1
Reviewed-on: http://codereview.qt.nokia.com/168
Reviewed-by: Liang Qi <liang.qi@nokia.com>
This commit is contained in:
Liang Qi 2011-05-27 13:34:28 +02:00 committed by Sergio Ahumada
parent 8f4c007f85
commit 623c753a7b
4 changed files with 128 additions and 0 deletions

View File

@ -386,6 +386,45 @@ QUuid::QUuid(const QByteArray &text)
}
#endif
/*!
Creates a QUuid object from the binary representation of the UUID, as
specified by RFC 4122 section 4.1.2. See toRfc4122() for a further
explanation of the order of bytes required.
The byte array accepted is NOT a human readable format.
If the conversion fails, a null UUID is created.
\since 4.8
\sa toRfc4122(), QUuid()
*/
QUuid QUuid::fromRfc4122(const QByteArray &bytes)
{
if (bytes.isEmpty() || bytes.length() != 16)
return QUuid();
uint d1;
ushort d2, d3;
uchar d4[8];
const uchar *data = reinterpret_cast<const uchar *>(bytes.constData());
d1 = qFromBigEndian<quint32>(data);
data += sizeof(quint32);
d2 = qFromBigEndian<quint16>(data);
data += sizeof(quint16);
d3 = qFromBigEndian<quint16>(data);
data += sizeof(quint16);
for (int i = 0; i < 8; ++i) {
d4[i] = *(data);
data++;
}
return QUuid(d1, d2, d3, d4[0], d4[1], d4[2], d4[3], d4[4], d4[5], d4[6], d4[7]);
}
/*!
\fn bool QUuid::operator==(const QUuid &other) const
@ -499,6 +538,59 @@ QByteArray QUuid::toByteArray() const
}
#endif
/*!
Returns the binary representation of this QUuid. The byte array is in big
endian format, and formatted according to RFC 4122, section 4.1.2 -
"Layout and byte order".
The order is as follows:
\table
\header
\o Field #
\o Source
\row
\o 1
\o data1
\row
\o 2
\o data2
\row
\o 3
\o data3
\row
\o 4
\o data4[0] .. data4[7]
\endtable
\since 4.8
*/
QByteArray QUuid::toRfc4122() const
{
// we know how many bytes a UUID has, I hope :)
QByteArray bytes(16, Qt::Uninitialized);
uchar *data = reinterpret_cast<uchar*>(bytes.data());
qToBigEndian(data1, data);
data += sizeof(quint32);
qToBigEndian(data2, data);
data += sizeof(quint16);
qToBigEndian(data3, data);
data += sizeof(quint16);
for (int i = 0; i < 8; ++i) {
*(data) = data4[i];
data++;
}
return bytes;
}
#ifndef QT_NO_DATASTREAM
/*!
\relates QUuid

View File

@ -112,6 +112,8 @@ struct Q_CORE_EXPORT QUuid
QUuid(const QByteArray &);
QByteArray toByteArray() const;
#endif
QByteArray toRfc4122() const;
static QUuid fromRfc4122(const QByteArray &);
bool isNull() const;
bool operator==(const QUuid &orig) const

View File

@ -65,6 +65,8 @@ private slots:
void fromString();
void toByteArray();
void fromByteArray();
void toRfc4122();
void fromRfc4122();
void check_QDataStream();
void isNull();
void equal();
@ -147,6 +149,20 @@ void tst_QUuid::fromByteArray()
QCOMPARE(uuidB, QUuid(QByteArray("{1ab6e93a-b1cb-4a87-ba47-ec7e99039a7b}")));
}
void tst_QUuid::toRfc4122()
{
QCOMPARE(uuidA.toRfc4122(), QByteArray::fromHex("fc69b59ecc344436a43cee95d128b8c5"));
QCOMPARE(uuidB.toRfc4122(), QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b"));
}
void tst_QUuid::fromRfc4122()
{
QCOMPARE(uuidA, QUuid::fromRfc4122(QByteArray::fromHex("fc69b59ecc344436a43cee95d128b8c5")));
QCOMPARE(uuidB, QUuid::fromRfc4122(QByteArray::fromHex("1ab6e93ab1cb4a87ba47ec7e99039a7b")));
}
void tst_QUuid::check_QDataStream()
{
QUuid tmp;

View File

@ -58,6 +58,8 @@ private slots:
void fromString();
void toByteArray();
void fromByteArray();
void toRfc4122();
void fromRfc4122();
void toDataStream();
void fromDataStream();
void isNull();
@ -111,6 +113,22 @@ void tst_bench_QUuid::fromByteArray()
}
}
void tst_bench_QUuid::toRfc4122()
{
QUuid uuid = QUuid::createUuid();
QBENCHMARK {
uuid.toRfc4122();
}
}
void tst_bench_QUuid::fromRfc4122()
{
QByteArray string = QByteArray::fromHex("67C8770B44F1410AAB9AF9B5446F13EE");
QBENCHMARK {
QUuid uuid = QUuid::fromRfc4122(string);
}
}
void tst_bench_QUuid::toDataStream()
{
QUuid uuid1, uuid2;