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