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

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