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