diff options
Diffstat (limited to 'src/corelib/plugin/quuid.cpp')
-rw-r--r-- | src/corelib/plugin/quuid.cpp | 191 |
1 files changed, 144 insertions, 47 deletions
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 8613f96c21..9c7216c3c5 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 }; @@ -287,6 +290,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,32 +590,13 @@ 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()); } /*! @@ -623,27 +726,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 +745,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 +771,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; } @@ -895,7 +992,7 @@ QUuid QUuid::createUuid() return result; } -#else // Q_OS_WIN +#elif !defined(QT_BOOTSTRAPPED) QUuid QUuid::createUuid() { @@ -909,7 +1006,7 @@ QUuid QUuid::createUuid() return result; } -#endif // !Q_OS_WIN +#endif // !Q_OS_WIN && !QT_BOOTSTRAPPED /*! \fn bool QUuid::operator==(const GUID &guid) const |