mirror of https://github.com/qt/qtbase.git
QUuid: add the ability to specify the byte order for 128-bit IDs
Some more modern protocols like Bluetooth LE transmit data in little endian. QtBluetooth will benefit from this. Change-Id: Id8e48e8f498c4a029619fffd1728c94ddd444537 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This commit is contained in:
parent
0f932b9a5d
commit
686c02224c
|
@ -301,30 +301,33 @@ static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCrypto
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn QUuid::QUuid(Id128Bytes id128) noexcept
|
\fn QUuid::QUuid(Id128Bytes id128, QSysInfo::Endian order) noexcept
|
||||||
\since 6.6
|
\since 6.6
|
||||||
|
|
||||||
Creates a QUuid based on the integral \a id128 parameter.
|
Creates a QUuid based on the integral \a id128 parameter and respecting the
|
||||||
|
byte order \a order.
|
||||||
|
|
||||||
\sa fromBytes(), toBytes(), toRfc4122()
|
\sa fromBytes(), toBytes(), toRfc4122()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn QUuid::Id128Bytes QUuid::toBytes() const noexcept
|
\fn QUuid::Id128Bytes QUuid::toBytes(QSysInfo::Endian order) const noexcept
|
||||||
\since 6.6
|
\since 6.6
|
||||||
|
|
||||||
Returns an 128-bit ID created from this QUuid. The binary content of this
|
Returns an 128-bit ID created from this QUuid on the byte order specified
|
||||||
function is the same as toRfc4122(). See that function for more details.
|
by \a order. The binary content of this function is the same as toRfc4122()
|
||||||
|
if the order is QSysInfo::BigEndian. See that function for more details.
|
||||||
|
|
||||||
\sa toRfc4122(), fromBytes(), QUuid()
|
\sa toRfc4122(), fromBytes(), QUuid()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn QUuid QUuid::fromBytes(const void *bytes) noexcept
|
\fn QUuid QUuid::fromBytes(const void *bytes, QSysInfo::Endian order) noexcept
|
||||||
\since 6.6
|
\since 6.6
|
||||||
|
|
||||||
Reads 128 bits (16 bytes) from \a bytes and returns the QUuid corresponding
|
Reads 128 bits (16 bytes) from \a bytes using byte order \a order and
|
||||||
to those bytes. This function does the same as fromRfc4122().
|
returns the QUuid corresponding to those bytes. This function does the same
|
||||||
|
as fromRfc4122() if the byte order \a order is QSysInfo::BigEndian.
|
||||||
|
|
||||||
\sa fromRfc4122()
|
\sa fromRfc4122()
|
||||||
*/
|
*/
|
||||||
|
@ -674,6 +677,9 @@ QDataStream &operator<<(QDataStream &s, const QUuid &id)
|
||||||
bytes = QByteArray(16, Qt::Uninitialized);
|
bytes = QByteArray(16, Qt::Uninitialized);
|
||||||
uchar *data = reinterpret_cast<uchar *>(bytes.data());
|
uchar *data = reinterpret_cast<uchar *>(bytes.data());
|
||||||
|
|
||||||
|
// for historical reasons, our little-endian serialization format
|
||||||
|
// stores each of the UUID fields in little endian, instead of storing
|
||||||
|
// a little endian Id128
|
||||||
qToLittleEndian(id.data1, data);
|
qToLittleEndian(id.data1, data);
|
||||||
data += sizeof(quint32);
|
data += sizeof(quint32);
|
||||||
qToLittleEndian(id.data2, data);
|
qToLittleEndian(id.data2, data);
|
||||||
|
|
|
@ -72,7 +72,7 @@ public:
|
||||||
constexpr QUuid(uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3,
|
constexpr QUuid(uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3,
|
||||||
uchar b4, uchar b5, uchar b6, uchar b7, uchar b8) noexcept
|
uchar b4, uchar b5, uchar b6, uchar b7, uchar b8) noexcept
|
||||||
: data1(l), data2(w1), data3(w2), data4{b1, b2, b3, b4, b5, b6, b7, b8} {}
|
: data1(l), data2(w1), data3(w2), data4{b1, b2, b3, b4, b5, b6, b7, b8} {}
|
||||||
QUuid(Id128Bytes id128) noexcept;
|
QUuid(Id128Bytes id128, QSysInfo::Endian order = QSysInfo::BigEndian) noexcept;
|
||||||
|
|
||||||
explicit QUuid(QAnyStringView string) noexcept
|
explicit QUuid(QAnyStringView string) noexcept
|
||||||
: QUuid{fromString(string)} {}
|
: QUuid{fromString(string)} {}
|
||||||
|
@ -86,10 +86,10 @@ public:
|
||||||
#endif
|
#endif
|
||||||
QString toString(StringFormat mode = WithBraces) const;
|
QString toString(StringFormat mode = WithBraces) const;
|
||||||
QByteArray toByteArray(StringFormat mode = WithBraces) const;
|
QByteArray toByteArray(StringFormat mode = WithBraces) const;
|
||||||
Id128Bytes toBytes() const noexcept;
|
Id128Bytes toBytes(QSysInfo::Endian order = QSysInfo::BigEndian) const noexcept;
|
||||||
QByteArray toRfc4122() const;
|
QByteArray toRfc4122() const;
|
||||||
|
|
||||||
static QUuid fromBytes(const void *bytes) noexcept;
|
static QUuid fromBytes(const void *bytes, QSysInfo::Endian order = QSysInfo::BigEndian) noexcept;
|
||||||
#if QT_CORE_REMOVED_SINCE(6, 3)
|
#if QT_CORE_REMOVED_SINCE(6, 3)
|
||||||
static QUuid fromRfc4122(const QByteArray &);
|
static QUuid fromRfc4122(const QByteArray &);
|
||||||
#endif
|
#endif
|
||||||
|
@ -179,6 +179,16 @@ public:
|
||||||
ushort data2 = 0;
|
ushort data2 = 0;
|
||||||
ushort data3 = 0;
|
ushort data3 = 0;
|
||||||
uchar data4[8] = {};
|
uchar data4[8] = {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr Id128Bytes bswap(Id128Bytes b)
|
||||||
|
{
|
||||||
|
// 128-bit byte swap
|
||||||
|
b.data64[0] = qbswap(b.data64[0]);
|
||||||
|
b.data64[1] = qbswap(b.data64[1]);
|
||||||
|
qSwap(b.data64[0], b.data64[1]);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_TYPEINFO(QUuid, Q_PRIMITIVE_TYPE);
|
Q_DECLARE_TYPEINFO(QUuid, Q_PRIMITIVE_TYPE);
|
||||||
|
@ -194,29 +204,33 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, const QUuid &);
|
||||||
|
|
||||||
Q_CORE_EXPORT size_t qHash(const QUuid &uuid, size_t seed = 0) noexcept;
|
Q_CORE_EXPORT size_t qHash(const QUuid &uuid, size_t seed = 0) noexcept;
|
||||||
|
|
||||||
inline QUuid::QUuid(Id128Bytes uuid) noexcept
|
inline QUuid::QUuid(Id128Bytes uuid, QSysInfo::Endian order) noexcept
|
||||||
{
|
{
|
||||||
|
if (order == QSysInfo::LittleEndian)
|
||||||
|
uuid = bswap(uuid);
|
||||||
data1 = qFromBigEndian<quint32>(&uuid.data[0]);
|
data1 = qFromBigEndian<quint32>(&uuid.data[0]);
|
||||||
data2 = qFromBigEndian<quint16>(&uuid.data[4]);
|
data2 = qFromBigEndian<quint16>(&uuid.data[4]);
|
||||||
data3 = qFromBigEndian<quint16>(&uuid.data[6]);
|
data3 = qFromBigEndian<quint16>(&uuid.data[6]);
|
||||||
memcpy(data4, &uuid.data[8], sizeof(data4));
|
memcpy(data4, &uuid.data[8], sizeof(data4));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QUuid::Id128Bytes QUuid::toBytes() const noexcept
|
inline QUuid::Id128Bytes QUuid::toBytes(QSysInfo::Endian order) const noexcept
|
||||||
{
|
{
|
||||||
Id128Bytes result = {};
|
Id128Bytes result = {};
|
||||||
qToBigEndian(data1, &result.data[0]);
|
qToBigEndian(data1, &result.data[0]);
|
||||||
qToBigEndian(data2, &result.data[4]);
|
qToBigEndian(data2, &result.data[4]);
|
||||||
qToBigEndian(data3, &result.data[6]);
|
qToBigEndian(data3, &result.data[6]);
|
||||||
memcpy(&result.data[8], data4, sizeof(data4));
|
memcpy(&result.data[8], data4, sizeof(data4));
|
||||||
|
if (order == QSysInfo::LittleEndian)
|
||||||
|
return bswap(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QUuid QUuid::fromBytes(const void *bytes) noexcept
|
inline QUuid QUuid::fromBytes(const void *bytes, QSysInfo::Endian order) noexcept
|
||||||
{
|
{
|
||||||
Id128Bytes result = {};
|
Id128Bytes result = {};
|
||||||
memcpy(result.data, bytes, sizeof(result));
|
memcpy(result.data, bytes, sizeof(result));
|
||||||
return QUuid(result);
|
return QUuid(result, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator<=(const QUuid &lhs, const QUuid &rhs) noexcept
|
inline bool operator<=(const QUuid &lhs, const QUuid &rhs) noexcept
|
||||||
|
|
|
@ -237,6 +237,12 @@ void tst_QUuid::id128()
|
||||||
QCOMPARE(QUuid(bytesB), uuidB);
|
QCOMPARE(QUuid(bytesB), uuidB);
|
||||||
QVERIFY(memcmp(uuidA.toBytes().data, bytesA.data, sizeof(QUuid::Id128Bytes)) == 0);
|
QVERIFY(memcmp(uuidA.toBytes().data, bytesA.data, sizeof(QUuid::Id128Bytes)) == 0);
|
||||||
QVERIFY(memcmp(uuidB.toBytes().data, bytesB.data, sizeof(QUuid::Id128Bytes)) == 0);
|
QVERIFY(memcmp(uuidB.toBytes().data, bytesB.data, sizeof(QUuid::Id128Bytes)) == 0);
|
||||||
|
|
||||||
|
QUuid::Id128Bytes leBytesA = {};
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QUuid::createUuidV3OrV5()
|
void tst_QUuid::createUuidV3OrV5()
|
||||||
|
|
Loading…
Reference in New Issue