diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2022-11-18 12:56:38 -0800 |
---|---|---|
committer | Ivan Solovev <ivan.solovev@qt.io> | 2022-12-16 19:29:10 +0100 |
commit | 686c02224c03735356bdab987bf62644eb34cc34 (patch) | |
tree | 94500183cb86c3c6c2e26c478da18784448254b0 /src/corelib/plugin | |
parent | 0f932b9a5de21060fb9763eed24298ae929e9821 (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.cpp | 22 | ||||
-rw-r--r-- | src/corelib/plugin/quuid.h | 28 |
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 |