~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/corelib/plugin/quuid.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the core module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "quuid.h"
 
30
 
 
31
#include "qdatastream.h"
 
32
 
 
33
/*!
 
34
    \class QUuid
 
35
    \brief The QUuid class stores a Universally Unique Identifier (UUID).
 
36
 
 
37
    \reentrant
 
38
    \ingroup misc
 
39
 
 
40
    For objects or declarations that must be uniquely identified,
 
41
    UUIDs (also known as GUIDs) are widely used in order to assign a
 
42
    fixed and easy to compare value to the object or declaration. The
 
43
    128-bit value of a UUID is generated by an algorithm that
 
44
    guarantees that the value is unique.
 
45
 
 
46
    In Qt, UUIDs are wrapped by the QUuid struct which provides
 
47
    convenience functions for handling UUIDs. Most platforms provide
 
48
    a tool to generate new UUIDs, for example, \c uuidgen and \c
 
49
    guidgen.
 
50
 
 
51
    UUIDs generated by QUuid, are based on the \c Random version of the
 
52
    \c DCE (Distributed Computing Environment) standard.
 
53
 
 
54
    UUIDs can be constructed from numeric values or from strings, or
 
55
    using the static createUuid() function. They can be converted to a
 
56
    string with toString(). UUIDs have a variant() and a version(),
 
57
    and null UUIDs return true from isNull().
 
58
*/
 
59
 
 
60
/*!
 
61
    \fn QUuid::QUuid(const GUID &guid)
 
62
 
 
63
    Casts a Windows \a guid to a Qt QUuid.
 
64
 
 
65
    \warning This function is only for Windows platforms.
 
66
*/
 
67
 
 
68
/*!
 
69
    \fn QUuid &QUuid::operator=(const GUID &guid)
 
70
 
 
71
    Assigns a Windows \a guid to a Qt QUuid.
 
72
 
 
73
    \warning This function is only for Windows platforms.
 
74
*/
 
75
 
 
76
/*!
 
77
    \fn QUuid::operator GUID() const
 
78
 
 
79
    Returns a Windows GUID from a QUuid.
 
80
 
 
81
    \warning This function is only for Windows platforms.
 
82
*/
 
83
 
 
84
/*!
 
85
    \fn QUuid::QUuid()
 
86
 
 
87
    Creates the null UUID {00000000-0000-0000-0000-000000000000}.
 
88
*/
 
89
 
 
90
/*!
 
91
    \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)
 
92
 
 
93
    Creates a UUID with the value specified by the parameters, \a l,
 
94
    \a w1, \a w2, \a b1, \a b2, \a b3, \a b4, \a b5, \a b6, \a b7, \a
 
95
    b8.
 
96
 
 
97
    Example:
 
98
    \code
 
99
    // {67C8770B-44F1-410A-AB9A-F9B5446F13EE}
 
100
    QUuid IID_MyInterface(0x67c8770b, 0x44f1, 0x410a, 0xab, 0x9a, 0xf9, 0xb5, 0x44, 0x6f, 0x13, 0xee)
 
101
    \endcode
 
102
*/
 
103
 
 
104
#ifndef QT_NO_QUUID_STRING
 
105
/*!
 
106
    Creates a QUuid object from the string \a text. The function can
 
107
    only convert a string in the format
 
108
    {HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH} (where 'H' stands for a hex
 
109
    digit). If the conversion fails a null UUID is created.
 
110
*/
 
111
QUuid::QUuid(const QString &text)
 
112
{
 
113
    bool ok;
 
114
    if (text.isEmpty()) {
 
115
        *this = QUuid();
 
116
        return;
 
117
    }
 
118
    QString temp = text.toUpper();
 
119
    if (temp[0] != QLatin1Char('{'))
 
120
        temp = QLatin1Char('{') + text;
 
121
    if (text[(int)text.length()-1] != QLatin1Char('}'))
 
122
        temp += QLatin1Char('}');
 
123
 
 
124
    data1 = temp.mid(1, 8).toULongLong(&ok, 16);
 
125
    if (!ok) {
 
126
        *this = QUuid();
 
127
        return;
 
128
    }
 
129
 
 
130
    data2 = temp.mid(10, 4).toUInt(&ok, 16);
 
131
    if (!ok) {
 
132
        *this = QUuid();
 
133
        return;
 
134
    }
 
135
    data3 = temp.mid(15, 4).toUInt(&ok, 16);
 
136
    if (!ok) {
 
137
        *this = QUuid();
 
138
        return;
 
139
    }
 
140
    data4[0] = temp.mid(20, 2).toUInt(&ok, 16);
 
141
    if (!ok) {
 
142
        *this = QUuid();
 
143
        return;
 
144
    }
 
145
    data4[1] = temp.mid(22, 2).toUInt(&ok, 16);
 
146
    if (!ok) {
 
147
        *this = QUuid();
 
148
        return;
 
149
    }
 
150
    for (int i = 2; i<8; i++) {
 
151
        data4[i] = temp.mid(25 + (i-2)*2, 2).toUShort(&ok, 16);
 
152
        if (!ok) {
 
153
            *this = QUuid();
 
154
            return;
 
155
        }
 
156
    }
 
157
}
 
158
 
 
159
/*!
 
160
    \internal
 
161
*/
 
162
QUuid::QUuid(const char *text)
 
163
{
 
164
    *this = QUuid(QString::fromLatin1(text));
 
165
}
 
166
#endif
 
167
 
 
168
/*!
 
169
    \fn bool QUuid::operator==(const QUuid &other) const
 
170
 
 
171
    Returns true if this QUuid and the \a other QUuid are identical;
 
172
    otherwise returns false.
 
173
*/
 
174
 
 
175
/*!
 
176
    \fn bool QUuid::operator!=(const QUuid &other) const
 
177
 
 
178
    Returns true if this QUuid and the \a other QUuid are different;
 
179
    otherwise returns false.
 
180
*/
 
181
#ifndef QT_NO_QUUID_STRING
 
182
/*!
 
183
    \fn QUuid::operator QString() const
 
184
 
 
185
    Returns the string representation of the uuid.
 
186
 
 
187
    \sa toString()
 
188
*/
 
189
 
 
190
static QString uuidhex(uint data, int digits)
 
191
{
 
192
    return QString::number(data, 16).rightJustified(digits, QLatin1Char('0'));
 
193
}
 
194
 
 
195
/*!
 
196
    Returns the string representation of the uuid.
 
197
*/
 
198
QString QUuid::toString() const
 
199
{
 
200
    QString result;
 
201
 
 
202
    QChar dash = QLatin1Char('-');
 
203
    result = QLatin1Char('{') + uuidhex(data1,8);
 
204
    result += dash;
 
205
    result += uuidhex(data2,4);
 
206
    result += dash;
 
207
    result += uuidhex(data3,4);
 
208
    result += dash;
 
209
    result += uuidhex(data4[0],2);
 
210
    result += uuidhex(data4[1],2);
 
211
    result += dash;
 
212
    for (int i = 2; i < 8; i++)
 
213
        result += uuidhex(data4[i],2);
 
214
 
 
215
    return result + QLatin1Char('}');
 
216
}
 
217
#endif
 
218
 
 
219
#ifndef QT_NO_DATASTREAM
 
220
/*!
 
221
    \relates QUuid
 
222
    Writes the uuid \a id to the datastream \a s.
 
223
*/
 
224
QDataStream &operator<<(QDataStream &s, const QUuid &id)
 
225
{
 
226
    s << (quint32)id.data1;
 
227
    s << (quint16)id.data2;
 
228
    s << (quint16)id.data3;
 
229
    for (int i = 0; i < 8; i++)
 
230
        s << (quint8)id.data4[i];
 
231
    return s;
 
232
}
 
233
 
 
234
/*!
 
235
    \relates QUuid
 
236
    Reads uuid from from the stream \a s into \a id.
 
237
*/
 
238
QDataStream &operator>>(QDataStream &s, QUuid &id)
 
239
{
 
240
    quint32 u32;
 
241
    quint16 u16;
 
242
    quint8 u8;
 
243
    s >> u32;
 
244
    id.data1 = u32;
 
245
    s >> u16;
 
246
    id.data2 = u16;
 
247
    s >> u16;
 
248
    id.data3 = u16;
 
249
    for (int i = 0; i < 8; i++) {
 
250
        s >> u8;
 
251
        id.data4[i] = u8;
 
252
    }
 
253
    return s;
 
254
}
 
255
#endif
 
256
 
 
257
/*!
 
258
    Returns true if this is the null UUID
 
259
    {00000000-0000-0000-0000-000000000000}; otherwise returns false.
 
260
*/
 
261
bool QUuid::isNull() const
 
262
{
 
263
    return data4[0] == 0 && data4[1] == 0 && data4[2] == 0 && data4[3] == 0 &&
 
264
           data4[4] == 0 && data4[5] == 0 && data4[6] == 0 && data4[7] == 0 &&
 
265
           data1 == 0 && data2 == 0 && data3 == 0;
 
266
}
 
267
 
 
268
/*!
 
269
    \enum QUuid::Variant
 
270
 
 
271
    This enum defines the variant of the UUID, which is the scheme
 
272
    which defines the layout of the 128-bits value.
 
273
 
 
274
    \value VarUnknown Variant is unknown
 
275
    \value NCS Reserved for NCS (Network Computing System) backward compatibility
 
276
    \value DCE Distributed Computing Environment, the scheme used by QUuid
 
277
    \value Microsoft Reserved for Microsoft backward compatibility (GUID)
 
278
    \value Reserved Reserved for future definition
 
279
*/
 
280
 
 
281
/*!
 
282
    \enum QUuid::Version
 
283
 
 
284
    This enum defines the version of the UUID.
 
285
 
 
286
    \value VerUnknown Version is unknown
 
287
    \value Time Time-based, by using timestamp, clock sequence, and
 
288
    MAC network card address (if available) for the node sections
 
289
    \value EmbeddedPOSIX DCE Security version, with embedded POSIX UUIDs
 
290
    \value Name Name-based, by using values from a name for all sections
 
291
    \value Random Random-based, by using random numbers for all sections
 
292
*/
 
293
 
 
294
/*!
 
295
    \fn QUuid::Variant QUuid::variant() const
 
296
 
 
297
    Returns the variant of the UUID.
 
298
    The null UUID is considered to be of an unknown variant.
 
299
 
 
300
    \sa version()
 
301
*/
 
302
QUuid::Variant QUuid::variant() const
 
303
{
 
304
    if (isNull())
 
305
        return VarUnknown;
 
306
    // Check the 3 MSB of data4[0]
 
307
    if ((data4[0] & 0x80) == 0x00) return NCS;
 
308
    else if ((data4[0] & 0xC0) == 0x80) return DCE;
 
309
    else if ((data4[0] & 0xE0) == 0xC0) return Microsoft;
 
310
    else if ((data4[0] & 0xE0) == 0xE0) return Reserved;
 
311
    return VarUnknown;
 
312
}
 
313
 
 
314
/*!
 
315
    \fn QUuid::Version QUuid::version() const
 
316
 
 
317
    Returns the version of the UUID, if the UUID is of the DCE
 
318
    variant; otherwise returns VerUnknown.
 
319
 
 
320
    \sa variant()
 
321
*/
 
322
QUuid::Version QUuid::version() const
 
323
{
 
324
    // Check the 4 MSB of data3
 
325
    Version ver = (Version)(data3>>12);
 
326
    if (isNull()
 
327
         || (variant() != DCE)
 
328
         || ver < Time
 
329
         || ver > Random)
 
330
        return VerUnknown;
 
331
    return ver;
 
332
}
 
333
 
 
334
/*!
 
335
    \fn bool QUuid::operator<(const QUuid &other) const
 
336
 
 
337
    Returns true if this QUuid is of the same variant,
 
338
    and lexicographically before the \a other QUuid;
 
339
    otherwise returns false.
 
340
 
 
341
    \sa variant()
 
342
*/
 
343
#define ISLESS(f1, f2) if (f1!=f2) return (f1<f2);
 
344
bool QUuid::operator<(const QUuid &other) const
 
345
{
 
346
    if (variant() != other.variant())
 
347
        return false;
 
348
 
 
349
    ISLESS(data1, other.data1);
 
350
    ISLESS(data2, other.data2);
 
351
    ISLESS(data3, other.data3);
 
352
    for (int n = 0; n < 8; n++) {
 
353
        ISLESS(data4[n], other.data4[n]);
 
354
    }
 
355
    return false;
 
356
}
 
357
 
 
358
/*!
 
359
    \fn bool QUuid::operator>(const QUuid &other) const
 
360
 
 
361
    Returns true if this QUuid is of the same variant,
 
362
    and lexicographically after the \a other QUuid;
 
363
    otherwise returns false.
 
364
 
 
365
    \sa variant()
 
366
*/
 
367
#define ISMORE(f1, f2) if (f1!=f2) return (f1>f2);
 
368
bool QUuid::operator>(const QUuid &other) const
 
369
{
 
370
    if (variant() != other.variant())
 
371
        return false;
 
372
 
 
373
    ISMORE(data1, other.data1);
 
374
    ISMORE(data2, other.data2);
 
375
    ISMORE(data3, other.data3);
 
376
    for (int n = 0; n < 8; n++) {
 
377
        ISMORE(data4[n], other.data4[n]);
 
378
    }
 
379
    return false;
 
380
}
 
381
 
 
382
/*!
 
383
    \fn QUuid QUuid::createUuid()
 
384
 
 
385
    Returns a new UUID of \c DCE variant, and \c Random type. The
 
386
    UUIDs generated are based on the platform specific pseudo-random
 
387
    generator, which is usually not a cryptographic-quality random
 
388
    number generator. Therefore, a UUID is not guaranteed to be unique
 
389
    cross application instances.
 
390
 
 
391
    On Windows, the new UUID is extremely likely to be unique on the
 
392
    same or any other system, networked or not.
 
393
 
 
394
    \sa variant(), version()
 
395
*/
 
396
#if defined(Q_OS_WIN32)
 
397
#include <objbase.h> // For CoCreateGuid
 
398
QUuid QUuid::createUuid()
 
399
{
 
400
    GUID guid;
 
401
    CoCreateGuid(&guid);
 
402
    QUuid result = guid;
 
403
    return result;
 
404
}
 
405
#else // !Q_OS_WIN32
 
406
#include "qdatetime.h"
 
407
#include "stdlib.h" // For srand/rand
 
408
QUuid QUuid::createUuid()
 
409
{
 
410
    static const int intbits = sizeof(int)*8;
 
411
    static int randbits = 0;
 
412
    if (!randbits) {
 
413
        int max = RAND_MAX;
 
414
        do { ++randbits; } while ((max=max>>1));
 
415
        srand((uint)QDateTime::currentDateTime().toTime_t());
 
416
        rand(); // Skip first
 
417
    }
 
418
 
 
419
    QUuid result;
 
420
    uint *data = &(result.data1);
 
421
    int chunks = 16 / sizeof(uint);
 
422
    while (chunks--) {
 
423
        uint randNumber = 0;
 
424
        for (int filled = 0; filled < intbits; filled += randbits)
 
425
            randNumber |= rand()<<filled;
 
426
         *(data+chunks) = randNumber;
 
427
    }
 
428
 
 
429
    result.data4[0] = (result.data4[0] & 0x3F) | 0x80;        // UV_DCE
 
430
    result.data3 = (result.data3 & 0x0FFF) | 0x4000;        // UV_Random
 
431
 
 
432
    return result;
 
433
}
 
434
#endif // !Q_OS_WIN32
 
435
 
 
436
/*!
 
437
    \fn bool QUuid::operator==(const GUID &guid) const
 
438
 
 
439
    Returns true if this UUID is equal to the Windows GUID \a guid;
 
440
    otherwise returns false.
 
441
*/
 
442
 
 
443
/*!
 
444
    \fn bool QUuid::operator!=(const GUID &guid) const
 
445
 
 
446
    Returns true if this UUID is not equal to the Windows GUID \a
 
447
    guid; otherwise returns false.
 
448
*/