1/****************************************************************************
2**
3** Copyright (C) 2016 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(value: (p[i] >> 4) & 0xf);
65 dst[1] = QtMiscUtils::toHexLower(value: 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(c: 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, value: uuid.data1);
91 if ((mode & QUuid::Id128) != QUuid::Id128)
92 *dst++ = '-';
93 _q_toHex(dst, value: uuid.data2);
94 if ((mode & QUuid::Id128) != QUuid::Id128)
95 *dst++ = '-';
96 _q_toHex(dst, value: uuid.data3);
97 if ((mode & QUuid::Id128) != QUuid::Id128)
98 *dst++ = '-';
99 for (int i = 0; i < 2; i++)
100 _q_toHex(dst, value: uuid.data4[i]);
101 if ((mode & QUuid::Id128) != QUuid::Id128)
102 *dst++ = '-';
103 for (int i = 2; i < 8; i++)
104 _q_toHex(dst, value: 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(data: ns.toRfc4122());
160 hash.addData(data: baseData);
161 hashResult = hash.result();
162 }
163 hashResult.resize(size: 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(string: 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(n: 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(src: 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(src: text.data());
439}
440
441/*!
442 \internal
443*/
444QUuid::QUuid(const char *text)
445 : QUuid(_q_uuidFromHex(src: 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(text: 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, algorithm: QCryptographicHash::Md5, version: 3);
510}
511#endif
512
513QUuid QUuid::createUuidV5(const QUuid &ns, const QByteArray &baseData)
514{
515 return createFromName(ns, baseData, algorithm: QCryptographicHash::Sha1, version: 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>(src: data);
543 data += sizeof(quint32);
544 d2 = qFromBigEndian<quint16>(src: data);
545 data += sizeof(quint16);
546 d3 = qFromBigEndian<quint16>(src: 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 Returns the string representation of this QUuid. The string is
573 formatted as five hex fields separated by '-' and enclosed in
574 curly braces, i.e., "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where
575 'x' is a hex digit. From left to right, the five hex fields are
576 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() const
606{
607 char latin1[MaxStringUuidLength];
608 const auto end = _q_uuidToHex(uuid: *this, dst: latin1);
609 Q_ASSERT(end - latin1 == MaxStringUuidLength);
610 Q_UNUSED(end);
611 return QString::fromLatin1(str: latin1, size: MaxStringUuidLength);
612}
613
614/*!
615 \since 5.11
616
617 Returns the string representation of this QUuid, with the formattiong
618 controlled by the \a mode parameter. From left to right, the five hex
619 fields are obtained from the four public data members in QUuid as follows:
620
621 \table
622 \header
623 \li Field #
624 \li Source
625
626 \row
627 \li 1
628 \li data1
629
630 \row
631 \li 2
632 \li data2
633
634 \row
635 \li 3
636 \li data3
637
638 \row
639 \li 4
640 \li data4[0] .. data4[1]
641
642 \row
643 \li 5
644 \li data4[2] .. data4[7]
645
646 \endtable
647*/
648QString QUuid::toString(QUuid::StringFormat mode) const
649{
650 char latin1[MaxStringUuidLength];
651 const auto end = _q_uuidToHex(uuid: *this, dst: latin1, mode);
652 return QString::fromLatin1(str: latin1, size: end - latin1);
653}
654
655/*!
656 Returns the binary representation of this QUuid. The byte array is
657 formatted as five hex fields separated by '-' and enclosed in
658 curly braces, i.e., "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where
659 'x' is a hex digit. From left to right, the five hex fields are
660 obtained from the four public data members in QUuid as follows:
661
662 \table
663 \header
664 \li Field #
665 \li Source
666
667 \row
668 \li 1
669 \li data1
670
671 \row
672 \li 2
673 \li data2
674
675 \row
676 \li 3
677 \li data3
678
679 \row
680 \li 4
681 \li data4[0] .. data4[1]
682
683 \row
684 \li 5
685 \li data4[2] .. data4[7]
686
687 \endtable
688
689 \since 4.8
690*/
691QByteArray QUuid::toByteArray() const
692{
693 QByteArray result(MaxStringUuidLength, Qt::Uninitialized);
694 const auto end = _q_uuidToHex(uuid: *this, dst: const_cast<char*>(result.constData()));
695 Q_ASSERT(end - result.constData() == MaxStringUuidLength);
696 Q_UNUSED(end);
697 return result;
698}
699
700/*!
701 \since 5.11
702
703 Returns the string representation of this QUuid, with the formattiong
704 controlled by the \a mode parameter. From left to right, the five hex
705 fields are obtained from the four public data members in QUuid as follows:
706
707 \table
708 \header
709 \li Field #
710 \li Source
711
712 \row
713 \li 1
714 \li data1
715
716 \row
717 \li 2
718 \li data2
719
720 \row
721 \li 3
722 \li data3
723
724 \row
725 \li 4
726 \li data4[0] .. data4[1]
727
728 \row
729 \li 5
730 \li data4[2] .. data4[7]
731
732 \endtable
733*/
734QByteArray QUuid::toByteArray(QUuid::StringFormat mode) const
735{
736 QByteArray result(MaxStringUuidLength, Qt::Uninitialized);
737 const auto end = _q_uuidToHex(uuid: *this, dst: const_cast<char*>(result.constData()), mode);
738 result.resize(size: end - result.constData());
739 return result;
740}
741
742/*!
743 Returns the binary representation of this QUuid. The byte array is in big
744 endian format, and formatted according to RFC 4122, section 4.1.2 -
745 "Layout and byte order".
746
747 The order is as follows:
748
749 \table
750 \header
751 \li Field #
752 \li Source
753
754 \row
755 \li 1
756 \li data1
757
758 \row
759 \li 2
760 \li data2
761
762 \row
763 \li 3
764 \li data3
765
766 \row
767 \li 4
768 \li data4[0] .. data4[7]
769
770 \endtable
771
772 \since 4.8
773*/
774QByteArray QUuid::toRfc4122() const
775{
776 // we know how many bytes a UUID has, I hope :)
777 QByteArray bytes(16, Qt::Uninitialized);
778 uchar *data = reinterpret_cast<uchar*>(bytes.data());
779
780 qToBigEndian(src: data1, dest: data);
781 data += sizeof(quint32);
782 qToBigEndian(src: data2, dest: data);
783 data += sizeof(quint16);
784 qToBigEndian(src: data3, dest: data);
785 data += sizeof(quint16);
786
787 for (int i = 0; i < 8; ++i) {
788 *(data) = data4[i];
789 data++;
790 }
791
792 return bytes;
793}
794
795#ifndef QT_NO_DATASTREAM
796/*!
797 \relates QUuid
798 Writes the UUID \a id to the data stream \a s.
799*/
800QDataStream &operator<<(QDataStream &s, const QUuid &id)
801{
802 QByteArray bytes;
803 if (s.byteOrder() == QDataStream::BigEndian) {
804 bytes = id.toRfc4122();
805 } else {
806 // we know how many bytes a UUID has, I hope :)
807 bytes = QByteArray(16, Qt::Uninitialized);
808 uchar *data = reinterpret_cast<uchar*>(bytes.data());
809
810 qToLittleEndian(src: id.data1, dest: data);
811 data += sizeof(quint32);
812 qToLittleEndian(src: id.data2, dest: data);
813 data += sizeof(quint16);
814 qToLittleEndian(src: id.data3, dest: data);
815 data += sizeof(quint16);
816
817 for (int i = 0; i < 8; ++i) {
818 *(data) = id.data4[i];
819 data++;
820 }
821 }
822
823 if (s.writeRawData(bytes.data(), len: 16) != 16) {
824 s.setStatus(QDataStream::WriteFailed);
825 }
826 return s;
827}
828
829/*!
830 \relates QUuid
831 Reads a UUID from the stream \a s into \a id.
832*/
833QDataStream &operator>>(QDataStream &s, QUuid &id)
834{
835 QByteArray bytes(16, Qt::Uninitialized);
836 if (s.readRawData(bytes.data(), len: 16) != 16) {
837 s.setStatus(QDataStream::ReadPastEnd);
838 return s;
839 }
840
841 if (s.byteOrder() == QDataStream::BigEndian) {
842 id = QUuid::fromRfc4122(bytes);
843 } else {
844 const uchar *data = reinterpret_cast<const uchar *>(bytes.constData());
845
846 id.data1 = qFromLittleEndian<quint32>(src: data);
847 data += sizeof(quint32);
848 id.data2 = qFromLittleEndian<quint16>(src: data);
849 data += sizeof(quint16);
850 id.data3 = qFromLittleEndian<quint16>(src: data);
851 data += sizeof(quint16);
852
853 for (int i = 0; i < 8; ++i) {
854 id.data4[i] = *(data);
855 data++;
856 }
857 }
858
859 return s;
860}
861#endif // QT_NO_DATASTREAM
862
863/*!
864 Returns \c true if this is the null UUID
865 {00000000-0000-0000-0000-000000000000}; otherwise returns \c false.
866*/
867bool QUuid::isNull() const noexcept
868{
869 return data4[0] == 0 && data4[1] == 0 && data4[2] == 0 && data4[3] == 0 &&
870 data4[4] == 0 && data4[5] == 0 && data4[6] == 0 && data4[7] == 0 &&
871 data1 == 0 && data2 == 0 && data3 == 0;
872}
873
874/*!
875 \enum QUuid::Variant
876
877 This enum defines the values used in the \l{Variant field}
878 {variant field} of the UUID. The value in the variant field
879 determines the layout of the 128-bit value.
880
881 \value VarUnknown Variant is unknown
882 \value NCS Reserved for NCS (Network Computing System) backward compatibility
883 \value DCE Distributed Computing Environment, the scheme used by QUuid
884 \value Microsoft Reserved for Microsoft backward compatibility (GUID)
885 \value Reserved Reserved for future definition
886*/
887
888/*!
889 \enum QUuid::Version
890
891 This enum defines the values used in the \l{Version field}
892 {version field} of the UUID. The version field is meaningful
893 only if the value in the \l{Variant field} {variant field}
894 is QUuid::DCE.
895
896 \value VerUnknown Version is unknown
897 \value Time Time-based, by using timestamp, clock sequence, and
898 MAC network card address (if available) for the node sections
899 \value EmbeddedPOSIX DCE Security version, with embedded POSIX UUIDs
900 \value Name Name-based, by using values from a name for all sections
901 \value Md5 Alias for Name
902 \value Random Random-based, by using random numbers for all sections
903 \value Sha1
904*/
905
906/*!
907 \fn QUuid::Variant QUuid::variant() const
908
909 Returns the value in the \l{Variant field} {variant field} of the
910 UUID. If the return value is QUuid::DCE, call version() to see
911 which layout it uses. The null UUID is considered to be of an
912 unknown variant.
913
914 \sa version()
915*/
916QUuid::Variant QUuid::variant() const noexcept
917{
918 if (isNull())
919 return VarUnknown;
920 // Check the 3 MSB of data4[0]
921 if ((data4[0] & 0x80) == 0x00) return NCS;
922 else if ((data4[0] & 0xC0) == 0x80) return DCE;
923 else if ((data4[0] & 0xE0) == 0xC0) return Microsoft;
924 else if ((data4[0] & 0xE0) == 0xE0) return Reserved;
925 return VarUnknown;
926}
927
928/*!
929 \fn QUuid::Version QUuid::version() const
930
931 Returns the \l{Version field} {version field} of the UUID, if the
932 UUID's \l{Variant field} {variant field} is QUuid::DCE. Otherwise
933 it returns QUuid::VerUnknown.
934
935 \sa variant()
936*/
937QUuid::Version QUuid::version() const noexcept
938{
939 // Check the 4 MSB of data3
940 Version ver = (Version)(data3>>12);
941 if (isNull()
942 || (variant() != DCE)
943 || ver < Time
944 || ver > Sha1)
945 return VerUnknown;
946 return ver;
947}
948
949/*!
950 \fn bool QUuid::operator<(const QUuid &other) const
951
952 Returns \c true if this QUuid has the same \l{Variant field}
953 {variant field} as the \a other QUuid and is lexicographically
954 \e{before} the \a other QUuid. If the \a other QUuid has a
955 different variant field, the return value is determined by
956 comparing the two \l{QUuid::Variant} {variants}.
957
958 \sa variant()
959*/
960bool QUuid::operator<(const QUuid &other) const noexcept
961{
962 if (variant() != other.variant())
963 return variant() < other.variant();
964
965#define ISLESS(f1, f2) if (f1!=f2) return (f1<f2);
966 ISLESS(data1, other.data1);
967 ISLESS(data2, other.data2);
968 ISLESS(data3, other.data3);
969 for (int n = 0; n < 8; n++) {
970 ISLESS(data4[n], other.data4[n]);
971 }
972#undef ISLESS
973 return false;
974}
975
976/*!
977 \fn bool QUuid::operator>(const QUuid &other) const
978
979 Returns \c true if this QUuid has the same \l{Variant field}
980 {variant field} as the \a other QUuid and is lexicographically
981 \e{after} the \a other QUuid. If the \a other QUuid has a
982 different variant field, the return value is determined by
983 comparing the two \l{QUuid::Variant} {variants}.
984
985 \sa variant()
986*/
987bool QUuid::operator>(const QUuid &other) const noexcept
988{
989 return other < *this;
990}
991
992/*!
993 \fn bool operator<=(const QUuid &lhs, const QUuid &rhs)
994 \relates QUuid
995 \since 5.5
996
997 Returns \c true if \a lhs has the same \l{Variant field}
998 {variant field} as \a rhs and is lexicographically
999 \e{not after} \a rhs. If \a rhs has a
1000 different variant field, the return value is determined by
1001 comparing the two \l{QUuid::Variant} {variants}.
1002
1003 \sa {QUuid::}{variant()}
1004*/
1005
1006/*!
1007 \fn bool operator>=(const QUuid &lhs, const QUuid &rhs)
1008 \relates QUuid
1009 \since 5.5
1010
1011 Returns \c true if \a lhs has the same \l{Variant field}
1012 {variant field} as \a rhs and is lexicographically
1013 \e{not before} \a rhs. If \a rhs has a
1014 different variant field, the return value is determined by
1015 comparing the two \l{QUuid::Variant} {variants}.
1016
1017 \sa {QUuid::}{variant()}
1018*/
1019
1020/*!
1021 \fn QUuid QUuid::createUuid()
1022
1023 On any platform other than Windows, this function returns a new UUID with
1024 variant QUuid::DCE and version QUuid::Random. On Windows, a GUID is
1025 generated using the Windows API and will be of the type that the API
1026 decides to create.
1027
1028 \sa variant(), version()
1029*/
1030#if defined(Q_OS_WIN)
1031
1032QT_BEGIN_INCLUDE_NAMESPACE
1033#include <objbase.h> // For CoCreateGuid
1034QT_END_INCLUDE_NAMESPACE
1035
1036QUuid QUuid::createUuid()
1037{
1038 GUID guid;
1039 CoCreateGuid(&guid);
1040 QUuid result = guid;
1041 return result;
1042}
1043
1044#else // Q_OS_WIN
1045
1046QUuid QUuid::createUuid()
1047{
1048 QUuid result(Qt::Uninitialized);
1049 uint *data = &(result.data1);
1050 enum { AmountToRead = 4 };
1051 QRandomGenerator::system()->fillRange(buffer: data, count: AmountToRead);
1052
1053 result.data4[0] = (result.data4[0] & 0x3F) | 0x80; // UV_DCE
1054 result.data3 = (result.data3 & 0x0FFF) | 0x4000; // UV_Random
1055
1056 return result;
1057}
1058#endif // !Q_OS_WIN
1059
1060/*!
1061 \fn bool QUuid::operator==(const GUID &guid) const
1062
1063 Returns \c true if this UUID is equal to the Windows GUID \a guid;
1064 otherwise returns \c false.
1065*/
1066
1067/*!
1068 \fn bool QUuid::operator!=(const GUID &guid) const
1069
1070 Returns \c true if this UUID is not equal to the Windows GUID \a
1071 guid; otherwise returns \c false.
1072*/
1073
1074#ifndef QT_NO_DEBUG_STREAM
1075/*!
1076 \relates QUuid
1077 Writes the UUID \a id to the output stream for debugging information \a dbg.
1078*/
1079QDebug operator<<(QDebug dbg, const QUuid &id)
1080{
1081 QDebugStateSaver saver(dbg);
1082 dbg.nospace() << "QUuid(" << id.toString() << ')';
1083 return dbg;
1084}
1085#endif
1086
1087/*!
1088 \since 5.0
1089 \relates QUuid
1090 Returns a hash of the UUID \a uuid, using \a seed to seed the calculation.
1091*/
1092uint qHash(const QUuid &uuid, uint seed) noexcept
1093{
1094 return uuid.data1 ^ uuid.data2 ^ (uuid.data3 << 16)
1095 ^ ((uuid.data4[0] << 24) | (uuid.data4[1] << 16) | (uuid.data4[2] << 8) | uuid.data4[3])
1096 ^ ((uuid.data4[4] << 24) | (uuid.data4[5] << 16) | (uuid.data4[6] << 8) | uuid.data4[7])
1097 ^ seed;
1098}
1099
1100
1101QT_END_NAMESPACE
1102

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