7ef8522411a3ea0a741c41fcee1c3a02ee941b4b
[profile/ivi/qtbase.git] / src / corelib / plugin / quuid.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
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.
17 **
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.
21 **
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.
29 **
30 ** Other Usage
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.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "quuid.h"
43
44 #include "qdatastream.h"
45 #include "qendian.h"
46
47 QT_BEGIN_NAMESPACE
48
49 #ifndef QT_NO_QUUID_STRING
50 template <class Char, class Integral>
51 void _q_toHex(Char *&dst, Integral value)
52 {
53     static const char digits[] = "0123456789abcdef";
54
55     if (sizeof(Integral) > 1)
56         value = qToBigEndian(value);
57
58     const char* p = reinterpret_cast<const char*>(&value);
59
60     for (uint i = 0; i < sizeof(Integral); ++i, dst += 2) {
61         uint j = (p[i] >> 4) & 0xf;
62         dst[0] = Char(digits[j]);
63         j = p[i] & 0xf;
64         dst[1] = Char(digits[j]);
65     }
66 }
67
68 template <class Char, class Integral>
69 bool _q_fromHex(const Char *&src, Integral &value)
70 {
71     value = 0;
72
73     for (uint i = 0; i < sizeof(Integral) * 2; ++i) {
74         int ch = *src++;
75         int tmp;
76         if (ch >= '0' && ch <= '9')
77             tmp = ch - '0';
78         else if (ch >= 'a' && ch <= 'f')
79             tmp = ch - 'a' + 10;
80         else if (ch >= 'A' && ch <= 'F')
81             tmp = ch - 'A' + 10;
82         else
83             return false;
84
85         value = value * 16 + tmp;
86     }
87
88     return true;
89 }
90
91 template <class Char>
92 void _q_uuidToHex(Char *&dst, const uint &d1, const ushort &d2, const ushort &d3, const uchar (&d4)[8])
93 {
94     *dst++ = Char('{');
95     _q_toHex(dst, d1);
96     *dst++ = Char('-');
97     _q_toHex(dst, d2);
98     *dst++ = Char('-');
99     _q_toHex(dst, d3);
100     *dst++ = Char('-');
101     for (int i = 0; i < 2; i++)
102         _q_toHex(dst, d4[i]);
103     *dst++ = Char('-');
104     for (int i = 2; i < 8; i++)
105         _q_toHex(dst, d4[i]);
106     *dst = Char('}');
107 }
108
109 template <class Char>
110 bool _q_uuidFromHex(const Char *&src, uint &d1, ushort &d2, ushort &d3, uchar (&d4)[8])
111 {
112     if (*src == Char('{'))
113         src++;
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])) {
129         return false;
130     }
131
132     return true;
133 }
134 #endif
135
136 /*!
137     \class QUuid
138     \brief The QUuid class stores a Universally Unique Identifier (UUID).
139
140     \reentrant
141
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.
149
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}.
162
163     \table
164     \header
165     \o msb0
166     \o msb1
167     \o msb2
168     \o Variant 
169
170     \row
171     \o 0
172     \o x
173     \o x
174     \o NCS (Network Computing System)
175
176     \row
177     \o 1
178     \o 0
179     \o x
180     \o DCE (Distributed Computing Environment)
181
182     \row
183     \o 1
184     \o 1
185     \o 0
186     \o Microsoft (GUID)
187
188     \row
189     \o 1
190     \o 1
191     \o 1
192     \o Reserved for future expansion
193
194     \endtable
195
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
205     significant bits.
206
207     \table
208     \header
209     \o msb0
210     \o msb1
211     \o msb2
212     \o msb3
213     \o Version
214
215     \row
216     \o 0
217     \o 0
218     \o 0
219     \o 1
220     \o Time
221
222     \row
223     \o 0
224     \o 0
225     \o 1
226     \o 0
227     \o Embedded POSIX
228
229     \row
230     \o 0
231     \o 0
232     \o 1
233     \o 1
234     \o Name
235
236     \row
237     \o 0
238     \o 1
239     \o 0
240     \o 0
241     \o Random
242
243     \endtable
244
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}.
248     
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
256     unique. But it is
257     \l{http://en.wikipedia.org/wiki/Universally_Unique_Identifier#Random_UUID_probability_of_duplicates}
258     {a \e{very} small chance}.
259
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().
264 */
265
266 /*!
267     \fn QUuid::QUuid(const GUID &guid)
268
269     Casts a Windows \a guid to a Qt QUuid.
270
271     \warning This function is only for Windows platforms.
272 */
273
274 /*!
275     \fn QUuid &QUuid::operator=(const GUID &guid)
276
277     Assigns a Windows \a guid to a Qt QUuid.
278
279     \warning This function is only for Windows platforms.
280 */
281
282 /*!
283     \fn QUuid::operator GUID() const
284
285     Returns a Windows GUID from a QUuid.
286
287     \warning This function is only for Windows platforms.
288 */
289
290 /*!
291     \fn QUuid::QUuid()
292
293     Creates the null UUID. toString() will output the null UUID
294     as "{00000000-0000-0000-0000-000000000000}".
295 */
296
297 /*!
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)
299
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
302     b8.
303
304     Example:
305     \snippet doc/src/snippets/code/src_corelib_plugin_quuid.cpp 0
306 */
307
308 #ifndef QT_NO_QUUID_STRING
309 /*!
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.
317
318     \sa toString(), QUuid()
319 */
320 QUuid::QUuid(const QString &text)
321 {
322     if (text.length() < 36) {
323         *this = QUuid();
324         return;
325     }
326
327     const ushort *data = reinterpret_cast<const ushort *>(text.unicode());
328
329     if (*data == '{' && text.length() < 37) {
330         *this = QUuid();
331         return;
332     }
333
334     if (!_q_uuidFromHex(data, data1, data2, data3, data4)) {
335         *this = QUuid();
336         return;
337     }
338 }
339
340 /*!
341     \internal
342 */
343 QUuid::QUuid(const char *text)
344 {
345     *this = QUuid(QString::fromLatin1(text));
346 }
347 #endif
348
349 /*!
350     \fn bool QUuid::operator==(const QUuid &other) const
351
352     Returns true if this QUuid and the \a other QUuid are identical;
353     otherwise returns false.
354 */
355
356 /*!
357     \fn bool QUuid::operator!=(const QUuid &other) const
358
359     Returns true if this QUuid and the \a other QUuid are different;
360     otherwise returns false.
361 */
362 #ifndef QT_NO_QUUID_STRING
363 /*!
364     \fn QUuid::operator QString() const
365
366     Returns the string representation of the uuid.
367
368     \sa toString()
369 */
370
371 /*!
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:
377
378     \table
379     \header
380     \o Field #
381     \o Source
382     
383     \row
384     \o 1
385     \o data1
386     
387     \row
388     \o 2
389     \o data2
390     
391     \row
392     \o 3
393     \o data3
394     
395     \row
396     \o 4
397     \o data4[0] .. data4[1]
398     
399     \row
400     \o 5
401     \o data4[2] .. data4[7]
402
403     \endtable
404 */
405 QString QUuid::toString() const
406 {
407     QString result(38, Qt::Uninitialized);
408     ushort *data = (ushort *)result.unicode();
409
410     _q_uuidToHex(data, data1, data2, data3, data4);
411
412     return result;
413 }
414 #endif
415
416 #ifndef QT_NO_DATASTREAM
417 /*!
418     \relates QUuid
419     Writes the UUID \a id to the data stream \a s.
420 */
421 QDataStream &operator<<(QDataStream &s, const QUuid &id)
422 {
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];
428     return s;
429 }
430
431 /*!
432     \relates QUuid
433     Reads a UUID from the stream \a s into \a id.
434 */
435 QDataStream &operator>>(QDataStream &s, QUuid &id)
436 {
437     quint32 u32;
438     quint16 u16;
439     quint8 u8;
440     s >> u32;
441     id.data1 = u32;
442     s >> u16;
443     id.data2 = u16;
444     s >> u16;
445     id.data3 = u16;
446     for (int i = 0; i < 8; i++) {
447         s >> u8;
448         id.data4[i] = u8;
449     }
450     return s;
451 }
452 #endif // QT_NO_DATASTREAM
453
454 /*!
455     Returns true if this is the null UUID
456     {00000000-0000-0000-0000-000000000000}; otherwise returns false.
457 */
458 bool QUuid::isNull() const
459 {
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;
463 }
464
465 /*!
466     \enum QUuid::Variant
467
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.
471
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
477 */
478
479 /*!
480     \enum QUuid::Version
481
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}
485     is QUuid::DCE.
486
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
493 */
494
495 /*!
496     \fn QUuid::Variant QUuid::variant() const
497
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
501     unknown variant.
502
503     \sa version()
504 */
505 QUuid::Variant QUuid::variant() const
506 {
507     if (isNull())
508         return VarUnknown;
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;
514     return VarUnknown;
515 }
516
517 /*!
518     \fn QUuid::Version QUuid::version() const
519
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.
523
524     \sa variant()
525 */
526 QUuid::Version QUuid::version() const
527 {
528     // Check the 4 MSB of data3
529     Version ver = (Version)(data3>>12);
530     if (isNull()
531          || (variant() != DCE)
532          || ver < Time
533          || ver > Random)
534         return VerUnknown;
535     return ver;
536 }
537
538 /*!
539     \fn bool QUuid::operator<(const QUuid &other) const
540
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}.
546
547     \sa variant()
548 */
549 #define ISLESS(f1, f2) if (f1!=f2) return (f1<f2);
550 bool QUuid::operator<(const QUuid &other) const
551 {
552     if (variant() != other.variant())
553         return variant() < other.variant();
554
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]);
560     }
561     return false;
562 }
563
564 /*!
565     \fn bool QUuid::operator>(const QUuid &other) const
566
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}.
572
573     \sa variant()
574 */
575 #define ISMORE(f1, f2) if (f1!=f2) return (f1>f2);
576 bool QUuid::operator>(const QUuid &other) const
577 {
578     if (variant() != other.variant())
579         return variant() > other.variant();
580
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]);
586     }
587     return false;
588 }
589
590 /*!
591     \fn QUuid QUuid::createUuid()
592
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.
601
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.
604
605     \sa variant(), version()
606 */
607 #if defined(Q_OS_WIN32) && ! defined(Q_CC_MWERKS)
608
609 QT_BEGIN_INCLUDE_NAMESPACE
610 #include <objbase.h> // For CoCreateGuid
611 QT_END_INCLUDE_NAMESPACE
612
613 QUuid QUuid::createUuid()
614 {
615     GUID guid;
616     CoCreateGuid(&guid);
617     QUuid result = guid;
618     return result;
619 }
620
621 #else // !Q_OS_WIN32
622
623 QT_BEGIN_INCLUDE_NAMESPACE
624 #include "qdatetime.h"
625 #include "qfile.h"
626 #include "qthreadstorage.h"
627 #include <stdlib.h> // for RAND_MAX
628 QT_END_INCLUDE_NAMESPACE
629
630 #if !defined(QT_BOOTSTRAPPED) && defined(Q_OS_UNIX)
631 Q_GLOBAL_STATIC(QThreadStorage<QFile *>, devUrandomStorage);
632 #endif
633
634 QUuid QUuid::createUuid()
635 {
636     QUuid result;
637     uint *data = &(result.data1);
638
639 #if defined(Q_OS_UNIX)
640     QFile *devUrandom;
641 #  if !defined(QT_BOOTSTRAPPED)
642     devUrandom = devUrandomStorage()->localData();
643     if (!devUrandom) {
644         devUrandom = new QFile(QLatin1String("/dev/urandom"));
645         devUrandom->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
646         devUrandomStorage()->setLocalData(devUrandom);
647     }
648 # else
649     QFile file(QLatin1String("/dev/urandom"));
650     devUrandom = &file;
651     devUrandom->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
652 # endif
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
657         ;
658     } else
659 #endif
660     {
661         static const int intbits = sizeof(int)*8;
662         static int randbits = 0;
663         if (!randbits) {
664             int r = 0;
665             int max = RAND_MAX;
666             do { ++r; } while ((max=max>>1));
667             randbits = r;
668         }
669
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
672         // re-used).
673 #ifndef QT_BOOTSTRAPPED
674         static QThreadStorage<int *> uuidseed;
675         if (!uuidseed.hasLocalData())
676         {
677             int *pseed = new int;
678             static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2);
679             qsrand(*pseed = QDateTime::currentDateTime().toTime_t()
680                    + quintptr(&pseed)
681                    + serial.fetchAndAddRelaxed(1));
682             uuidseed.setLocalData(pseed);
683         }
684 #else
685         static bool seeded = false;
686         if (!seeded)
687             qsrand(QDateTime::currentDateTime().toTime_t()
688                    + quintptr(&seeded));
689 #endif
690
691         int chunks = 16 / sizeof(uint);
692         while (chunks--) {
693             uint randNumber = 0;
694             for (int filled = 0; filled < intbits; filled += randbits)
695                 randNumber |= qrand()<<filled;
696             *(data+chunks) = randNumber;
697         }
698     }
699
700     result.data4[0] = (result.data4[0] & 0x3F) | 0x80;        // UV_DCE
701     result.data3 = (result.data3 & 0x0FFF) | 0x4000;        // UV_Random
702
703     return result;
704 }
705 #endif // !Q_OS_WIN32
706
707 /*!
708     \fn bool QUuid::operator==(const GUID &guid) const
709
710     Returns true if this UUID is equal to the Windows GUID \a guid;
711     otherwise returns false.
712 */
713
714 /*!
715     \fn bool QUuid::operator!=(const GUID &guid) const
716
717     Returns true if this UUID is not equal to the Windows GUID \a
718     guid; otherwise returns false.
719 */
720
721 QT_END_NAMESPACE