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 
50 QT_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.
54 enum { MaxStringUuidLength = 38 };
55 
56 template <class Integral>
_q_toHex(char * & dst,Integral value)57 void _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 
69 template <class Integral>
_q_fromHex(const char * & src,Integral & value)70 bool _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 
_q_uuidToHex(const QUuid & uuid,char * dst,QUuid::StringFormat mode=QUuid::WithBraces)86 static 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 */
120 Q_NEVER_INLINE
_q_uuidFromHex(const char * src)121 static 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 
createFromName(const QUuid & ns,const QByteArray & baseData,QCryptographicHash::Algorithm algorithm,int version)152 static 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 */
QUuid(const QString & text)382 QUuid::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 */
fromString(QStringView text)400 QUuid 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 */
fromString(QLatin1String text)430 QUuid 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 */
QUuid(const char * text)444 QUuid::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 */
QUuid(const QByteArray & text)462 QUuid::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
createUuidV3(const QUuid & ns,const QByteArray & baseData)507 QUuid QUuid::createUuidV3(const QUuid &ns, const QByteArray &baseData)
508 {
509     return createFromName(ns, baseData, QCryptographicHash::Md5, 3);
510 }
511 #endif
512 
createUuidV5(const QUuid & ns,const QByteArray & baseData)513 QUuid 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 */
fromRfc4122(const QByteArray & bytes)531 QUuid 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     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 */
toString() const605 QString QUuid::toString() const
606 {
607     char latin1[MaxStringUuidLength];
608     const auto end = _q_uuidToHex(*this, latin1);
609     Q_ASSERT(end - latin1 == MaxStringUuidLength);
610     Q_UNUSED(end);
611     return QString::fromLatin1(latin1, 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 */
toString(QUuid::StringFormat mode) const648 QString QUuid::toString(QUuid::StringFormat mode) const
649 {
650     char latin1[MaxStringUuidLength];
651     const auto end = _q_uuidToHex(*this, latin1, mode);
652     return QString::fromLatin1(latin1, 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 */
toByteArray() const691 QByteArray QUuid::toByteArray() const
692 {
693     QByteArray result(MaxStringUuidLength, Qt::Uninitialized);
694     const auto end = _q_uuidToHex(*this, 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 */
toByteArray(QUuid::StringFormat mode) const734 QByteArray QUuid::toByteArray(QUuid::StringFormat mode) const
735 {
736     QByteArray result(MaxStringUuidLength, Qt::Uninitialized);
737     const auto end = _q_uuidToHex(*this, const_cast<char*>(result.constData()), mode);
738     result.resize(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 */
toRfc4122() const774 QByteArray 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(data1, data);
781     data += sizeof(quint32);
782     qToBigEndian(data2, data);
783     data += sizeof(quint16);
784     qToBigEndian(data3, 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 */
operator <<(QDataStream & s,const QUuid & id)800 QDataStream &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(id.data1, data);
811         data += sizeof(quint32);
812         qToLittleEndian(id.data2, data);
813         data += sizeof(quint16);
814         qToLittleEndian(id.data3, 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(), 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 */
operator >>(QDataStream & s,QUuid & id)833 QDataStream &operator>>(QDataStream &s, QUuid &id)
834 {
835     QByteArray bytes(16, Qt::Uninitialized);
836     if (s.readRawData(bytes.data(), 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>(data);
847         data += sizeof(quint32);
848         id.data2 = qFromLittleEndian<quint16>(data);
849         data += sizeof(quint16);
850         id.data3 = qFromLittleEndian<quint16>(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 */
isNull() const867 bool 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 */
variant() const916 QUuid::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 */
version() const937 QUuid::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 */
operator <(const QUuid & other) const960 bool 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 */
operator >(const QUuid & other) const987 bool 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 
1032 QT_BEGIN_INCLUDE_NAMESPACE
1033 #include <objbase.h> // For CoCreateGuid
1034 QT_END_INCLUDE_NAMESPACE
1035 
createUuid()1036 QUuid QUuid::createUuid()
1037 {
1038     GUID guid;
1039     CoCreateGuid(&guid);
1040     QUuid result = guid;
1041     return result;
1042 }
1043 
1044 #else // Q_OS_WIN
1045 
createUuid()1046 QUuid QUuid::createUuid()
1047 {
1048     QUuid result(Qt::Uninitialized);
1049     uint *data = &(result.data1);
1050     enum { AmountToRead = 4 };
1051     QRandomGenerator::system()->fillRange(data, 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 */
operator <<(QDebug dbg,const QUuid & id)1079 QDebug 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 */
qHash(const QUuid & uuid,uint seed)1092 uint 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 
1101 QT_END_NAMESPACE
1102