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"
50 \brief The QUuid class stores a Universally Unique Identifier (UUID).
54 Using \e{U}niversally \e{U}nique \e{ID}entifiers (UUID) is a
55 standard way to uniquely identify entities in a distributed
56 computing environment. A UUID is a 16-byte (128-bit) number
57 generated by some algorithm that is meant to guarantee that the
58 UUID will be unique in the distributed computing environment where
59 it is used. The acronym GUID is often used instead, \e{G}lobally
60 \e{U}nique \e{ID}entifiers, but it refers to the same thing.
63 Actually, the GUID is one \e{variant} of UUID. Multiple variants
64 are in use. Each UUID contains a bit field that specifies which
65 type (variant) of UUID it is. Call variant() to discover which
66 type of UUID an instance of QUuid contains. It extracts the three
67 most signifcant bits of byte 8 of the 16 bytes. In QUuid, byte 8
68 is \c{QUuid::data4[0]}. If you create instances of QUuid using the
69 constructor that accepts all the numeric values as parameters, use
70 the following table to set the three most significant bits of
71 parameter \c{b1}, which becomes \c{QUuid::data4[0]} and contains
72 the variant field in its three most significant bits. In the
73 table, 'x' means \e {don't care}.
86 \o NCS (Network Computing System)
92 \o DCE (Distributed Computing Environment)
104 \o Reserved for future expansion
108 \target Version field
109 If variant() returns QUuid::DCE, the UUID also contains a
110 \e{version} field in the four most significant bits of
111 \c{QUuid::data3}, and you can call version() to discover which
112 version your QUuid contains. If you create instances of QUuid
113 using the constructor that accepts all the numeric values as
114 parameters, use the following table to set the four most
115 significant bits of parameter \c{w2}, which becomes
116 \c{QUuid::data3} and contains the version field in its four most
157 The field layouts for the DCE versions listed in the table above
158 are specified in the \l{http://www.ietf.org/rfc/rfc4122.txt}
159 {Network Working Group UUID Specification}.
161 Most platforms provide a tool for generating new UUIDs, e.g. \c
162 uuidgen and \c guidgen. You can also use createUuid(). UUIDs
163 generated by createUuid() are of the random type. Their
164 QUuid::Version bits are set to QUuid::Random, and their
165 QUuid::Variant bits are set to QUuid::DCE. The rest of the UUID is
166 composed of random numbers. Theoretically, this means there is a
167 small chance that a UUID generated by createUuid() will not be
169 \l{http://en.wikipedia.org/wiki/Universally_Unique_Identifier#Random_UUID_probability_of_duplicates}
170 {a \e{very} small chance}.
172 UUIDs can be constructed from numeric values or from strings, or
173 using the static createUuid() function. They can be converted to a
174 string with toString(). UUIDs have a variant() and a version(),
175 and null UUIDs return true from isNull().
179 \fn QUuid::QUuid(const GUID &guid)
181 Casts a Windows \a guid to a Qt QUuid.
183 \warning This function is only for Windows platforms.
187 \fn QUuid &QUuid::operator=(const GUID &guid)
189 Assigns a Windows \a guid to a Qt QUuid.
191 \warning This function is only for Windows platforms.
195 \fn QUuid::operator GUID() const
197 Returns a Windows GUID from a QUuid.
199 \warning This function is only for Windows platforms.
205 Creates the null UUID. toString() will output the null UUID
206 as "{00000000-0000-0000-0000-000000000000}".
210 \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)
212 Creates a UUID with the value specified by the parameters, \a l,
213 \a w1, \a w2, \a b1, \a b2, \a b3, \a b4, \a b5, \a b6, \a b7, \a
217 \snippet doc/src/snippets/code/src_corelib_plugin_quuid.cpp 0
220 #ifndef QT_NO_QUUID_STRING
222 Creates a QUuid object from the string \a text, which must be
223 formatted as five hex fields separated by '-', e.g.,
224 "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where 'x' is a hex
225 digit. The curly braces shown here are optional, but it is normal to
226 include them. If the conversion fails, a null UUID is created. See
227 toString() for an explanation of how the five hex fields map to the
228 public data members in QUuid.
230 \sa toString(), QUuid()
232 QUuid::QUuid(const QString &text)
235 if (text.isEmpty()) {
239 QString temp = text.toUpper();
240 if (temp[0] != QLatin1Char('{'))
241 temp = QLatin1Char('{') + text;
242 if (text[(int)text.length()-1] != QLatin1Char('}'))
243 temp += QLatin1Char('}');
245 data1 = temp.mid(1, 8).toULongLong(&ok, 16);
251 data2 = temp.mid(10, 4).toUInt(&ok, 16);
256 data3 = temp.mid(15, 4).toUInt(&ok, 16);
261 data4[0] = temp.mid(20, 2).toUInt(&ok, 16);
266 data4[1] = temp.mid(22, 2).toUInt(&ok, 16);
271 for (int i = 2; i<8; i++) {
272 data4[i] = temp.mid(25 + (i-2)*2, 2).toUShort(&ok, 16);
283 QUuid::QUuid(const char *text)
285 *this = QUuid(QString::fromLatin1(text));
290 \fn bool QUuid::operator==(const QUuid &other) const
292 Returns true if this QUuid and the \a other QUuid are identical;
293 otherwise returns false.
297 \fn bool QUuid::operator!=(const QUuid &other) const
299 Returns true if this QUuid and the \a other QUuid are different;
300 otherwise returns false.
302 #ifndef QT_NO_QUUID_STRING
304 \fn QUuid::operator QString() const
306 Returns the string representation of the uuid.
311 static QString uuidhex(uint data, int digits)
313 return QString::number(data, 16).rightJustified(digits, QLatin1Char('0'));
317 Returns the string representation of this QUuid. The string is
318 formatted as five hex fields separated by '-' and enclosed in
319 curly braces, i.e., "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where
320 'x' is a hex digit. From left to right, the five hex fields are
321 obtained from the four public data members in QUuid as follows:
342 \o data4[0] .. data4[1]
346 \o data4[2] .. data4[7]
350 QString QUuid::toString() const
354 QChar dash = QLatin1Char('-');
355 result = QLatin1Char('{') + uuidhex(data1,8);
357 result += uuidhex(data2,4);
359 result += uuidhex(data3,4);
361 result += uuidhex(data4[0],2);
362 result += uuidhex(data4[1],2);
364 for (int i = 2; i < 8; i++)
365 result += uuidhex(data4[i],2);
367 return result + QLatin1Char('}');
371 #ifndef QT_NO_DATASTREAM
374 Writes the UUID \a id to the data stream \a s.
376 QDataStream &operator<<(QDataStream &s, const QUuid &id)
378 s << (quint32)id.data1;
379 s << (quint16)id.data2;
380 s << (quint16)id.data3;
381 for (int i = 0; i < 8; i++)
382 s << (quint8)id.data4[i];
388 Reads a UUID from the stream \a s into \a id.
390 QDataStream &operator>>(QDataStream &s, QUuid &id)
401 for (int i = 0; i < 8; i++) {
407 #endif // QT_NO_DATASTREAM
410 Returns true if this is the null UUID
411 {00000000-0000-0000-0000-000000000000}; otherwise returns false.
413 bool QUuid::isNull() const
415 return data4[0] == 0 && data4[1] == 0 && data4[2] == 0 && data4[3] == 0 &&
416 data4[4] == 0 && data4[5] == 0 && data4[6] == 0 && data4[7] == 0 &&
417 data1 == 0 && data2 == 0 && data3 == 0;
423 This enum defines the values used in the \l{Variant field}
424 {variant field} of the UUID. The value in the variant field
425 determines the layout of the 128-bit value.
427 \value VarUnknown Variant is unknown
428 \value NCS Reserved for NCS (Network Computing System) backward compatibility
429 \value DCE Distributed Computing Environment, the scheme used by QUuid
430 \value Microsoft Reserved for Microsoft backward compatibility (GUID)
431 \value Reserved Reserved for future definition
437 This enum defines the values used in the \l{Version field}
438 {version field} of the UUID. The version field is meaningful
439 only if the value in the \l{Variant field} {variant field}
442 \value VerUnknown Version is unknown
443 \value Time Time-based, by using timestamp, clock sequence, and
444 MAC network card address (if available) for the node sections
445 \value EmbeddedPOSIX DCE Security version, with embedded POSIX UUIDs
446 \value Name Name-based, by using values from a name for all sections
447 \value Random Random-based, by using random numbers for all sections
451 \fn QUuid::Variant QUuid::variant() const
453 Returns the value in the \l{Variant field} {variant field} of the
454 UUID. If the return value is QUuid::DCE, call version() to see
455 which layout it uses. The null UUID is considered to be of an
460 QUuid::Variant QUuid::variant() const
464 // Check the 3 MSB of data4[0]
465 if ((data4[0] & 0x80) == 0x00) return NCS;
466 else if ((data4[0] & 0xC0) == 0x80) return DCE;
467 else if ((data4[0] & 0xE0) == 0xC0) return Microsoft;
468 else if ((data4[0] & 0xE0) == 0xE0) return Reserved;
473 \fn QUuid::Version QUuid::version() const
475 Returns the \l{Version field} {version field} of the UUID, if the
476 UUID's \l{Variant field} {variant field} is QUuid::DCE. Otherwise
477 it returns QUuid::VerUnknown.
481 QUuid::Version QUuid::version() const
483 // Check the 4 MSB of data3
484 Version ver = (Version)(data3>>12);
486 || (variant() != DCE)
494 \fn bool QUuid::operator<(const QUuid &other) const
496 Returns true if this QUuid has the same \l{Variant field}
497 {variant field} as the \a other QUuid and is lexicographically
498 \e{before} the \a other QUuid. If the \a other QUuid has a
499 different variant field, the return value is determined by
500 comparing the two \l{QUuid::Variant} {variants}.
504 #define ISLESS(f1, f2) if (f1!=f2) return (f1<f2);
505 bool QUuid::operator<(const QUuid &other) const
507 if (variant() != other.variant())
508 return variant() < other.variant();
510 ISLESS(data1, other.data1);
511 ISLESS(data2, other.data2);
512 ISLESS(data3, other.data3);
513 for (int n = 0; n < 8; n++) {
514 ISLESS(data4[n], other.data4[n]);
520 \fn bool QUuid::operator>(const QUuid &other) const
522 Returns true if this QUuid has the same \l{Variant field}
523 {variant field} as the \a other QUuid and is lexicographically
524 \e{after} the \a other QUuid. If the \a other QUuid has a
525 different variant field, the return value is determined by
526 comparing the two \l{QUuid::Variant} {variants}.
530 #define ISMORE(f1, f2) if (f1!=f2) return (f1>f2);
531 bool QUuid::operator>(const QUuid &other) const
533 if (variant() != other.variant())
534 return variant() > other.variant();
536 ISMORE(data1, other.data1);
537 ISMORE(data2, other.data2);
538 ISMORE(data3, other.data3);
539 for (int n = 0; n < 8; n++) {
540 ISMORE(data4[n], other.data4[n]);
546 \fn QUuid QUuid::createUuid()
548 On any platform other than Windows, this function returns a new
549 UUID with variant QUuid::DCE and version QUuid::Random. If
550 the /dev/urandom device exists, then the numbers used to construct
551 the UUID will be of cryptographic quality, which will make the UUID
552 unique. Otherwise, the numbers of the UUID will be obtained from
553 the local pseudo-random number generator (qrand(), which is seeded
554 by qsrand()) which is usually not of cryptograhic quality, which
555 means that the UUID can't be guaranteed to be unique.
557 On a Windows platform, a GUID is generated, which almost certainly
558 \e{will} be unique, on this or any other system, networked or not.
560 \sa variant(), version()
562 #if defined(Q_OS_WIN32) && ! defined(Q_CC_MWERKS)
564 QT_BEGIN_INCLUDE_NAMESPACE
565 #include <objbase.h> // For CoCreateGuid
566 QT_END_INCLUDE_NAMESPACE
568 QUuid QUuid::createUuid()
578 QT_BEGIN_INCLUDE_NAMESPACE
579 #include "qdatetime.h"
581 #include "qthreadstorage.h"
582 #include <stdlib.h> // for RAND_MAX
583 QT_END_INCLUDE_NAMESPACE
585 #if !defined(QT_BOOTSTRAPPED) && defined(Q_OS_UNIX)
586 Q_GLOBAL_STATIC(QThreadStorage<QFile *>, devUrandomStorage);
589 QUuid QUuid::createUuid()
592 uint *data = &(result.data1);
594 #if defined(Q_OS_UNIX)
596 # if !defined(QT_BOOTSTRAPPED)
597 devUrandom = devUrandomStorage()->localData();
599 devUrandom = new QFile(QLatin1String("/dev/urandom"));
600 devUrandom->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
601 devUrandomStorage()->setLocalData(devUrandom);
604 QFile file(QLatin1String("/dev/urandom"));
606 devUrandom->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
608 enum { AmountToRead = 4 * sizeof(uint) };
609 if (devUrandom->isOpen()
610 && devUrandom->read((char *) data, AmountToRead) == AmountToRead) {
611 // we got what we wanted, nothing more to do
616 static const int intbits = sizeof(int)*8;
617 static int randbits = 0;
621 do { ++r; } while ((max=max>>1));
625 // Seed the PRNG once per thread with a combination of current time, a
626 // stack address and a serial counter (since thread stack addresses are
628 #ifndef QT_BOOTSTRAPPED
629 static QThreadStorage<int *> uuidseed;
630 if (!uuidseed.hasLocalData())
632 int *pseed = new int;
633 static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2);
634 qsrand(*pseed = QDateTime::currentDateTime().toTime_t()
636 + serial.fetchAndAddRelaxed(1));
637 uuidseed.setLocalData(pseed);
640 static bool seeded = false;
642 qsrand(QDateTime::currentDateTime().toTime_t()
643 + quintptr(&seeded));
646 int chunks = 16 / sizeof(uint);
649 for (int filled = 0; filled < intbits; filled += randbits)
650 randNumber |= qrand()<<filled;
651 *(data+chunks) = randNumber;
655 result.data4[0] = (result.data4[0] & 0x3F) | 0x80; // UV_DCE
656 result.data3 = (result.data3 & 0x0FFF) | 0x4000; // UV_Random
660 #endif // !Q_OS_WIN32
663 \fn bool QUuid::operator==(const GUID &guid) const
665 Returns true if this UUID is equal to the Windows GUID \a guid;
666 otherwise returns false.
670 \fn bool QUuid::operator!=(const GUID &guid) const
672 Returns true if this UUID is not equal to the Windows GUID \a
673 guid; otherwise returns false.