1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtCore module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
44 #include "qdatastream.h"
49 #ifndef QT_NO_QUUID_STRING
50 template <class Char, class Integral>
51 void _q_toHex(Char *&dst, Integral value)
53 static const char digits[] = "0123456789abcdef";
55 value = qToBigEndian(value);
57 const char* p = reinterpret_cast<const char*>(&value);
59 for (uint i = 0; i < sizeof(Integral); ++i, dst += 2) {
60 uint j = (p[i] >> 4) & 0xf;
61 dst[0] = Char(digits[j]);
63 dst[1] = Char(digits[j]);
67 template <class Char, class Integral>
68 bool _q_fromHex(const Char *&src, Integral &value)
72 for (uint i = 0; i < sizeof(Integral) * 2; ++i) {
75 if (ch >= '0' && ch <= '9')
77 else if (ch >= 'a' && ch <= 'f')
79 else if (ch >= 'A' && ch <= 'F')
84 value = value * 16 + tmp;
91 void _q_uuidToHex(Char *&dst, const uint &d1, const ushort &d2, const ushort &d3, const uchar (&d4)[8])
100 for (int i = 0; i < 2; i++)
101 _q_toHex(dst, d4[i]);
103 for (int i = 2; i < 8; i++)
104 _q_toHex(dst, d4[i]);
108 template <class Char>
109 bool _q_uuidFromHex(const Char *&src, uint &d1, ushort &d2, ushort &d3, uchar (&d4)[8])
111 if (*src == Char('{'))
113 if (!_q_fromHex(src, d1)
114 || *src++ != Char('-')
115 || !_q_fromHex(src, d2)
116 || *src++ != Char('-')
117 || !_q_fromHex(src, d3)
118 || *src++ != Char('-')
119 || !_q_fromHex(src, d4[0])
120 || !_q_fromHex(src, d4[1])
121 || *src++ != Char('-')
122 || !_q_fromHex(src, d4[2])
123 || !_q_fromHex(src, d4[3])
124 || !_q_fromHex(src, d4[4])
125 || !_q_fromHex(src, d4[5])
126 || !_q_fromHex(src, d4[6])
127 || !_q_fromHex(src, d4[7])) {
137 \brief The QUuid class stores a Universally Unique Identifier (UUID).
141 Using \e{U}niversally \e{U}nique \e{ID}entifiers (UUID) is a
142 standard way to uniquely identify entities in a distributed
143 computing environment. A UUID is a 16-byte (128-bit) number
144 generated by some algorithm that is meant to guarantee that the
145 UUID will be unique in the distributed computing environment where
146 it is used. The acronym GUID is often used instead, \e{G}lobally
147 \e{U}nique \e{ID}entifiers, but it refers to the same thing.
149 \target Variant field
150 Actually, the GUID is one \e{variant} of UUID. Multiple variants
151 are in use. Each UUID contains a bit field that specifies which
152 type (variant) of UUID it is. Call variant() to discover which
153 type of UUID an instance of QUuid contains. It extracts the three
154 most signifcant bits of byte 8 of the 16 bytes. In QUuid, byte 8
155 is \c{QUuid::data4[0]}. If you create instances of QUuid using the
156 constructor that accepts all the numeric values as parameters, use
157 the following table to set the three most significant bits of
158 parameter \c{b1}, which becomes \c{QUuid::data4[0]} and contains
159 the variant field in its three most significant bits. In the
160 table, 'x' means \e {don't care}.
173 \o NCS (Network Computing System)
179 \o DCE (Distributed Computing Environment)
191 \o Reserved for future expansion
195 \target Version field
196 If variant() returns QUuid::DCE, the UUID also contains a
197 \e{version} field in the four most significant bits of
198 \c{QUuid::data3}, and you can call version() to discover which
199 version your QUuid contains. If you create instances of QUuid
200 using the constructor that accepts all the numeric values as
201 parameters, use the following table to set the four most
202 significant bits of parameter \c{w2}, which becomes
203 \c{QUuid::data3} and contains the version field in its four most
244 The field layouts for the DCE versions listed in the table above
245 are specified in the \l{http://www.ietf.org/rfc/rfc4122.txt}
246 {Network Working Group UUID Specification}.
248 Most platforms provide a tool for generating new UUIDs, e.g. \c
249 uuidgen and \c guidgen. You can also use createUuid(). UUIDs
250 generated by createUuid() are of the random type. Their
251 QUuid::Version bits are set to QUuid::Random, and their
252 QUuid::Variant bits are set to QUuid::DCE. The rest of the UUID is
253 composed of random numbers. Theoretically, this means there is a
254 small chance that a UUID generated by createUuid() will not be
256 \l{http://en.wikipedia.org/wiki/Universally_Unique_Identifier#Random_UUID_probability_of_duplicates}
257 {a \e{very} small chance}.
259 UUIDs can be constructed from numeric values or from strings, or
260 using the static createUuid() function. They can be converted to a
261 string with toString(). UUIDs have a variant() and a version(),
262 and null UUIDs return true from isNull().
266 \fn QUuid::QUuid(const GUID &guid)
268 Casts a Windows \a guid to a Qt QUuid.
270 \warning This function is only for Windows platforms.
274 \fn QUuid &QUuid::operator=(const GUID &guid)
276 Assigns a Windows \a guid to a Qt QUuid.
278 \warning This function is only for Windows platforms.
282 \fn QUuid::operator GUID() const
284 Returns a Windows GUID from a QUuid.
286 \warning This function is only for Windows platforms.
292 Creates the null UUID. toString() will output the null UUID
293 as "{00000000-0000-0000-0000-000000000000}".
297 \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)
299 Creates a UUID with the value specified by the parameters, \a l,
300 \a w1, \a w2, \a b1, \a b2, \a b3, \a b4, \a b5, \a b6, \a b7, \a
304 \snippet doc/src/snippets/code/src_corelib_plugin_quuid.cpp 0
307 #ifndef QT_NO_QUUID_STRING
309 Creates a QUuid object from the string \a text, which must be
310 formatted as five hex fields separated by '-', e.g.,
311 "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where 'x' is a hex
312 digit. The curly braces shown here are optional, but it is normal to
313 include them. If the conversion fails, a null UUID is created. See
314 toString() for an explanation of how the five hex fields map to the
315 public data members in QUuid.
317 \sa toString(), QUuid()
319 QUuid::QUuid(const QString &text)
321 if (text.length() < 36) {
326 const ushort *data = reinterpret_cast<const ushort *>(text.unicode());
328 if (*data == '{' && text.length() < 37) {
333 if (!_q_uuidFromHex(data, data1, data2, data3, data4)) {
342 QUuid::QUuid(const char *text)
344 *this = QUuid(QString::fromLatin1(text));
349 \fn bool QUuid::operator==(const QUuid &other) const
351 Returns true if this QUuid and the \a other QUuid are identical;
352 otherwise returns false.
356 \fn bool QUuid::operator!=(const QUuid &other) const
358 Returns true if this QUuid and the \a other QUuid are different;
359 otherwise returns false.
361 #ifndef QT_NO_QUUID_STRING
363 \fn QUuid::operator QString() const
365 Returns the string representation of the uuid.
371 Returns the string representation of this QUuid. The string is
372 formatted as five hex fields separated by '-' and enclosed in
373 curly braces, i.e., "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where
374 'x' is a hex digit. From left to right, the five hex fields are
375 obtained from the four public data members in QUuid as follows:
396 \o data4[0] .. data4[1]
400 \o data4[2] .. data4[7]
404 QString QUuid::toString() const
406 QString result(38, Qt::Uninitialized);
407 ushort *data = (ushort *)result.unicode();
409 _q_uuidToHex(data, data1, data2, data3, data4);
415 #ifndef QT_NO_DATASTREAM
418 Writes the UUID \a id to the data stream \a s.
420 QDataStream &operator<<(QDataStream &s, const QUuid &id)
422 s << (quint32)id.data1;
423 s << (quint16)id.data2;
424 s << (quint16)id.data3;
425 for (int i = 0; i < 8; i++)
426 s << (quint8)id.data4[i];
432 Reads a UUID from the stream \a s into \a id.
434 QDataStream &operator>>(QDataStream &s, QUuid &id)
445 for (int i = 0; i < 8; i++) {
451 #endif // QT_NO_DATASTREAM
454 Returns true if this is the null UUID
455 {00000000-0000-0000-0000-000000000000}; otherwise returns false.
457 bool QUuid::isNull() const
459 return data4[0] == 0 && data4[1] == 0 && data4[2] == 0 && data4[3] == 0 &&
460 data4[4] == 0 && data4[5] == 0 && data4[6] == 0 && data4[7] == 0 &&
461 data1 == 0 && data2 == 0 && data3 == 0;
467 This enum defines the values used in the \l{Variant field}
468 {variant field} of the UUID. The value in the variant field
469 determines the layout of the 128-bit value.
471 \value VarUnknown Variant is unknown
472 \value NCS Reserved for NCS (Network Computing System) backward compatibility
473 \value DCE Distributed Computing Environment, the scheme used by QUuid
474 \value Microsoft Reserved for Microsoft backward compatibility (GUID)
475 \value Reserved Reserved for future definition
481 This enum defines the values used in the \l{Version field}
482 {version field} of the UUID. The version field is meaningful
483 only if the value in the \l{Variant field} {variant field}
486 \value VerUnknown Version is unknown
487 \value Time Time-based, by using timestamp, clock sequence, and
488 MAC network card address (if available) for the node sections
489 \value EmbeddedPOSIX DCE Security version, with embedded POSIX UUIDs
490 \value Name Name-based, by using values from a name for all sections
491 \value Random Random-based, by using random numbers for all sections
495 \fn QUuid::Variant QUuid::variant() const
497 Returns the value in the \l{Variant field} {variant field} of the
498 UUID. If the return value is QUuid::DCE, call version() to see
499 which layout it uses. The null UUID is considered to be of an
504 QUuid::Variant QUuid::variant() const
508 // Check the 3 MSB of data4[0]
509 if ((data4[0] & 0x80) == 0x00) return NCS;
510 else if ((data4[0] & 0xC0) == 0x80) return DCE;
511 else if ((data4[0] & 0xE0) == 0xC0) return Microsoft;
512 else if ((data4[0] & 0xE0) == 0xE0) return Reserved;
517 \fn QUuid::Version QUuid::version() const
519 Returns the \l{Version field} {version field} of the UUID, if the
520 UUID's \l{Variant field} {variant field} is QUuid::DCE. Otherwise
521 it returns QUuid::VerUnknown.
525 QUuid::Version QUuid::version() const
527 // Check the 4 MSB of data3
528 Version ver = (Version)(data3>>12);
530 || (variant() != DCE)
538 \fn bool QUuid::operator<(const QUuid &other) const
540 Returns true if this QUuid has the same \l{Variant field}
541 {variant field} as the \a other QUuid and is lexicographically
542 \e{before} the \a other QUuid. If the \a other QUuid has a
543 different variant field, the return value is determined by
544 comparing the two \l{QUuid::Variant} {variants}.
548 #define ISLESS(f1, f2) if (f1!=f2) return (f1<f2);
549 bool QUuid::operator<(const QUuid &other) const
551 if (variant() != other.variant())
552 return variant() < other.variant();
554 ISLESS(data1, other.data1);
555 ISLESS(data2, other.data2);
556 ISLESS(data3, other.data3);
557 for (int n = 0; n < 8; n++) {
558 ISLESS(data4[n], other.data4[n]);
564 \fn bool QUuid::operator>(const QUuid &other) const
566 Returns true if this QUuid has the same \l{Variant field}
567 {variant field} as the \a other QUuid and is lexicographically
568 \e{after} the \a other QUuid. If the \a other QUuid has a
569 different variant field, the return value is determined by
570 comparing the two \l{QUuid::Variant} {variants}.
574 #define ISMORE(f1, f2) if (f1!=f2) return (f1>f2);
575 bool QUuid::operator>(const QUuid &other) const
577 if (variant() != other.variant())
578 return variant() > other.variant();
580 ISMORE(data1, other.data1);
581 ISMORE(data2, other.data2);
582 ISMORE(data3, other.data3);
583 for (int n = 0; n < 8; n++) {
584 ISMORE(data4[n], other.data4[n]);
590 \fn QUuid QUuid::createUuid()
592 On any platform other than Windows, this function returns a new
593 UUID with variant QUuid::DCE and version QUuid::Random. If
594 the /dev/urandom device exists, then the numbers used to construct
595 the UUID will be of cryptographic quality, which will make the UUID
596 unique. Otherwise, the numbers of the UUID will be obtained from
597 the local pseudo-random number generator (qrand(), which is seeded
598 by qsrand()) which is usually not of cryptograhic quality, which
599 means that the UUID can't be guaranteed to be unique.
601 On a Windows platform, a GUID is generated, which almost certainly
602 \e{will} be unique, on this or any other system, networked or not.
604 \sa variant(), version()
606 #if defined(Q_OS_WIN32) && ! defined(Q_CC_MWERKS)
608 QT_BEGIN_INCLUDE_NAMESPACE
609 #include <objbase.h> // For CoCreateGuid
610 QT_END_INCLUDE_NAMESPACE
612 QUuid QUuid::createUuid()
622 QT_BEGIN_INCLUDE_NAMESPACE
623 #include "qdatetime.h"
625 #include "qthreadstorage.h"
626 #include <stdlib.h> // for RAND_MAX
627 QT_END_INCLUDE_NAMESPACE
629 #if !defined(QT_BOOTSTRAPPED) && defined(Q_OS_UNIX)
630 Q_GLOBAL_STATIC(QThreadStorage<QFile *>, devUrandomStorage);
633 QUuid QUuid::createUuid()
636 uint *data = &(result.data1);
638 #if defined(Q_OS_UNIX)
640 # if !defined(QT_BOOTSTRAPPED)
641 devUrandom = devUrandomStorage()->localData();
643 devUrandom = new QFile(QLatin1String("/dev/urandom"));
644 devUrandom->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
645 devUrandomStorage()->setLocalData(devUrandom);
648 QFile file(QLatin1String("/dev/urandom"));
650 devUrandom->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
652 enum { AmountToRead = 4 * sizeof(uint) };
653 if (devUrandom->isOpen()
654 && devUrandom->read((char *) data, AmountToRead) == AmountToRead) {
655 // we got what we wanted, nothing more to do
660 static const int intbits = sizeof(int)*8;
661 static int randbits = 0;
665 do { ++r; } while ((max=max>>1));
669 // Seed the PRNG once per thread with a combination of current time, a
670 // stack address and a serial counter (since thread stack addresses are
672 #ifndef QT_BOOTSTRAPPED
673 static QThreadStorage<int *> uuidseed;
674 if (!uuidseed.hasLocalData())
676 int *pseed = new int;
677 static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2);
678 qsrand(*pseed = QDateTime::currentDateTime().toTime_t()
680 + serial.fetchAndAddRelaxed(1));
681 uuidseed.setLocalData(pseed);
684 static bool seeded = false;
686 qsrand(QDateTime::currentDateTime().toTime_t()
687 + quintptr(&seeded));
690 int chunks = 16 / sizeof(uint);
693 for (int filled = 0; filled < intbits; filled += randbits)
694 randNumber |= qrand()<<filled;
695 *(data+chunks) = randNumber;
699 result.data4[0] = (result.data4[0] & 0x3F) | 0x80; // UV_DCE
700 result.data3 = (result.data3 & 0x0FFF) | 0x4000; // UV_Random
704 #endif // !Q_OS_WIN32
707 \fn bool QUuid::operator==(const GUID &guid) const
709 Returns true if this UUID is equal to the Windows GUID \a guid;
710 otherwise returns false.
714 \fn bool QUuid::operator!=(const GUID &guid) const
716 Returns true if this UUID is not equal to the Windows GUID \a
717 guid; otherwise returns false.