summaryrefslogtreecommitdiffstats
path: root/src/corelib/plugin
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2022-11-18 12:56:38 -0800
committerIvan Solovev <ivan.solovev@qt.io>2022-12-16 19:29:10 +0100
commit686c02224c03735356bdab987bf62644eb34cc34 (patch)
tree94500183cb86c3c6c2e26c478da18784448254b0 /src/corelib/plugin
parent0f932b9a5de21060fb9763eed24298ae929e9821 (diff)
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>
Diffstat (limited to 'src/corelib/plugin')
-rw-r--r--src/corelib/plugin/quuid.cpp22
-rw-r--r--src/corelib/plugin/quuid.h28
2 files changed, 35 insertions, 15 deletions
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp
index a980c9a5ba..baf9a8bd3e 100644
--- a/src/corelib/plugin/quuid.cpp
+++ b/src/corelib/plugin/quuid.cpp
@@ -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
- 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()
*/
/*!
- \fn QUuid::Id128Bytes QUuid::toBytes() const noexcept
+ \fn QUuid::Id128Bytes QUuid::toBytes(QSysInfo::Endian order) const noexcept
\since 6.6
- Returns an 128-bit ID created from this QUuid. The binary content of this
- function is the same as toRfc4122(). See that function for more details.
+ Returns an 128-bit ID created from this QUuid on the byte order specified
+ 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()
*/
/*!
- \fn QUuid QUuid::fromBytes(const void *bytes) noexcept
+ \fn QUuid QUuid::fromBytes(const void *bytes, QSysInfo::Endian order) noexcept
\since 6.6
- Reads 128 bits (16 bytes) from \a bytes and returns the QUuid corresponding
- to those bytes. This function does the same as fromRfc4122().
+ Reads 128 bits (16 bytes) from \a bytes using byte order \a order and
+ 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()
*/
@@ -674,6 +677,9 @@ QDataStream &operator<<(QDataStream &s, const QUuid &id)
bytes = QByteArray(16, Qt::Uninitialized);
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);
data += sizeof(quint32);
qToLittleEndian(id.data2, data);
diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h
index 21833efe03..9ba6564ef0 100644
--- a/src/corelib/plugin/quuid.h
+++ b/src/corelib/plugin/quuid.h
@@ -72,7 +72,7 @@ public:
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
: 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
: QUuid{fromString(string)} {}
@@ -86,10 +86,10 @@ public:
#endif
QString toString(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;
- 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)
static QUuid fromRfc4122(const QByteArray &);
#endif
@@ -179,6 +179,16 @@ public:
ushort data2 = 0;
ushort data3 = 0;
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);
@@ -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;
-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]);
data2 = qFromBigEndian<quint16>(&uuid.data[4]);
data3 = qFromBigEndian<quint16>(&uuid.data[6]);
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 = {};
qToBigEndian(data1, &result.data[0]);
qToBigEndian(data2, &result.data[4]);
qToBigEndian(data3, &result.data[6]);
memcpy(&result.data[8], data4, sizeof(data4));
+ if (order == QSysInfo::LittleEndian)
+ return bswap(result);
return result;
}
-inline QUuid QUuid::fromBytes(const void *bytes) noexcept
+inline QUuid QUuid::fromBytes(const void *bytes, QSysInfo::Endian order) noexcept
{
Id128Bytes result = {};
memcpy(result.data, bytes, sizeof(result));
- return QUuid(result);
+ return QUuid(result, order);
}
inline bool operator<=(const QUuid &lhs, const QUuid &rhs) noexcept