File indexing completed on 2025-01-18 10:07:41
0001
0002
0003
0004 #ifndef QUUID_H
0005 #define QUUID_H
0006
0007 #include <QtCore/qendian.h>
0008 #include <QtCore/qstring.h>
0009
0010 #if defined(Q_OS_WIN) || defined(Q_QDOC)
0011 #ifndef GUID_DEFINED
0012 #define GUID_DEFINED
0013 typedef struct _GUID
0014 {
0015 ulong Data1;
0016 ushort Data2;
0017 ushort Data3;
0018 uchar Data4[8];
0019 } GUID, *REFGUID, *LPGUID;
0020 #endif
0021 #endif
0022
0023 #if defined(Q_OS_DARWIN) || defined(Q_QDOC)
0024 Q_FORWARD_DECLARE_CF_TYPE(CFUUID);
0025 Q_FORWARD_DECLARE_OBJC_CLASS(NSUUID);
0026 #endif
0027
0028 QT_BEGIN_NAMESPACE
0029
0030 class Q_CORE_EXPORT QUuid
0031 {
0032 QUuid(Qt::Initialization) {}
0033 public:
0034 enum Variant {
0035 VarUnknown =-1,
0036 NCS = 0,
0037 DCE = 2,
0038 Microsoft = 6,
0039 Reserved = 7
0040 };
0041
0042 enum Version {
0043 VerUnknown =-1,
0044 Time = 1,
0045 EmbeddedPOSIX = 2,
0046 Md5 = 3,
0047 Name = Md5,
0048 Random = 4,
0049 Sha1 = 5
0050 };
0051
0052 enum StringFormat {
0053 WithBraces = 0,
0054 WithoutBraces = 1,
0055 Id128 = 3
0056 };
0057
0058 union alignas(16) Id128Bytes {
0059 quint8 data[16];
0060 quint16 data16[8];
0061 quint32 data32[4];
0062 quint64 data64[2];
0063 #if defined(__SIZEOF_INT128__)
0064 QT_WARNING_PUSH
0065 QT_WARNING_DISABLE_GCC("-Wpedantic")
0066 unsigned __int128 data128[1];
0067 QT_WARNING_POP
0068 #elif defined(QT_SUPPORTS_INT128)
0069 # error "struct QUuid::Id128Bytes should not depend on QT_SUPPORTS_INT128 for ABI reasons."
0070 # error "Adjust the declaration of the `data128` member above so it is always defined if it's " \
0071 "supported by the current compiler/architecture in any configuration."
0072 #endif
0073
0074 constexpr explicit operator QByteArrayView() const noexcept
0075 {
0076 return QByteArrayView(data, sizeof(data));
0077 }
0078
0079 friend constexpr Id128Bytes qbswap(Id128Bytes b) noexcept
0080 {
0081
0082 auto b0 = qbswap(b.data64[0]);
0083 auto b1 = qbswap(b.data64[1]);
0084 b.data64[0] = b1;
0085 b.data64[1] = b0;
0086 return b;
0087 }
0088 };
0089
0090 constexpr QUuid() noexcept : data1(0), data2(0), data3(0), data4{0,0,0,0,0,0,0,0} {}
0091
0092 constexpr QUuid(uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3,
0093 uchar b4, uchar b5, uchar b6, uchar b7, uchar b8) noexcept
0094 : data1(l), data2(w1), data3(w2), data4{b1, b2, b3, b4, b5, b6, b7, b8} {}
0095 explicit inline QUuid(Id128Bytes id128, QSysInfo::Endian order = QSysInfo::BigEndian) noexcept;
0096
0097 explicit QUuid(QAnyStringView string) noexcept
0098 : QUuid{fromString(string)} {}
0099 static QUuid fromString(QAnyStringView string) noexcept;
0100 #if QT_CORE_REMOVED_SINCE(6, 3)
0101 explicit QUuid(const QString &);
0102 static QUuid fromString(QStringView string) noexcept;
0103 static QUuid fromString(QLatin1StringView string) noexcept;
0104 explicit QUuid(const char *);
0105 explicit QUuid(const QByteArray &);
0106 #endif
0107 QString toString(StringFormat mode = WithBraces) const;
0108 QByteArray toByteArray(StringFormat mode = WithBraces) const;
0109 inline Id128Bytes toBytes(QSysInfo::Endian order = QSysInfo::BigEndian) const noexcept;
0110 QByteArray toRfc4122() const;
0111
0112 static inline QUuid fromBytes(const void *bytes, QSysInfo::Endian order = QSysInfo::BigEndian);
0113 #if QT_CORE_REMOVED_SINCE(6, 3)
0114 static QUuid fromRfc4122(const QByteArray &);
0115 #endif
0116 static QUuid fromRfc4122(QByteArrayView) noexcept;
0117
0118 bool isNull() const noexcept;
0119
0120 #ifdef QT_SUPPORTS_INT128
0121 static constexpr QUuid fromUInt128(quint128 uuid, QSysInfo::Endian order = QSysInfo::BigEndian) noexcept;
0122 constexpr quint128 toUInt128(QSysInfo::Endian order = QSysInfo::BigEndian) const noexcept;
0123 #endif
0124
0125 constexpr bool operator==(const QUuid &orig) const noexcept
0126 {
0127 if (data1 != orig.data1 || data2 != orig.data2 ||
0128 data3 != orig.data3)
0129 return false;
0130
0131 for (uint i = 0; i < 8; i++)
0132 if (data4[i] != orig.data4[i])
0133 return false;
0134
0135 return true;
0136 }
0137
0138 constexpr bool operator!=(const QUuid &orig) const noexcept
0139 {
0140 return !(*this == orig);
0141 }
0142
0143 bool operator<(const QUuid &other) const noexcept;
0144 bool operator>(const QUuid &other) const noexcept;
0145
0146 #if defined(Q_OS_WIN) || defined(Q_QDOC)
0147
0148
0149 constexpr QUuid(const GUID &guid) noexcept
0150 : data1(guid.Data1), data2(guid.Data2), data3(guid.Data3),
0151 data4{guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
0152 guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]} {}
0153
0154 constexpr QUuid &operator=(const GUID &guid) noexcept
0155 {
0156 *this = QUuid(guid);
0157 return *this;
0158 }
0159
0160 constexpr operator GUID() const noexcept
0161 {
0162 GUID guid = { data1, data2, data3, { data4[0], data4[1], data4[2], data4[3], data4[4], data4[5], data4[6], data4[7] } };
0163 return guid;
0164 }
0165
0166 constexpr bool operator==(const GUID &guid) const noexcept
0167 {
0168 return *this == QUuid(guid);
0169 }
0170
0171 constexpr bool operator!=(const GUID &guid) const noexcept
0172 {
0173 return !(*this == guid);
0174 }
0175 #endif
0176 static QUuid createUuid();
0177 #ifndef QT_BOOTSTRAPPED
0178 static QUuid createUuidV3(const QUuid &ns, const QByteArray &baseData);
0179 #endif
0180 static QUuid createUuidV5(const QUuid &ns, const QByteArray &baseData);
0181 #ifndef QT_BOOTSTRAPPED
0182 static inline QUuid createUuidV3(const QUuid &ns, const QString &baseData)
0183 {
0184 return QUuid::createUuidV3(ns, baseData.toUtf8());
0185 }
0186 #endif
0187
0188 static inline QUuid createUuidV5(const QUuid &ns, const QString &baseData)
0189 {
0190 return QUuid::createUuidV5(ns, baseData.toUtf8());
0191 }
0192
0193 QUuid::Variant variant() const noexcept;
0194 QUuid::Version version() const noexcept;
0195
0196 #if defined(Q_OS_DARWIN) || defined(Q_QDOC)
0197 static QUuid fromCFUUID(CFUUIDRef uuid);
0198 CFUUIDRef toCFUUID() const Q_DECL_CF_RETURNS_RETAINED;
0199 static QUuid fromNSUUID(const NSUUID *uuid);
0200 NSUUID *toNSUUID() const Q_DECL_NS_RETURNS_AUTORELEASED;
0201 #endif
0202
0203 uint data1;
0204 ushort data2;
0205 ushort data3;
0206 uchar data4[8];
0207 };
0208
0209 Q_DECLARE_TYPEINFO(QUuid, Q_PRIMITIVE_TYPE);
0210
0211 #ifndef QT_NO_DATASTREAM
0212 Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QUuid &);
0213 Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QUuid &);
0214 #endif
0215
0216 #ifndef QT_NO_DEBUG_STREAM
0217 Q_CORE_EXPORT QDebug operator<<(QDebug, const QUuid &);
0218 #endif
0219
0220 Q_CORE_EXPORT size_t qHash(const QUuid &uuid, size_t seed = 0) noexcept;
0221
0222 QUuid::QUuid(Id128Bytes uuid, QSysInfo::Endian order) noexcept
0223 {
0224 if (order == QSysInfo::LittleEndian)
0225 uuid = qbswap(uuid);
0226 data1 = qFromBigEndian<quint32>(&uuid.data[0]);
0227 data2 = qFromBigEndian<quint16>(&uuid.data[4]);
0228 data3 = qFromBigEndian<quint16>(&uuid.data[6]);
0229 memcpy(data4, &uuid.data[8], sizeof(data4));
0230 }
0231
0232 QUuid::Id128Bytes QUuid::toBytes(QSysInfo::Endian order) const noexcept
0233 {
0234 Id128Bytes result = {};
0235 qToBigEndian(data1, &result.data[0]);
0236 qToBigEndian(data2, &result.data[4]);
0237 qToBigEndian(data3, &result.data[6]);
0238 memcpy(&result.data[8], data4, sizeof(data4));
0239 if (order == QSysInfo::LittleEndian)
0240 return qbswap(result);
0241 return result;
0242 }
0243
0244 QUuid QUuid::fromBytes(const void *bytes, QSysInfo::Endian order)
0245 {
0246 Id128Bytes result = {};
0247 memcpy(result.data, bytes, sizeof(result));
0248 return QUuid(result, order);
0249 }
0250
0251 #ifdef QT_SUPPORTS_INT128
0252 constexpr QUuid QUuid::fromUInt128(quint128 uuid, QSysInfo::Endian order) noexcept
0253 {
0254 QUuid result = {};
0255 if (order == QSysInfo::BigEndian) {
0256 result.data1 = qFromBigEndian<quint32>(int(uuid));
0257 result.data2 = qFromBigEndian<quint16>(ushort(uuid >> 32));
0258 result.data3 = qFromBigEndian<quint16>(ushort(uuid >> 48));
0259 for (int i = 0; i < 8; ++i)
0260 result.data4[i] = uchar(uuid >> (64 + i * 8));
0261 } else {
0262 result.data1 = qFromLittleEndian<quint32>(uint(uuid >> 96));
0263 result.data2 = qFromLittleEndian<quint16>(ushort(uuid >> 80));
0264 result.data3 = qFromLittleEndian<quint16>(ushort(uuid >> 64));
0265 for (int i = 0; i < 8; ++i)
0266 result.data4[i] = uchar(uuid >> (56 - i * 8));
0267 }
0268 return result;
0269 }
0270
0271 constexpr quint128 QUuid::toUInt128(QSysInfo::Endian order) const noexcept
0272 {
0273 quint128 result = {};
0274 if (order == QSysInfo::BigEndian) {
0275 for (int i = 0; i < 8; ++i)
0276 result |= quint64(data4[i]) << (i * 8);
0277 result = result << 64;
0278 result |= quint64(qToBigEndian<quint16>(data3)) << 48;
0279 result |= quint64(qToBigEndian<quint16>(data2)) << 32;
0280 result |= qToBigEndian<quint32>(data1);
0281 } else {
0282 result = qToLittleEndian<quint32>(data1);
0283 result = result << 32;
0284 result |= quint64(qToLittleEndian<quint16>(data2)) << 16;
0285 result |= quint64(qToLittleEndian<quint16>(data3));
0286 result = result << 64;
0287 for (int i = 0; i < 8; ++i)
0288 result |= quint64(data4[i]) << (56 - i * 8);
0289 }
0290 return result;
0291 }
0292 #endif
0293
0294 inline bool operator<=(const QUuid &lhs, const QUuid &rhs) noexcept
0295 { return !(rhs < lhs); }
0296 inline bool operator>=(const QUuid &lhs, const QUuid &rhs) noexcept
0297 { return !(lhs < rhs); }
0298
0299 #if defined(Q_QDOC)
0300
0301
0302 QUuid::Id128Bytes qFromBigEndian(QUuid::Id128Bytes src);
0303 QUuid::Id128Bytes qFromLittleEndian(QUuid::Id128Bytes src);
0304 QUuid::Id128Bytes qToBigEndian(QUuid::Id128Bytes src);
0305 QUuid::Id128Bytes qToLittleEndian(QUuid::Id128Bytes src);
0306 #endif
0307
0308 QT_END_NAMESPACE
0309
0310 #endif