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 if (sizeof(Integral) > 1)
56 value = qToBigEndian(value);
58 const char* p = reinterpret_cast<const char*>(&value);
60 for (uint i = 0; i < sizeof(Integral); ++i, dst += 2) {
61 uint j = (p[i] >> 4) & 0xf;
62 dst[0] = Char(digits[j]);
64 dst[1] = Char(digits[j]);
68 template <class Char, class Integral>
69 bool _q_fromHex(const Char *&src, Integral &value)
73 for (uint i = 0; i < sizeof(Integral) * 2; ++i) {
76 if (ch >= '0' && ch <= '9')
78 else if (ch >= 'a' && ch <= 'f')
80 else if (ch >= 'A' && ch <= 'F')
85 value = value * 16 + tmp;
92 void _q_uuidToHex(Char *&dst, const uint &d1, const ushort &d2, const ushort &d3, const uchar (&d4)[8])
101 for (int i = 0; i < 2; i++)
102 _q_toHex(dst, d4[i]);
104 for (int i = 2; i < 8; i++)
105 _q_toHex(dst, d4[i]);
109 template <class Char>
110 bool _q_uuidFromHex(const Char *&src, uint &d1, ushort &d2, ushort &d3, uchar (&d4)[8])
112 if (*src == Char('{'))
114 if (!_q_fromHex(src, d1)
115 || *src++ != Char('-')
116 || !_q_fromHex(src, d2)
117 || *src++ != Char('-')
118 || !_q_fromHex(src, d3)
119 || *src++ != Char('-')
120 || !_q_fromHex(src, d4[0])
121 || !_q_fromHex(src, d4[1])
122 || *src++ != Char('-')
123 || !_q_fromHex(src, d4[2])
124 || !_q_fromHex(src, d4[3])
125 || !_q_fromHex(src, d4[4])
126 || !_q_fromHex(src, d4[5])
127 || !_q_fromHex(src, d4[6])
128 || !_q_fromHex(src, d4[7])) {
138 \brief The QUuid class stores a Universally Unique Identifier (UUID).
142 Using \e{U}niversally \e{U}nique \e{ID}entifiers (UUID) is a
143 standard way to uniquely identify entities in a distributed
144 computing environment. A UUID is a 16-byte (128-bit) number
145 generated by some algorithm that is meant to guarantee that the
146 UUID will be unique in the distributed computing environment where
147 it is used. The acronym GUID is often used instead, \e{G}lobally
148 \e{U}nique \e{ID}entifiers, but it refers to the same thing.
150 \target Variant field
151 Actually, the GUID is one \e{variant} of UUID. Multiple variants
152 are in use. Each UUID contains a bit field that specifies which
153 type (variant) of UUID it is. Call variant() to discover which
154 type of UUID an instance of QUuid contains. It extracts the three
155 most signifcant bits of byte 8 of the 16 bytes. In QUuid, byte 8
156 is \c{QUuid::data4[0]}. If you create instances of QUuid using the
157 constructor that accepts all the numeric values as parameters, use
158 the following table to set the three most significant bits of
159 parameter \c{b1}, which becomes \c{QUuid::data4[0]} and contains
160 the variant field in its three most significant bits. In the
161 table, 'x' means \e {don't care}.
174 \o NCS (Network Computing System)
180 \o DCE (Distributed Computing Environment)
192 \o Reserved for future expansion
196 \target Version field
197 If variant() returns QUuid::DCE, the UUID also contains a
198 \e{version} field in the four most significant bits of
199 \c{QUuid::data3}, and you can call version() to discover which
200 version your QUuid contains. If you create instances of QUuid
201 using the constructor that accepts all the numeric values as
202 parameters, use the following table to set the four most
203 significant bits of parameter \c{w2}, which becomes
204 \c{QUuid::data3} and contains the version field in its four most
245 The field layouts for the DCE versions listed in the table above
246 are specified in the \l{http://www.ietf.org/rfc/rfc4122.txt}
247 {Network Working Group UUID Specification}.
249 Most platforms provide a tool for generating new UUIDs, e.g. \c
250 uuidgen and \c guidgen. You can also use createUuid(). UUIDs
251 generated by createUuid() are of the random type. Their
252 QUuid::Version bits are set to QUuid::Random, and their
253 QUuid::Variant bits are set to QUuid::DCE. The rest of the UUID is
254 composed of random numbers. Theoretically, this means there is a
255 small chance that a UUID generated by createUuid() will not be
257 \l{http://en.wikipedia.org/wiki/Universally_Unique_Identifier#Random_UUID_probability_of_duplicates}
258 {a \e{very} small chance}.
260 UUIDs can be constructed from numeric values or from strings, or
261 using the static createUuid() function. They can be converted to a
262 string with toString(). UUIDs have a variant() and a version(),
263 and null UUIDs return true from isNull().
267 \fn QUuid::QUuid(const GUID &guid)
269 Casts a Windows \a guid to a Qt QUuid.
271 \warning This function is only for Windows platforms.
275 \fn QUuid &QUuid::operator=(const GUID &guid)
277 Assigns a Windows \a guid to a Qt QUuid.
279 \warning This function is only for Windows platforms.
283 \fn QUuid::operator GUID() const
285 Returns a Windows GUID from a QUuid.
287 \warning This function is only for Windows platforms.
293 Creates the null UUID. toString() will output the null UUID
294 as "{00000000-0000-0000-0000-000000000000}".
298 \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)
300 Creates a UUID with the value specified by the parameters, \a l,
301 \a w1, \a w2, \a b1, \a b2, \a b3, \a b4, \a b5, \a b6, \a b7, \a
305 \snippet doc/src/snippets/code/src_corelib_plugin_quuid.cpp 0
308 #ifndef QT_NO_QUUID_STRING
310 Creates a QUuid object from the string \a text, which must be
311 formatted as five hex fields separated by '-', e.g.,
312 "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where 'x' is a hex
313 digit. The curly braces shown here are optional, but it is normal to
314 include them. If the conversion fails, a null UUID is created. See
315 toString() for an explanation of how the five hex fields map to the
316 public data members in QUuid.
318 \sa toString(), QUuid()
320 QUuid::QUuid(const QString &text)
322 if (text.length() < 36) {
327 const ushort *data = reinterpret_cast<const ushort *>(text.unicode());
329 if (*data == '{' && text.length() < 37) {
334 if (!_q_uuidFromHex(data, data1, data2, data3, data4)) {
343 QUuid::QUuid(const char *text)
345 *this = QUuid(QString::fromLatin1(text));
350 \fn bool QUuid::operator==(const QUuid &other) const
352 Returns true if this QUuid and the \a other QUuid are identical;
353 otherwise returns false.
357 \fn bool QUuid::operator!=(const QUuid &other) const
359 Returns true if this QUuid and the \a other QUuid are different;
360 otherwise returns false.
362 #ifndef QT_NO_QUUID_STRING
364 \fn QUuid::operator QString() const
366 Returns the string representation of the uuid.
372 Returns the string representation of this QUuid. The string is
373 formatted as five hex fields separated by '-' and enclosed in
374 curly braces, i.e., "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" where
375 'x' is a hex digit. From left to right, the five hex fields are
376 obtained from the four public data members in QUuid as follows:
397 \o data4[0] .. data4[1]
401 \o data4[2] .. data4[7]
405 QString QUuid::toString() const
407 QString result(38, Qt::Uninitialized);
408 ushort *data = (ushort *)result.unicode();
410 _q_uuidToHex(data, data1, data2, data3, data4);
416 #ifndef QT_NO_DATASTREAM
419 Writes the UUID \a id to the data stream \a s.
421 QDataStream &operator<<(QDataStream &s, const QUuid &id)
423 s << (quint32)id.data1;
424 s << (quint16)id.data2;
425 s << (quint16)id.data3;
426 for (int i = 0; i < 8; i++)
427 s << (quint8)id.data4[i];
433 Reads a UUID from the stream \a s into \a id.
435 QDataStream &operator>>(QDataStream &s, QUuid &id)
446 for (int i = 0; i < 8; i++) {
452 #endif // QT_NO_DATASTREAM
455 Returns true if this is the null UUID
456 {00000000-0000-0000-0000-000000000000}; otherwise returns false.
458 bool QUuid::isNull() const
460 return data4[0] == 0 && data4[1] == 0 && data4[2] == 0 && data4[3] == 0 &&
461 data4[4] == 0 && data4[5] == 0 && data4[6] == 0 && data4[7] == 0 &&
462 data1 == 0 && data2 == 0 && data3 == 0;
468 This enum defines the values used in the \l{Variant field}
469 {variant field} of the UUID. The value in the variant field
470 determines the layout of the 128-bit value.
472 \value VarUnknown Variant is unknown
473 \value NCS Reserved for NCS (Network Computing System) backward compatibility
474 \value DCE Distributed Computing Environment, the scheme used by QUuid
475 \value Microsoft Reserved for Microsoft backward compatibility (GUID)
476 \value Reserved Reserved for future definition
482 This enum defines the values used in the \l{Version field}
483 {version field} of the UUID. The version field is meaningful
484 only if the value in the \l{Variant field} {variant field}
487 \value VerUnknown Version is unknown
488 \value Time Time-based, by using timestamp, clock sequence, and
489 MAC network card address (if available) for the node sections
490 \value EmbeddedPOSIX DCE Security version, with embedded POSIX UUIDs
491 \value Name Name-based, by using values from a name for all sections
492 \value Random Random-based, by using random numbers for all sections
496 \fn QUuid::Variant QUuid::variant() const
498 Returns the value in the \l{Variant field} {variant field} of the
499 UUID. If the return value is QUuid::DCE, call version() to see
500 which layout it uses. The null UUID is considered to be of an
505 QUuid::Variant QUuid::variant() const
509 // Check the 3 MSB of data4[0]
510 if ((data4[0] & 0x80) == 0x00) return NCS;
511 else if ((data4[0] & 0xC0) == 0x80) return DCE;
512 else if ((data4[0] & 0xE0) == 0xC0) return Microsoft;
513 else if ((data4[0] & 0xE0) == 0xE0) return Reserved;
518 \fn QUuid::Version QUuid::version() const
520 Returns the \l{Version field} {version field} of the UUID, if the
521 UUID's \l{Variant field} {variant field} is QUuid::DCE. Otherwise
522 it returns QUuid::VerUnknown.
526 QUuid::Version QUuid::version() const
528 // Check the 4 MSB of data3
529 Version ver = (Version)(data3>>12);
531 || (variant() != DCE)
539 \fn bool QUuid::operator<(const QUuid &other) const
541 Returns true if this QUuid has the same \l{Variant field}
542 {variant field} as the \a other QUuid and is lexicographically
543 \e{before} the \a other QUuid. If the \a other QUuid has a
544 different variant field, the return value is determined by
545 comparing the two \l{QUuid::Variant} {variants}.
549 #define ISLESS(f1, f2) if (f1!=f2) return (f1<f2);
550 bool QUuid::operator<(const QUuid &other) const
552 if (variant() != other.variant())
553 return variant() < other.variant();
555 ISLESS(data1, other.data1);
556 ISLESS(data2, other.data2);
557 ISLESS(data3, other.data3);
558 for (int n = 0; n < 8; n++) {
559 ISLESS(data4[n], other.data4[n]);
565 \fn bool QUuid::operator>(const QUuid &other) const
567 Returns true if this QUuid has the same \l{Variant field}
568 {variant field} as the \a other QUuid and is lexicographically
569 \e{after} the \a other QUuid. If the \a other QUuid has a
570 different variant field, the return value is determined by
571 comparing the two \l{QUuid::Variant} {variants}.
575 #define ISMORE(f1, f2) if (f1!=f2) return (f1>f2);
576 bool QUuid::operator>(const QUuid &other) const
578 if (variant() != other.variant())
579 return variant() > other.variant();
581 ISMORE(data1, other.data1);
582 ISMORE(data2, other.data2);
583 ISMORE(data3, other.data3);
584 for (int n = 0; n < 8; n++) {
585 ISMORE(data4[n], other.data4[n]);
591 \fn QUuid QUuid::createUuid()
593 On any platform other than Windows, this function returns a new
594 UUID with variant QUuid::DCE and version QUuid::Random. If
595 the /dev/urandom device exists, then the numbers used to construct
596 the UUID will be of cryptographic quality, which will make the UUID
597 unique. Otherwise, the numbers of the UUID will be obtained from
598 the local pseudo-random number generator (qrand(), which is seeded
599 by qsrand()) which is usually not of cryptograhic quality, which
600 means that the UUID can't be guaranteed to be unique.
602 On a Windows platform, a GUID is generated, which almost certainly
603 \e{will} be unique, on this or any other system, networked or not.
605 \sa variant(), version()
607 #if defined(Q_OS_WIN32) && ! defined(Q_CC_MWERKS)
609 QT_BEGIN_INCLUDE_NAMESPACE
610 #include <objbase.h> // For CoCreateGuid
611 QT_END_INCLUDE_NAMESPACE
613 QUuid QUuid::createUuid()
623 QT_BEGIN_INCLUDE_NAMESPACE
624 #include "qdatetime.h"
626 #include "qthreadstorage.h"
627 #include <stdlib.h> // for RAND_MAX
628 QT_END_INCLUDE_NAMESPACE
630 #if !defined(QT_BOOTSTRAPPED) && defined(Q_OS_UNIX)
631 Q_GLOBAL_STATIC(QThreadStorage<QFile *>, devUrandomStorage);
634 QUuid QUuid::createUuid()
637 uint *data = &(result.data1);
639 #if defined(Q_OS_UNIX)
641 # if !defined(QT_BOOTSTRAPPED)
642 devUrandom = devUrandomStorage()->localData();
644 devUrandom = new QFile(QLatin1String("/dev/urandom"));
645 devUrandom->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
646 devUrandomStorage()->setLocalData(devUrandom);
649 QFile file(QLatin1String("/dev/urandom"));
651 devUrandom->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
653 enum { AmountToRead = 4 * sizeof(uint) };
654 if (devUrandom->isOpen()
655 && devUrandom->read((char *) data, AmountToRead) == AmountToRead) {
656 // we got what we wanted, nothing more to do
661 static const int intbits = sizeof(int)*8;
662 static int randbits = 0;
666 do { ++r; } while ((max=max>>1));
670 // Seed the PRNG once per thread with a combination of current time, a
671 // stack address and a serial counter (since thread stack addresses are
673 #ifndef QT_BOOTSTRAPPED
674 static QThreadStorage<int *> uuidseed;
675 if (!uuidseed.hasLocalData())
677 int *pseed = new int;
678 static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2);
679 qsrand(*pseed = QDateTime::currentDateTime().toTime_t()
681 + serial.fetchAndAddRelaxed(1));
682 uuidseed.setLocalData(pseed);
685 static bool seeded = false;
687 qsrand(QDateTime::currentDateTime().toTime_t()
688 + quintptr(&seeded));
691 int chunks = 16 / sizeof(uint);
694 for (int filled = 0; filled < intbits; filled += randbits)
695 randNumber |= qrand()<<filled;
696 *(data+chunks) = randNumber;
700 result.data4[0] = (result.data4[0] & 0x3F) | 0x80; // UV_DCE
701 result.data3 = (result.data3 & 0x0FFF) | 0x4000; // UV_Random
705 #endif // !Q_OS_WIN32
708 \fn bool QUuid::operator==(const GUID &guid) const
710 Returns true if this UUID is equal to the Windows GUID \a guid;
711 otherwise returns false.
715 \fn bool QUuid::operator!=(const GUID &guid) const
717 Returns true if this UUID is not equal to the Windows GUID \a
718 guid; otherwise returns false.