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