QUuid: handle quint128 and Id128Bytes data in the same way
The QUuid(quint128) ctor was handing the incoming data differently
from the QUuid(Id128Bytes) ctor. Same was valid for the return
values of QUuid::toUint128() vs QUuid::toBytes().
The provided test didn't reveal it, because it was treating the same
128-bit input value as BE in one place, and as LE in another place.
This patch fixes the test, and updates the implementation of
QUuid(quint128) ctor and toUInt128() method to verify that the
updated test passes.
This commit amends 8566c2db85
Pick-to: 6.6
Change-Id: I24edb8ba0c8f7fd15062ba0b2a94ad387c3e98b6
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
parent
ef4e36aa3c
commit
0393fa6bf2
|
|
@ -246,26 +246,40 @@ inline QUuid QUuid::fromBytes(const void *bytes, QSysInfo::Endian order) noexcep
|
|||
constexpr QUuid::QUuid(quint128 uuid, QSysInfo::Endian order) noexcept
|
||||
: QUuid()
|
||||
{
|
||||
if (order == QSysInfo::LittleEndian)
|
||||
uuid = qbswap(uuid);
|
||||
data1 = uint(uuid >> 96);
|
||||
data2 = ushort(uuid >> 80);
|
||||
data3 = ushort(uuid >> 64);
|
||||
for (int i = 0; i < 8; ++i)
|
||||
data4[i] = uchar(uuid >> (56 - i * 8));
|
||||
if (order == QSysInfo::BigEndian) {
|
||||
data1 = qFromBigEndian<quint32>(int(uuid));
|
||||
data2 = qFromBigEndian<quint16>(ushort(uuid >> 32));
|
||||
data3 = qFromBigEndian<quint16>(ushort(uuid >> 48));
|
||||
for (int i = 0; i < 8; ++i)
|
||||
data4[i] = uchar(uuid >> (64 + i * 8));
|
||||
} else {
|
||||
data1 = qFromLittleEndian<quint32>(uint(uuid >> 96));
|
||||
data2 = qFromLittleEndian<quint16>(ushort(uuid >> 80));
|
||||
data3 = qFromLittleEndian<quint16>(ushort(uuid >> 64));
|
||||
for (int i = 0; i < 8; ++i)
|
||||
data4[i] = uchar(uuid >> (56 - i * 8));
|
||||
}
|
||||
}
|
||||
|
||||
constexpr quint128 QUuid::toUInt128(QSysInfo::Endian order) const noexcept
|
||||
{
|
||||
quint128 result = {};
|
||||
result = data1;
|
||||
result <<= 32;
|
||||
result |= (data2 << 16) | uint(data3);
|
||||
result <<= 64;
|
||||
for (int i = 0; i < 8; ++i)
|
||||
result |= quint64(data4[i]) << (56 - i * 8);
|
||||
if (order == QSysInfo::LittleEndian)
|
||||
return qbswap(result);
|
||||
if (order == QSysInfo::BigEndian) {
|
||||
for (int i = 0; i < 8; ++i)
|
||||
result |= quint64(data4[i]) << (i * 8);
|
||||
result = result << 64;
|
||||
result |= quint64(qToBigEndian<quint16>(data3)) << 48;
|
||||
result |= quint64(qToBigEndian<quint16>(data2)) << 32;
|
||||
result |= qToBigEndian<quint32>(data1);
|
||||
} else {
|
||||
result = qToLittleEndian<quint32>(data1);
|
||||
result = result << 32;
|
||||
result |= quint64(qToLittleEndian<quint16>(data2)) << 16;
|
||||
result |= quint64(qToLittleEndian<quint16>(data3));
|
||||
result = result << 64;
|
||||
for (int i = 0; i < 8; ++i)
|
||||
result |= quint64(data4[i]) << (56 - i * 8);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -250,15 +250,16 @@ void tst_QUuid::uint128()
|
|||
{
|
||||
#ifdef __SIZEOF_INT128__
|
||||
constexpr quint128 u = quint128(Q_UINT64_C(0xfc69b59ecc344436)) << 64
|
||||
| Q_UINT64_C(0xa43cee95d128b8c5);
|
||||
constexpr QUuid uuid(u);
|
||||
static_assert(uuid.toUInt128() == u, "Round-trip through QUuid failed");
|
||||
| Q_UINT64_C(0xa43cee95d128b8c5); // This is LE
|
||||
constexpr quint128 be = qToBigEndian(u);
|
||||
constexpr QUuid uuid(be);
|
||||
static_assert(uuid.toUInt128() == be, "Round-trip through QUuid failed");
|
||||
|
||||
QCOMPARE(uuid, uuidA);
|
||||
QCOMPARE(quint64(uuid.toUInt128() >> 64), quint64(u >> 64));
|
||||
QCOMPARE(quint64(uuid.toUInt128()), quint64(u));
|
||||
QCOMPARE(quint64(uuid.toUInt128() >> 64), quint64(be >> 64));
|
||||
QCOMPARE(quint64(uuid.toUInt128()), quint64(be));
|
||||
|
||||
quint128 le = qFromBigEndian(u);
|
||||
quint128 le = qFromBigEndian(be);
|
||||
QCOMPARE(quint64(uuid.toUInt128(QSysInfo::LittleEndian) >> 64), quint64(le >> 64));
|
||||
QCOMPARE(quint64(uuid.toUInt128(QSysInfo::LittleEndian)), quint64(le));
|
||||
QCOMPARE(QUuid(le, QSysInfo::LittleEndian), uuidA);
|
||||
|
|
@ -266,6 +267,11 @@ void tst_QUuid::uint128()
|
|||
QUuid::Id128Bytes bytes = { .data128 = { qToBigEndian(u) } };
|
||||
QUuid uuid2(bytes);
|
||||
QCOMPARE(uuid2, uuid);
|
||||
|
||||
// verify that toBytes() and toUInt128() provide bytewise similar result
|
||||
constexpr quint128 val = uuid.toUInt128();
|
||||
bytes = uuid.toBytes();
|
||||
QVERIFY(memcmp(&val, bytes.data, sizeof(val)) == 0);
|
||||
#else
|
||||
QSKIP("This platform has no support for 128-bit integer");
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue