QUuid: convert bswap(Id128Bytes) to a hidden friend of Id128Bytes

... and rename it to qbswap(), thus enabling the endian conversions
for Id128bytes via q{To,From}{Little,Big}Endian() functions.

Found during Qt 6.6 API Review.

Pick-to: 6.6
Change-Id: Ie320cee52ec2b9de0aaa112adec8febb7f5b68a2
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
Ivan Solovev 2023-08-15 17:18:55 +02:00
parent e6a36f21a3
commit 470b2b8ad9
3 changed files with 86 additions and 13 deletions

View File

@ -300,6 +300,54 @@ static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCrypto
values.
*/
/*!
\fn QUuid::Id128Bytes qFromBigEndian(QUuid::Id128Bytes src)
\since 6.6
\relates QUuid::Id128Bytes
\overload
Converts \a src from big-endian byte order and returns the struct holding
the binary representation of UUID in host byte order.
\sa <QtEndian>
*/
/*!
\fn QUuid::Id128Bytes qFromLittleEndian(QUuid::Id128Bytes src)
\since 6.6
\relates QUuid::Id128Bytes
\overload
Converts \a src from little-endian byte order and returns the struct holding
the binary representation of UUID in host byte order.
\sa <QtEndian>
*/
/*!
\fn QUuid::Id128Bytes qToBigEndian(QUuid::Id128Bytes src)
\since 6.6
\relates QUuid::Id128Bytes
\overload
Converts \a src from host byte order and returns the struct holding the
binary representation of UUID in big-endian byte order.
\sa <QtEndian>
*/
/*!
\fn QUuid::Id128Bytes qToLittleEndian(QUuid::Id128Bytes src)
\since 6.6
\relates QUuid::Id128Bytes
\overload
Converts \a src from host byte order and returns the struct holding the
binary representation of UUID in little-endian byte order.
\sa <QtEndian>
*/
/*!
\fn QUuid::QUuid(Id128Bytes id128, QSysInfo::Endian order) noexcept
\since 6.6

View File

@ -68,6 +68,16 @@ public:
{
return QByteArrayView(data, sizeof(data));
}
friend constexpr Id128Bytes qbswap(Id128Bytes b) noexcept
{
// 128-bit byte swap
auto b0 = qbswap(b.data64[0]);
auto b1 = qbswap(b.data64[1]);
b.data64[0] = b1;
b.data64[1] = b0;
return b;
}
};
constexpr QUuid() noexcept : data1(0), data2(0), data3(0), data4{0,0,0,0,0,0,0,0} {}
@ -188,17 +198,6 @@ public:
ushort data2;
ushort data3;
uchar data4[8];
private:
static constexpr Id128Bytes bswap(Id128Bytes b)
{
// 128-bit byte swap
auto b0 = qbswap(b.data64[0]);
auto b1 = qbswap(b.data64[1]);
b.data64[0] = b1;
b.data64[1] = b0;
return b;
}
};
Q_DECLARE_TYPEINFO(QUuid, Q_PRIMITIVE_TYPE);
@ -217,7 +216,7 @@ Q_CORE_EXPORT size_t qHash(const QUuid &uuid, size_t seed = 0) noexcept;
QUuid::QUuid(Id128Bytes uuid, QSysInfo::Endian order) noexcept
{
if (order == QSysInfo::LittleEndian)
uuid = bswap(uuid);
uuid = qbswap(uuid);
data1 = qFromBigEndian<quint32>(&uuid.data[0]);
data2 = qFromBigEndian<quint16>(&uuid.data[4]);
data3 = qFromBigEndian<quint16>(&uuid.data[6]);
@ -232,7 +231,7 @@ QUuid::Id128Bytes QUuid::toBytes(QSysInfo::Endian order) const noexcept
qToBigEndian(data3, &result.data[6]);
memcpy(&result.data[8], data4, sizeof(data4));
if (order == QSysInfo::LittleEndian)
return bswap(result);
return qbswap(result);
return result;
}
@ -291,6 +290,15 @@ inline bool operator<=(const QUuid &lhs, const QUuid &rhs) noexcept
inline bool operator>=(const QUuid &lhs, const QUuid &rhs) noexcept
{ return !(lhs < rhs); }
#if defined(Q_QDOC)
// provide fake declarations of qXXXEndian() functions, so that qDoc could
// distinguish them from the general template
QUuid::Id128Bytes qFromBigEndian(QUuid::Id128Bytes src);
QUuid::Id128Bytes qFromLittleEndian(QUuid::Id128Bytes src);
QUuid::Id128Bytes qToBigEndian(QUuid::Id128Bytes src);
QUuid::Id128Bytes qToLittleEndian(QUuid::Id128Bytes src);
#endif
QT_END_NAMESPACE
#endif // QUUID_H

View File

@ -244,6 +244,23 @@ void tst_QUuid::id128()
leBytesA.data[15 - i] = bytesA.data[i];
QCOMPARE(QUuid(leBytesA, QSysInfo::LittleEndian), uuidA);
QVERIFY(memcmp(uuidA.toBytes(QSysInfo::LittleEndian).data, leBytesA.data, sizeof(leBytesA)) == 0);
// check the new q{To,From}{Big,Little}Endian() overloads
QUuid::Id128Bytes roundtrip = qFromLittleEndian(qToLittleEndian(bytesA));
QVERIFY(memcmp(roundtrip.data, bytesA.data, sizeof(bytesA)) == 0);
roundtrip = qFromBigEndian(qToBigEndian(bytesA));
QVERIFY(memcmp(roundtrip.data, bytesA.data, sizeof(bytesA)) == 0);
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
const QUuid::Id128Bytes beBytesA = qToBigEndian(leBytesA);
QVERIFY(memcmp(beBytesA.data, bytesA.data, sizeof(beBytesA)) == 0);
const QUuid::Id128Bytes otherLeBytesA = qFromBigEndian(bytesA);
QVERIFY(memcmp(otherLeBytesA.data, leBytesA.data, sizeof(leBytesA)) == 0);
#else // Q_BIG_ENDIAN
const QUuid::Id128Bytes otherLeBytesA = qToLittleEndian(bytesA);
QVERIFY(memcmp(otherLeBytesA.data, leBytesA.data, sizeof(leBytesA)) == 0);
const QUuid::Id128Bytes beBytesA = qFromLittleEndian(leBytesA);
QVERIFY(memcmp(beBytesA.data, bytesA.data, sizeof(beBytesA)) == 0);
#endif // Q_BYTE_ORDER == Q_LITTLE_ENDIAN
}
void tst_QUuid::uint128()