source: vendor/trolltech/current/src/tools/quuid.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

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