diff options
Diffstat (limited to 'src/corelib/plugin/quuid.cpp')
-rw-r--r-- | src/corelib/plugin/quuid.cpp | 255 |
1 files changed, 168 insertions, 87 deletions
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 8613f96c21..42f21eea88 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -13,6 +13,9 @@ QT_BEGIN_NAMESPACE +// ensure QList of this is efficient +static_assert(QTypeInfo<QUuid::Id128Bytes>::isRelocatable); + // 16 bytes (a uint, two shorts and a uchar[8]), each represented by two hex // digits; plus four dashes and a pair of enclosing brace: 16*2 + 4 + 2 = 38. enum { MaxStringUuidLength = 38 }; @@ -139,6 +142,11 @@ static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCrypto \reentrant + \compares strong + \compareswith strong GUID + \note Comparison with GUID is Windows-only. + \endcompareswith + Using \e{U}niversally \e{U}nique \e{ID}entifiers (UUID) is a standard way to uniquely identify entities in a distributed computing environment. A UUID is a 16-byte (128-bit) number @@ -287,6 +295,125 @@ static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCrypto */ /*! + \class QUuid::Id128Bytes + \inmodule QtCore + \since 6.6 + + This trivial structure is 128 bits (16 bytes) in size and holds the binary + representation of a UUID. Applications can \c{memcpy()} its contents to and + from many other libraries' UUID or GUID structures that take 128-bit + 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 + + Creates a QUuid based on the integral \a id128 parameter. The input + \a id128 parameter is considered to have byte order \a order. + + \sa fromBytes(), toBytes(), toRfc4122(), toUInt128() +*/ + +/*! + \fn QUuid::fromUInt128(quint128 uuid, QSysInfo::Endian order) noexcept + \since 6.6 + + Creates a QUuid based on the integral \a uuid parameter. The input \a uuid + parameter is considered to have byte order \a order. + + \note This function is only present on platforms that offer a 128-bit + integer type. + + \sa toUInt128(), fromBytes(), toBytes(), toRfc4122() +*/ + +/*! + \fn quint128 QUuid::toUInt128(QSysInfo::Endian order) const noexcept + \since 6.6 + + Returns a 128-bit integer 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. + + \note This function is only present on platforms that offer a 128-bit + integer type. + + \sa toRfc4122(), fromUInt128(), toBytes(), fromBytes(), QUuid() +*/ + +/*! + \fn QUuid::Id128Bytes QUuid::toBytes(QSysInfo::Endian order) const noexcept + \since 6.6 + + Returns a 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, QSysInfo::Endian order) noexcept + \since 6.6 + + 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() +*/ + +/*! \fn QUuid::QUuid(const GUID &guid) Casts a Windows \a guid to a Qt QUuid. @@ -468,45 +595,26 @@ QUuid QUuid::createUuidV5(const QUuid &ns, const QByteArray &baseData) \since 4.8 - \sa toRfc4122(), QUuid() + \sa toRfc4122(), QUuid(), fromBytes() */ QUuid QUuid::fromRfc4122(QByteArrayView bytes) noexcept { if (bytes.isEmpty() || bytes.size() != 16) return QUuid(); - - uint d1; - ushort d2, d3; - uchar d4[8]; - - const uchar *data = reinterpret_cast<const uchar *>(bytes.data()); - - d1 = qFromBigEndian<quint32>(data); - data += sizeof(quint32); - d2 = qFromBigEndian<quint16>(data); - data += sizeof(quint16); - d3 = qFromBigEndian<quint16>(data); - data += sizeof(quint16); - - for (int i = 0; i < 8; ++i) { - d4[i] = *(data); - data++; - } - - return QUuid(d1, d2, d3, d4[0], d4[1], d4[2], d4[3], d4[4], d4[5], d4[6], d4[7]); + return fromBytes(bytes.data()); } /*! - \fn bool QUuid::operator==(const QUuid &other) const + \fn bool QUuid::operator==(const QUuid &lhs, const QUuid &rhs) - Returns \c true if this QUuid and the \a other QUuid are identical; + Returns \c true if \a lhs QUuid and the \a rhs QUuid are identical; otherwise returns \c false. */ /*! - \fn bool QUuid::operator!=(const QUuid &other) const + \fn bool QUuid::operator!=(const QUuid &lhs, const QUuid &rhs) - Returns \c true if this QUuid and the \a other QUuid are different; + Returns \c true if \a lhs QUuid and the \a rhs QUuid are different; otherwise returns \c false. */ @@ -623,27 +731,16 @@ QByteArray QUuid::toByteArray(QUuid::StringFormat mode) const \endtable + The bytes in the byte array returned by this function contains the same + binary content as toBytes(). + + \sa toBytes() \since 4.8 */ QByteArray QUuid::toRfc4122() const { - // we know how many bytes a UUID has, I hope :) - QByteArray bytes(16, Qt::Uninitialized); - uchar *data = reinterpret_cast<uchar *>(bytes.data()); - - qToBigEndian(data1, data); - data += sizeof(quint32); - qToBigEndian(data2, data); - data += sizeof(quint16); - qToBigEndian(data3, data); - data += sizeof(quint16); - - for (int i = 0; i < 8; ++i) { - *(data) = data4[i]; - data++; - } - - return bytes; + Id128Bytes bytes = toBytes(); + return QByteArrayView(bytes).toByteArray(); } #ifndef QT_NO_DATASTREAM @@ -653,14 +750,19 @@ QByteArray QUuid::toRfc4122() const */ QDataStream &operator<<(QDataStream &s, const QUuid &id) { - QByteArray bytes; + constexpr int NumBytes = sizeof(QUuid); + static_assert(NumBytes == 16, "Change the serialization format when this ever hits"); + char bytes[NumBytes]; if (s.byteOrder() == QDataStream::BigEndian) { - bytes = id.toRfc4122(); + const auto id128 = id.toBytes(); + static_assert(sizeof(id128) == NumBytes); + memcpy(bytes, &id128, NumBytes); } else { - // we know how many bytes a UUID has, I hope :) - bytes = QByteArray(16, Qt::Uninitialized); - uchar *data = reinterpret_cast<uchar *>(bytes.data()); + auto *data = bytes; + // 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); @@ -674,9 +776,9 @@ QDataStream &operator<<(QDataStream &s, const QUuid &id) } } - if (s.writeRawData(bytes.data(), 16) != 16) { + if (s.writeRawData(bytes, NumBytes) != NumBytes) s.setStatus(QDataStream::WriteFailed); - } + return s; } @@ -801,51 +903,31 @@ QUuid::Version QUuid::version() const noexcept } /*! - \fn bool QUuid::operator<(const QUuid &other) const + \fn bool QUuid::operator<(const QUuid &lhs, const QUuid &rhs) - Returns \c true if this QUuid has the same \l{Variant field} - {variant field} as the \a other QUuid and is lexicographically - \e{before} the \a other QUuid. If the \a other QUuid has a + Returns \c true if \a lhs QUuid has the same \l{Variant field} + {variant field} as the \a rhs QUuid and is lexicographically + \e{before} the \a rhs QUuid. If the \a rhs QUuid has a different variant field, the return value is determined by comparing the two \l{QUuid::Variant} {variants}. \sa variant() */ -bool QUuid::operator<(const QUuid &other) const noexcept -{ - if (variant() != other.variant()) - return variant() < other.variant(); - -#define ISLESS(f1, f2) if (f1!=f2) return (f1<f2); - ISLESS(data1, other.data1); - ISLESS(data2, other.data2); - ISLESS(data3, other.data3); - for (int n = 0; n < 8; n++) { - ISLESS(data4[n], other.data4[n]); - } -#undef ISLESS - return false; -} /*! - \fn bool QUuid::operator>(const QUuid &other) const + \fn bool QUuid::operator>(const QUuid &lhs, const QUuid &rhs) - Returns \c true if this QUuid has the same \l{Variant field} - {variant field} as the \a other QUuid and is lexicographically - \e{after} the \a other QUuid. If the \a other QUuid has a + Returns \c true if \a lhs QUuid has the same \l{Variant field} + {variant field} as the \a rhs QUuid and is lexicographically + \e{after} the \a rhs QUuid. If the \a rhs QUuid has a different variant field, the return value is determined by comparing the two \l{QUuid::Variant} {variants}. \sa variant() */ -bool QUuid::operator>(const QUuid &other) const noexcept -{ - return other < *this; -} /*! - \fn bool operator<=(const QUuid &lhs, const QUuid &rhs) - \relates QUuid + \fn bool QUuid::operator<=(const QUuid &lhs, const QUuid &rhs) \since 5.5 Returns \c true if \a lhs has the same \l{Variant field} @@ -858,8 +940,7 @@ bool QUuid::operator>(const QUuid &other) const noexcept */ /*! - \fn bool operator>=(const QUuid &lhs, const QUuid &rhs) - \relates QUuid + \fn bool QUuid::operator>=(const QUuid &lhs, const QUuid &rhs) \since 5.5 Returns \c true if \a lhs has the same \l{Variant field} @@ -895,7 +976,7 @@ QUuid QUuid::createUuid() return result; } -#else // Q_OS_WIN +#elif !defined(QT_BOOTSTRAPPED) QUuid QUuid::createUuid() { @@ -909,20 +990,20 @@ QUuid QUuid::createUuid() return result; } -#endif // !Q_OS_WIN +#endif // !Q_OS_WIN && !QT_BOOTSTRAPPED /*! - \fn bool QUuid::operator==(const GUID &guid) const + \fn bool QUuid::operator==(const QUuid &lhs, const GUID &rhs) - Returns \c true if this UUID is equal to the Windows GUID \a guid; + Returns \c true if \a lhs UUID is equal to the Windows GUID \a rhs; otherwise returns \c false. */ /*! - \fn bool QUuid::operator!=(const GUID &guid) const + \fn bool QUuid::operator!=(const QUuid &lhs, const GUID &rhs) - Returns \c true if this UUID is not equal to the Windows GUID \a - guid; otherwise returns \c false. + Returns \c true if \a lhs UUID is not equal to the Windows GUID \a rhs; + otherwise returns \c false. */ #ifndef QT_NO_DEBUG_STREAM |