1// Copyright (C) 2020 The Qt Company Ltd.
2// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "quuid.h"
6#include "quuid_p.h"
7
8#include "qcryptographichash.h"
9#include "qdatastream.h"
10#include "qdebug.h"
11#include "qendian.h"
12#include "qrandom.h"
13#include "private/qtools_p.h"
14
15QT_BEGIN_NAMESPACE
16
17// ensure QList of this is efficient
18static_assert(QTypeInfo<QUuid::Id128Bytes>::isRelocatable);
19
20// 16 bytes (a uint, two shorts and a uchar[8]), each represented by two hex
21// digits; plus four dashes and a pair of enclosing brace: 16*2 + 4 + 2 = 38.
22enum { MaxStringUuidLength = 38 };
23
24template <class Integral>
25void _q_toHex(char *&dst, Integral value)
26{
27 value = qToBigEndian(value);
28
29 const char *p = reinterpret_cast<const char *>(&value);
30
31 for (uint i = 0; i < sizeof(Integral); ++i, dst += 2) {
32 dst[0] = QtMiscUtils::toHexLower(value: (p[i] >> 4) & 0xf);
33 dst[1] = QtMiscUtils::toHexLower(value: p[i] & 0xf);
34 }
35}
36
37#if QT_VERSION_MAJOR == 7
38# warning Consider storing the UUID as simple bytes, not as {uint, ushort, short, array}
39#endif
40template <class Integral>
41bool _q_fromHex(const char *&src, Integral &value)
42{
43 value = 0;
44
45 for (uint i = 0; i < sizeof(Integral) * 2; ++i) {
46 uint ch = *src++;
47 int tmp = QtMiscUtils::fromHex(c: ch);
48 if (tmp == -1)
49 return false;
50
51 value = value * 16 + tmp;
52 }
53
54 return true;
55}
56
57static char *_q_uuidToHex(const QUuid &uuid, char *dst, QUuid::StringFormat mode = QUuid::WithBraces)
58{
59 if ((mode & QUuid::WithoutBraces) == 0)
60 *dst++ = '{';
61 _q_toHex(dst, value: uuid.data1);
62 if ((mode & QUuid::Id128) != QUuid::Id128)
63 *dst++ = '-';
64 _q_toHex(dst, value: uuid.data2);
65 if ((mode & QUuid::Id128) != QUuid::Id128)
66 *dst++ = '-';
67 _q_toHex(dst, value: uuid.data3);
68 if ((mode & QUuid::Id128) != QUuid::Id128)
69 *dst++ = '-';
70 for (int i = 0; i < 2; i++)
71 _q_toHex(dst, value: uuid.data4[i]);
72 if ((mode & QUuid::Id128) != QUuid::Id128)
73 *dst++ = '-';
74 for (int i = 2; i < 8; i++)
75 _q_toHex(dst, value: uuid.data4[i]);
76 if ((mode & QUuid::WithoutBraces) == 0)
77 *dst++ = '}';
78 return dst;
79}
80
81/*!
82 \internal
83
84 Parses the string representation of a UUID (with optional surrounding "{}")
85 by reading at most MaxStringUuidLength (38) characters from \a src, which
86 may be \nullptr. Stops at the first invalid character (which includes a
87 premature NUL).
88
89 Returns the successfully parsed QUuid, or a null QUuid in case of failure.
90*/
91Q_NEVER_INLINE
92static QUuid _q_uuidFromHex(const char *src)
93{
94 uint d1;
95 ushort d2, d3;
96 uchar d4[8];
97
98 if (src) {
99 if (*src == '{')
100 src++;
101 if (Q_LIKELY( _q_fromHex(src, d1)
102 && *src++ == '-'
103 && _q_fromHex(src, d2)
104 && *src++ == '-'
105 && _q_fromHex(src, d3)
106 && *src++ == '-'
107 && _q_fromHex(src, d4[0])
108 && _q_fromHex(src, d4[1])
109 && *src++ == '-'
110 && _q_fromHex(src, d4[2])
111 && _q_fromHex(src, d4[3])
112 && _q_fromHex(src, d4[4])
113 && _q_fromHex(src, d4[5])
114 && _q_fromHex(src, d4[6])
115 && _q_fromHex(src, d4[7]))) {
116 return QUuid(d1, d2, d3, d4[0], d4[1], d4[2], d4[3], d4[4], d4[5], d4[6], d4[7]);
117 }
118 }
119
120 return QUuid();
121}
122
123static QUuid createFromName(QUuid ns, QByteArrayView baseData, QCryptographicHash::Algorithm algorithm, int version) noexcept
124{
125 std::byte buffer[20];
126 Q_ASSERT(sizeof buffer >= size_t(QCryptographicHash::hashLength(algorithm)));
127 QByteArrayView hashResult
128 = QCryptographicHash::hashInto(buffer, data: {QByteArrayView{ns.toBytes()}, baseData}, method: algorithm);
129 Q_ASSERT(hashResult.size() >= 16);
130 hashResult.truncate(n: 16); // Sha1 will be too long
131
132 QUuid result = QUuid::fromRfc4122(hashResult);
133
134 result.data3 &= 0x0FFF;
135 result.data3 |= (version << 12);
136 result.data4[0] &= 0x3F;
137 result.data4[0] |= 0x80;
138
139 return result;
140}
141
142/*!
143 \class QUuid
144 \inmodule QtCore
145 \brief The QUuid class stores a Universally Unique Identifier (UUID).
146
147 \reentrant
148
149 \compares strong
150 \compareswith strong GUID
151 \note Comparison with GUID is Windows-only.
152 \endcompareswith
153
154 Using \e{U}niversally \e{U}nique \e{ID}entifiers (UUID) is a
155 standard way to uniquely identify entities in a distributed
156 computing environment. A UUID is a 16-byte (128-bit) number
157 generated by some algorithm that is meant to guarantee that the
158 UUID will be unique in the distributed computing environment where
159 it is used. The acronym GUID is often used instead, \e{G}lobally
160 \e{U}nique \e{ID}entifiers, but it refers to the same thing.
161
162 \target Variant field
163 Actually, the GUID is one \e{variant} of UUID. Multiple variants
164 are in use. Each UUID contains a bit field that specifies which
165 type (variant) of UUID it is. Call variant() to discover which
166 type of UUID an instance of QUuid contains. It extracts the three
167 most significant bits of byte 8 of the 16 bytes. In QUuid, byte 8
168 is \c{QUuid::data4[0]}. If you create instances of QUuid using the
169 constructor that accepts all the numeric values as parameters, use
170 the following table to set the three most significant bits of
171 parameter \c{b1}, which becomes \c{QUuid::data4[0]} and contains
172 the variant field in its three most significant bits. In the
173 table, 'x' means \e {don't care}.
174
175 \table
176 \header
177 \li msb0
178 \li msb1
179 \li msb2
180 \li Variant
181
182 \row
183 \li 0
184 \li x
185 \li x
186 \li NCS (Network Computing System)
187
188 \row
189 \li 1
190 \li 0
191 \li x
192 \li DCE (Distributed Computing Environment)
193
194 \row
195 \li 1
196 \li 1
197 \li 0
198 \li Microsoft (GUID)
199
200 \row
201 \li 1
202 \li 1
203 \li 1
204 \li Reserved for future expansion
205
206 \endtable
207
208 \target Version field
209 If variant() returns QUuid::DCE, the UUID also contains a
210 \e{version} field in the four most significant bits of
211 \c{QUuid::data3}, and you can call version() to discover which
212 version your QUuid contains. If you create instances of QUuid
213 using the constructor that accepts all the numeric values as
214 parameters, use the following table to set the four most
215 significant bits of parameter \c{w2}, which becomes
216 \c{QUuid::data3} and contains the version field in its four most
217 significant bits.
218
219 \table
220 \header
221 \li msb0
222 \li msb1
223 \li msb2
224 \li msb3
225 \li Version
226
227 \row
228 \li 0
229 \li 0
230 \li 0
231 \li 1
232 \li Time
233
234 \row
235 \li 0
236 \li 0
237 \li 1
238 \li 0
239 \li Embedded POSIX
240
241 \row
242 \li 0
243 \li 0
244 \li 1
245 \li 1
246 \li Md5(Name)
247
248 \row
249 \li 0
250 \li 1
251 \li 0
252 \li 0
253 \li Random
254
255 \row
256 \li 0
257 \li 1
258 \li 0
259 \li 1
260 \li Sha1
261
262 \endtable
263
264 The field layouts for the DCE versions listed in the table above
265 are specified in the \l{RFC 4122}
266 {Network Working Group UUID Specification}.
267
268 Most platforms provide a tool for generating new UUIDs, e.g. \c
269 uuidgen and \c guidgen. You can also use createUuid(). UUIDs
270 generated by createUuid() are of the random type. Their
271 QUuid::Version bits are set to QUuid::Random, and their
272 QUuid::Variant bits are set to QUuid::DCE. The rest of the UUID is
273 composed of random numbers. Theoretically, this means there is a
274 small chance that a UUID generated by createUuid() will not be
275 unique. But it is
276 \l{http://en.wikipedia.org/wiki/Universally_Unique_Identifier#Random_UUID_probability_of_duplicates}
277 {a \e{very} small chance}.
278
279 UUIDs can be constructed from numeric values or from strings, or
280 using the static createUuid() function. They can be converted to a
281 string with toString(). UUIDs have a variant() and a version(),
282 and null UUIDs return true from isNull().
283*/
284
285/*!
286 \enum QUuid::StringFormat
287 \since 5.11
288
289 This enum is used by toString(StringFormat) to control the formatting of the
290 string representation. The possible values are:
291
292 \value WithBraces The default, toString() will return five hex fields, separated by
293 dashes and surrounded by braces. Example:
294 {00000000-0000-0000-0000-000000000000}.
295 \value WithoutBraces Only the five dash-separated fields, without the braces. Example:
296 00000000-0000-0000-0000-000000000000.
297 \value Id128 Only the hex digits, without braces or dashes. Note that QUuid
298 cannot parse this back again as input.
299*/
300
301/*!
302 \class QUuid::Id128Bytes
303 \inmodule QtCore
304 \since 6.6
305
306 This trivial structure is 128 bits (16 bytes) in size and holds the binary
307 representation of a UUID. Applications can \c{memcpy()} its contents to and
308 from many other libraries' UUID or GUID structures that take 128-bit
309 values.
310*/
311
312/*!
313 \fn QUuid::Id128Bytes qFromBigEndian(QUuid::Id128Bytes src)
314 \since 6.6
315 \relates QUuid::Id128Bytes
316 \overload
317
318 Converts \a src from big-endian byte order and returns the struct holding
319 the binary representation of UUID in host byte order.
320
321 \sa <QtEndian>
322*/
323
324/*!
325 \fn QUuid::Id128Bytes qFromLittleEndian(QUuid::Id128Bytes src)
326 \since 6.6
327 \relates QUuid::Id128Bytes
328 \overload
329
330 Converts \a src from little-endian byte order and returns the struct holding
331 the binary representation of UUID in host byte order.
332
333 \sa <QtEndian>
334*/
335
336/*!
337 \fn QUuid::Id128Bytes qToBigEndian(QUuid::Id128Bytes src)
338 \since 6.6
339 \relates QUuid::Id128Bytes
340 \overload
341
342 Converts \a src from host byte order and returns the struct holding the
343 binary representation of UUID in big-endian byte order.
344
345 \sa <QtEndian>
346*/
347
348/*!
349 \fn QUuid::Id128Bytes qToLittleEndian(QUuid::Id128Bytes src)
350 \since 6.6
351 \relates QUuid::Id128Bytes
352 \overload
353
354 Converts \a src from host byte order and returns the struct holding the
355 binary representation of UUID in little-endian byte order.
356
357 \sa <QtEndian>
358*/
359
360/*!
361 \fn QUuid::QUuid(Id128Bytes id128, QSysInfo::Endian order) noexcept
362 \since 6.6
363
364 Creates a QUuid based on the integral \a id128 parameter. The input
365 \a id128 parameter is considered to have byte order \a order.
366
367 \sa fromBytes(), toBytes(), toRfc4122(), toUInt128()
368*/
369
370/*!
371 \fn QUuid::fromUInt128(quint128 uuid, QSysInfo::Endian order) noexcept
372 \since 6.6
373
374 Creates a QUuid based on the integral \a uuid parameter. The input \a uuid
375 parameter is considered to have byte order \a order.
376
377 \note This function is only present on platforms that offer a 128-bit
378 integer type.
379
380 \sa toUInt128(), fromBytes(), toBytes(), toRfc4122()
381*/
382
383/*!
384 \fn quint128 QUuid::toUInt128(QSysInfo::Endian order) const noexcept
385 \since 6.6
386
387 Returns a 128-bit integer created from this QUuid on the byte order
388 specified by \a order. The binary content of this function is the same as
389 toRfc4122() if the order is QSysInfo::BigEndian. See that function for more
390 details.
391
392 \note This function is only present on platforms that offer a 128-bit
393 integer type.
394
395 \sa toRfc4122(), fromUInt128(), toBytes(), fromBytes(), QUuid()
396*/
397
398/*!
399 \fn QUuid::Id128Bytes QUuid::toBytes(QSysInfo::Endian order) const noexcept
400 \since 6.6
401
402 Returns a 128-bit ID created from this QUuid on the byte order specified
403 by \a order. The binary content of this function is the same as toRfc4122()
404 if the order is QSysInfo::BigEndian. See that function for more details.
405
406 \sa toRfc4122(), fromBytes(), QUuid()
407*/
408
409/*!
410 \fn QUuid QUuid::fromBytes(const void *bytes, QSysInfo::Endian order) noexcept
411 \since 6.6
412
413 Reads 128 bits (16 bytes) from \a bytes using byte order \a order and
414 returns the QUuid corresponding to those bytes. This function does the same
415 as fromRfc4122() if the byte order \a order is QSysInfo::BigEndian.
416
417 \sa fromRfc4122()
418*/
419
420/*!
421 \fn QUuid::QUuid(const GUID &guid)
422
423 Casts a Windows \a guid to a Qt QUuid.
424
425 \warning This function is only for Windows platforms.
426*/
427
428/*!
429 \fn QUuid &QUuid::operator=(const GUID &guid)
430
431 Assigns a Windows \a guid to a Qt QUuid.
432
433 \warning This function is only for Windows platforms.
434*/
435
436/*!
437 \fn QUuid::operator GUID() const
438
439 Returns a Windows GUID from a QUuid.
440
441 \warning This function is only for Windows platforms.
442*/
443
444/*!
445 \fn QUuid::QUuid()
446
447 Creates the null UUID. toString() will output the null UUID
448 as "{00000000-0000-0000-0000-000000000000}".
449*/
450
451/*!
452 \fn QUuid::QUuid(uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3, uchar b4, uchar b5, uchar b6, uchar b7, uchar b8)
453
454 Creates a UUID with the value specified by the parameters, \a l,
455 \a w1, \a w2, \a b1, \a b2, \a b3, \a b4, \a b5, \a b6, \a b7, \a
456 b8.
457
458 Example:
459 \snippet code/src_corelib_plugin_quuid.cpp 0
460*/
461
462/*!
463 \fn QUuid::QUuid(QAnyStringView text)
464
465 Creates a QUuid object from the string \a text, which must be
466 formatted as five hex fields separated by '-', e.g.,
467 "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where each 'x' is a hex
468 digit. The curly braces shown here are optional, but it is normal to
469 include them. If the conversion fails, a null UUID is created. See
470 toString() for an explanation of how the five hex fields map to the
471 public data members in QUuid.
472
473 \note In Qt versions prior to 6.3, this constructor was an overload
474 set consisting of QString, QByteArray and \c{const char*}
475 instead of one constructor taking QAnyStringView.
476
477 \sa toString(), QUuid()
478*/
479
480/*!
481 \fn static QUuid::fromString(QAnyStringView string)
482 \since 5.10
483
484 Creates a QUuid object from the string \a string, which must be
485 formatted as five hex fields separated by '-', e.g.,
486 "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where each 'x' is a hex
487 digit. The curly braces shown here are optional, but it is normal to
488 include them. If the conversion fails, a null UUID is returned. See
489 toString() for an explanation of how the five hex fields map to the
490 public data members in QUuid.
491
492 \note In Qt versions prior to 6.3, this function was an overload
493 set consisting of QStringView and QLatin1StringView instead of
494 one function taking QAnyStringView.
495
496 \sa toString(), QUuid()
497*/
498static QUuid uuidFromString(QStringView text) noexcept
499{
500 if (text.size() > MaxStringUuidLength)
501 text.truncate(n: MaxStringUuidLength);
502
503 char latin1[MaxStringUuidLength + 1];
504 char *dst = latin1;
505
506 for (QChar ch : text)
507 *dst++ = ch.toLatin1();
508
509 *dst++ = '\0'; // don't read garbage as potentially valid data
510
511 return _q_uuidFromHex(src: latin1);
512}
513
514static QUuid uuidFromString(QLatin1StringView text) noexcept
515{
516 if (Q_UNLIKELY(text.size() < MaxStringUuidLength - 2
517 || (text.front() == '{' && text.size() < MaxStringUuidLength - 1))) {
518 // Too short. Don't call _q_uuidFromHex(); QL1Ss need not be NUL-terminated,
519 // and we don't want to read trailing garbage as potentially valid data.
520 text = QLatin1StringView();
521 }
522 return _q_uuidFromHex(src: text.data());
523}
524
525Q_ALWAYS_INLINE
526// can treat UTF-8 the same as Latin-1:
527static QUuid uuidFromString(QUtf8StringView text) noexcept
528{
529 return uuidFromString(text: QLatin1StringView(text.data(), text.size()));
530}
531
532QUuid QUuid::fromString(QAnyStringView text) noexcept
533{
534 return text.visit(v: [] (auto text) { return uuidFromString(text); });
535}
536
537/*!
538 \since 5.0
539 \fn QUuid QUuid::createUuidV3(QUuid ns, QByteArrayView baseData);
540
541 This function returns a new UUID with variant QUuid::DCE and version QUuid::Md5.
542 \a ns is the namespace and \a baseData is the basic data as described by RFC 4122.
543
544 \note In Qt versions prior to 6.8, this function took QByteArray, not
545 QByteArrayView.
546
547 \sa variant(), version(), createUuidV5(), createUuidV7()
548*/
549
550/*!
551 \since 5.0
552 \fn QUuid QUuid::createUuidV3(const QUuid &ns, const QString &baseData);
553
554 This function returns a new UUID with variant QUuid::DCE and version QUuid::Md5.
555 \a ns is the namespace and \a baseData is the basic data as described by RFC 4122.
556
557 \sa variant(), version(), createUuidV5(), createUuidV7()
558*/
559
560/*!
561 \since 5.0
562 \fn QUuid QUuid::createUuidV5(QUuid ns, QByteArrayView baseData);
563
564 This function returns a new UUID with variant QUuid::DCE and version QUuid::Sha1.
565 \a ns is the namespace and \a baseData is the basic data as described by RFC 4122.
566
567 \note In Qt versions prior to 6.8, this function took QByteArray, not
568 QByteArrayView.
569
570 \sa variant(), version(), createUuidV3()
571*/
572
573/*!
574 \since 5.0
575 \fn QUuid QUuid::createUuidV5(const QUuid &ns, const QString &baseData);
576
577 This function returns a new UUID with variant QUuid::DCE and version QUuid::Sha1.
578 \a ns is the namespace and \a baseData is the basic data as described by RFC 4122.
579
580 \sa variant(), version(), createUuidV3()
581*/
582QUuid QUuid::createUuidV3(QUuid ns, QByteArrayView baseData) noexcept
583{
584 return createFromName(ns, baseData, algorithm: QCryptographicHash::Md5, version: 3);
585}
586
587QUuid QUuid::createUuidV5(QUuid ns, QByteArrayView baseData) noexcept
588{
589 return createFromName(ns, baseData, algorithm: QCryptographicHash::Sha1, version: 5);
590}
591
592/*!
593 \since 6.9
594
595 This function returns a new UUID with variant QUuid::DCE and version
596 QUuid::UnixEpoch.
597
598 It uses a time-ordered value field derived from the number of milliseconds
599 since the UNIX Epoch as described by
600 \l {https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-7}{RFC9562}.
601
602 \sa variant(), version(), createUuidV3(), createUuidV5()
603*/
604QUuid QUuid::createUuidV7()
605{
606 return createUuidV7_internal(tp: std::chrono::system_clock::now());
607}
608
609/*!
610 Creates a QUuid object from the binary representation of the UUID, as
611 specified by RFC 4122 section 4.1.2. See toRfc4122() for a further
612 explanation of the order of \a bytes required.
613
614 The byte array accepted is NOT a human readable format.
615
616 If the conversion fails, a null UUID is created.
617
618 \note In Qt versions prior to 6.3, this function took QByteArray, not
619 QByteArrayView.
620
621 \since 4.8
622
623 \sa toRfc4122(), QUuid(), fromBytes()
624*/
625QUuid QUuid::fromRfc4122(QByteArrayView bytes) noexcept
626{
627 if (bytes.isEmpty() || bytes.size() != 16)
628 return QUuid();
629 return fromBytes(bytes: bytes.data());
630}
631
632/*!
633 \fn bool QUuid::operator==(const QUuid &lhs, const QUuid &rhs)
634
635 Returns \c true if \a lhs QUuid and the \a rhs QUuid are identical;
636 otherwise returns \c false.
637*/
638
639/*!
640 \fn bool QUuid::operator!=(const QUuid &lhs, const QUuid &rhs)
641
642 Returns \c true if \a lhs QUuid and the \a rhs QUuid are different;
643 otherwise returns \c false.
644*/
645
646/*!
647 \since 5.11
648
649 Returns the string representation of this QUuid, with the formattiong
650 controlled by the \a mode parameter. From left to right, the five hex
651 fields are obtained from the four public data members in QUuid as follows:
652
653 \table
654 \header
655 \li Field #
656 \li Source
657
658 \row
659 \li 1
660 \li data1
661
662 \row
663 \li 2
664 \li data2
665
666 \row
667 \li 3
668 \li data3
669
670 \row
671 \li 4
672 \li data4[0] .. data4[1]
673
674 \row
675 \li 5
676 \li data4[2] .. data4[7]
677
678 \endtable
679*/
680QString QUuid::toString(QUuid::StringFormat mode) const
681{
682 char latin1[MaxStringUuidLength];
683 const auto end = _q_uuidToHex(uuid: *this, dst: latin1, mode);
684 return QString::fromLatin1(str: latin1, size: end - latin1);
685}
686
687/*!
688 \since 5.11
689
690 Returns the string representation of this QUuid, with the formattiong
691 controlled by the \a mode parameter. From left to right, the five hex
692 fields are obtained from the four public data members in QUuid as follows:
693
694 \table
695 \header
696 \li Field #
697 \li Source
698
699 \row
700 \li 1
701 \li data1
702
703 \row
704 \li 2
705 \li data2
706
707 \row
708 \li 3
709 \li data3
710
711 \row
712 \li 4
713 \li data4[0] .. data4[1]
714
715 \row
716 \li 5
717 \li data4[2] .. data4[7]
718
719 \endtable
720*/
721QByteArray QUuid::toByteArray(QUuid::StringFormat mode) const
722{
723 QByteArray result(MaxStringUuidLength, Qt::Uninitialized);
724 const auto end = _q_uuidToHex(uuid: *this, dst: const_cast<char *>(result.constData()), mode);
725 result.resize(size: end - result.constData());
726 return result;
727}
728
729/*!
730 Returns the binary representation of this QUuid. The byte array is in big
731 endian format, and formatted according to RFC 4122, section 4.1.2 -
732 "Layout and byte order".
733
734 The order is as follows:
735
736 \table
737 \header
738 \li Field #
739 \li Source
740
741 \row
742 \li 1
743 \li data1
744
745 \row
746 \li 2
747 \li data2
748
749 \row
750 \li 3
751 \li data3
752
753 \row
754 \li 4
755 \li data4[0] .. data4[7]
756
757 \endtable
758
759 The bytes in the byte array returned by this function contains the same
760 binary content as toBytes().
761
762 \sa toBytes()
763 \since 4.8
764*/
765QByteArray QUuid::toRfc4122() const
766{
767 Id128Bytes bytes = toBytes();
768 return QByteArrayView(bytes).toByteArray();
769}
770
771#ifndef QT_NO_DATASTREAM
772/*!
773 \relates QUuid
774 Writes the UUID \a id to the data stream \a s.
775*/
776QDataStream &operator<<(QDataStream &s, const QUuid &id)
777{
778 constexpr int NumBytes = sizeof(QUuid);
779 static_assert(NumBytes == 16, "Change the serialization format when this ever hits");
780 char bytes[NumBytes];
781 if (s.byteOrder() == QDataStream::BigEndian) {
782 const auto id128 = id.toBytes();
783 static_assert(sizeof(id128) == NumBytes);
784 memcpy(dest: bytes, src: &id128, n: NumBytes);
785 } else {
786 auto *data = bytes;
787
788 // for historical reasons, our little-endian serialization format
789 // stores each of the UUID fields in little endian, instead of storing
790 // a little endian Id128
791 qToLittleEndian(src: id.data1, dest: data);
792 data += sizeof(quint32);
793 qToLittleEndian(src: id.data2, dest: data);
794 data += sizeof(quint16);
795 qToLittleEndian(src: id.data3, dest: data);
796 data += sizeof(quint16);
797
798 for (int i = 0; i < 8; ++i) {
799 *(data) = id.data4[i];
800 data++;
801 }
802 }
803
804 if (s.writeRawData(bytes, len: NumBytes) != NumBytes)
805 s.setStatus(QDataStream::WriteFailed);
806
807 return s;
808}
809
810/*!
811 \relates QUuid
812 Reads a UUID from the stream \a s into \a id.
813*/
814QDataStream &operator>>(QDataStream &s, QUuid &id)
815{
816 std::array<char, 16> bytes;
817 if (s.readRawData(bytes.data(), len: 16) != 16) {
818 s.setStatus(QDataStream::ReadPastEnd);
819 return s;
820 }
821
822 if (s.byteOrder() == QDataStream::BigEndian) {
823 id = QUuid::fromRfc4122(bytes);
824 } else {
825 const uchar *data = reinterpret_cast<const uchar *>(bytes.data());
826
827 id.data1 = qFromLittleEndian<quint32>(src: data);
828 data += sizeof(quint32);
829 id.data2 = qFromLittleEndian<quint16>(src: data);
830 data += sizeof(quint16);
831 id.data3 = qFromLittleEndian<quint16>(src: data);
832 data += sizeof(quint16);
833
834 for (int i = 0; i < 8; ++i) {
835 id.data4[i] = *(data);
836 data++;
837 }
838 }
839
840 return s;
841}
842#endif // QT_NO_DATASTREAM
843
844/*!
845 \fn bool QUuid::isNull() const
846
847 Returns \c true if this is the null UUID
848 {00000000-0000-0000-0000-000000000000}; otherwise returns \c false.
849*/
850
851/*!
852 \enum QUuid::Variant
853
854 This enum defines the values used in the \l{Variant field}
855 {variant field} of the UUID. The value in the variant field
856 determines the layout of the 128-bit value.
857
858 \value VarUnknown Variant is unknown
859 \value NCS Reserved for NCS (Network Computing System) backward compatibility
860 \value DCE Distributed Computing Environment, the scheme used by QUuid
861 \value Microsoft Reserved for Microsoft backward compatibility (GUID)
862 \value Reserved Reserved for future definition
863*/
864
865/*!
866 \enum QUuid::Version
867
868 This enum defines the values used in the \l{Version field}
869 {version field} of the UUID. The version field is meaningful
870 only if the value in the \l{Variant field} {variant field}
871 is QUuid::DCE.
872
873 \value VerUnknown Version is unknown
874 \value Time Time-based, by using timestamp, clock sequence, and
875 MAC network card address (if available) for the node sections
876 \value EmbeddedPOSIX DCE Security version, with embedded POSIX UUIDs
877 \value Name Name-based, by using values from a name for all sections
878 \value Md5 Alias for Name
879 \value Random Random-based, by using random numbers for all sections
880 \value Sha1 Name-based version that uses SHA-1 hashing
881 \value UnixEpoch [since 6.9] Time-based UUID using the number of
882 milliseconds since the UNIX epoch
883*/
884
885/*!
886 \fn QUuid::Variant QUuid::variant() const
887
888 Returns the value in the \l{Variant field} {variant field} of the
889 UUID. If the return value is QUuid::DCE, call version() to see
890 which layout it uses. The null UUID is considered to be of an
891 unknown variant.
892
893 \sa version()
894*/
895
896/*!
897 \fn QUuid::Version QUuid::version() const
898
899 Returns the \l{Version field} {version field} of the UUID, if the
900 UUID's \l{Variant field} {variant field} is QUuid::DCE. Otherwise
901 it returns QUuid::VerUnknown.
902
903 \sa variant()
904*/
905
906/*!
907 \fn bool QUuid::operator<(const QUuid &lhs, const QUuid &rhs)
908 \fn bool QUuid::operator>(const QUuid &lhs, const QUuid &rhs)
909 \fn bool QUuid::operator<=(const QUuid &lhs, const QUuid &rhs)
910 \fn bool QUuid::operator>=(const QUuid &lhs, const QUuid &rhs)
911 \since 5.5
912
913 Performs a comparison of \a lhs against \a rhs and returns \c true if the
914 relative sorting of \a lhs and \a rhs is correct for the operation in
915 question, \c false otherwise. Note that the sorting performed by this
916 functions may not be equal to the sorting of the strings created by
917 toString(), nor the integers toId128(), or the byte array returned by
918 toBytes() and toRfc4122().
919
920 \sa {QUuid::}{variant()}
921*/
922
923/*!
924 \fn QUuid QUuid::createUuid()
925
926 On any platform other than Windows, this function returns a new UUID with
927 variant QUuid::DCE and version QUuid::Random. On Windows, a GUID is
928 generated using the Windows API and will be of the type that the API
929 decides to create.
930
931 \sa variant(), version()
932*/
933#if defined(Q_OS_WIN)
934
935QT_BEGIN_INCLUDE_NAMESPACE
936#include <objbase.h> // For CoCreateGuid
937QT_END_INCLUDE_NAMESPACE
938
939QUuid QUuid::createUuid()
940{
941 GUID guid;
942 CoCreateGuid(&guid);
943 QUuid result = guid;
944 return result;
945}
946
947#else
948
949QUuid QUuid::createUuid()
950{
951 QUuid result(Qt::Uninitialized);
952 uint *data = &(result.data1);
953 enum { AmountToRead = 4 };
954 QRandomGenerator::system()->fillRange(buffer: data, count: AmountToRead);
955
956 result.data4[0] = (result.data4[0] & 0x3F) | 0x80; // UV_DCE
957 result.data3 = (result.data3 & 0x0FFF) | 0x4000; // UV_Random
958
959 return result;
960}
961#endif // !Q_OS_WIN
962
963/*!
964 \fn bool QUuid::operator==(const QUuid &lhs, const GUID &rhs)
965
966 Returns \c true if \a lhs UUID is equal to the Windows GUID \a rhs;
967 otherwise returns \c false.
968*/
969
970/*!
971 \fn bool QUuid::operator!=(const QUuid &lhs, const GUID &rhs)
972
973 Returns \c true if \a lhs UUID is not equal to the Windows GUID \a rhs;
974 otherwise returns \c false.
975*/
976
977#ifndef QT_NO_DEBUG_STREAM
978/*!
979 \relates QUuid
980 Writes the UUID \a id to the output stream for debugging information \a dbg.
981*/
982QDebug operator<<(QDebug dbg, const QUuid &id)
983{
984 QDebugStateSaver saver(dbg);
985 dbg.nospace() << "QUuid(" << id.toString() << ')';
986 return dbg;
987}
988#endif
989
990/*!
991 \fn size_t qHash(const QUuid &key, size_t seed)
992 \since 5.0
993 \qhashold{QUuid}
994*/
995size_t qHash(const QUuid &uuid, size_t seed) noexcept
996{
997 static_assert(std::has_unique_object_representations_v<QUuid>,
998 "Can't use qHashBits() if the type has padding holes.");
999 return qHashBits(p: &uuid, size: sizeof(QUuid), seed);
1000}
1001
1002
1003QT_END_NAMESPACE
1004

source code of qtbase/src/corelib/plugin/quuid.cpp