From 623c753a7b6a582e352acc5a0abbb7eb402af3b7 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Fri, 27 May 2011 13:34:28 +0200 Subject: [PATCH] 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 --- src/corelib/plugin/quuid.cpp | 92 +++++++++++++++++++ src/corelib/plugin/quuid.h | 2 + tests/auto/quuid/tst_quuid.cpp | 16 ++++ .../corelib/plugin/quuid/tst_quuid.cpp | 18 ++++ 4 files changed, 128 insertions(+) diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index facd732609..eb29e6eba8 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -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(bytes.constData()); + + d1 = qFromBigEndian(data); + data += sizeof(quint32); + d2 = qFromBigEndian(data); + data += sizeof(quint16); + d3 = qFromBigEndian(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(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 diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h index 69c4044e3c..832d5bc5c6 100644 --- a/src/corelib/plugin/quuid.h +++ b/src/corelib/plugin/quuid.h @@ -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 diff --git a/tests/auto/quuid/tst_quuid.cpp b/tests/auto/quuid/tst_quuid.cpp index 3abc8af4c0..4948312fd4 100644 --- a/tests/auto/quuid/tst_quuid.cpp +++ b/tests/auto/quuid/tst_quuid.cpp @@ -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; diff --git a/tests/benchmarks/corelib/plugin/quuid/tst_quuid.cpp b/tests/benchmarks/corelib/plugin/quuid/tst_quuid.cpp index 24754ab370..a035cf3627 100644 --- a/tests/benchmarks/corelib/plugin/quuid/tst_quuid.cpp +++ b/tests/benchmarks/corelib/plugin/quuid/tst_quuid.cpp @@ -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;