VirtualBox

source: vbox/trunk/include/VBox/com/Guid.h@ 72904

Last change on this file since 72904 was 72904, checked in by vboxsync, 7 years ago

com::Guid: fix circular logic in isZero()

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.5 KB
Line 
1/* $Id: Guid.h 72904 2018-07-04 21:52:10Z vboxsync $ */
2/** @file
3 * MS COM / XPCOM Abstraction Layer - Guid class declaration.
4 */
5
6/*
7 * Copyright (C) 2006-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27#ifndef ___VBox_com_Guid_h
28#define ___VBox_com_Guid_h
29
30/* Make sure all the stdint.h macros are included - must come first! */
31#ifndef __STDC_LIMIT_MACROS
32# define __STDC_LIMIT_MACROS
33#endif
34#ifndef __STDC_CONSTANT_MACROS
35# define __STDC_CONSTANT_MACROS
36#endif
37
38#include "VBox/com/string.h"
39
40#include <iprt/uuid.h>
41#include <iprt/err.h>
42
43
44/** @defgroup grp_com_guid GUID Class
45 * @ingroup grp_com
46 * @{
47 */
48
49namespace com
50{
51
52typedef enum GuidState_t
53{
54 GUID_ZERO,
55 GUID_NORMAL,
56 GUID_INVALID
57} GuidState_t;
58
59/**
60 * Helper class that represents the UUID type and hides platform-specific
61 * implementation details.
62 */
63class Guid
64{
65public:
66
67 Guid()
68 {
69 ::RTUuidClear(&mUuid);
70 mGuidState = GUID_ZERO;
71 dbg_refresh();
72 }
73
74 Guid(const Guid &that)
75 {
76 mUuid = that.mUuid;
77 mGuidState = that.mGuidState;
78 dbg_refresh();
79 }
80
81 Guid(const RTUUID &that)
82 {
83 mUuid = that;
84 updateState();
85 dbg_refresh();
86 }
87
88 Guid(const GUID &that)
89 {
90 AssertCompileSize(GUID, sizeof(RTUUID));
91 ::memcpy(&mUuid, &that, sizeof(GUID));
92 updateState();
93 dbg_refresh();
94 }
95
96 /**
97 * Construct a GUID from a string.
98 *
99 * @param that The UUID string. Can be with or without the curly
100 * brackets. Empty strings are translated to a zero
101 * GUID, and strings which are not confirming to
102 * valid GUID string representations are marked as
103 * invalid.
104 */
105 Guid(const char *that)
106 {
107 initString(that);
108 }
109
110 /**
111 * Construct a GUID from a BSTR.
112 *
113 * @param that The UUID BSTR. Can be with or without the curly
114 * brackets. Empty strings are translated to a zero
115 * GUID, and strings which are not confirming to
116 * valid GUID string representations are marked as
117 * invalid.
118 */
119 Guid(CBSTR that)
120 {
121 initBSTR(that);
122 }
123
124 /**
125 * Construct a GUID from a Utf8Str.
126 *
127 * @param that The UUID Utf8Str. Can be with or without the curly
128 * brackets. Empty strings are translated to a zero
129 * GUID, and strings which are not confirming to
130 * valid GUID string representations are marked as
131 */
132 Guid(const Utf8Str &that)
133 {
134 initString(that.c_str());
135 }
136
137 /**
138 * Construct a GUID from a RTCString.
139 *
140 * @param that The UUID RTCString. Can be with or without the curly
141 * brackets. Empty strings are translated to a zero
142 * GUID, and strings which are not confirming to
143 * valid GUID string representations are marked as
144 */
145 Guid(const RTCString &that)
146 {
147 initString(that.c_str());
148 }
149
150 /**
151 * Construct a GUID from a Bstr.
152 *
153 * @param that The UUID Bstr. Can be with or without the curly
154 * brackets. Empty strings are translated to a zero
155 * GUID, and strings which are not confirming to
156 * valid GUID string representations are marked as
157 */
158 Guid(const Bstr &that)
159 {
160 initBSTR(that.raw());
161 }
162
163 Guid& operator=(const Guid &that)
164 {
165 mUuid = that.mUuid;
166 mGuidState = that.mGuidState;
167 dbg_refresh();
168 return *this;
169 }
170
171 Guid& operator=(const RTUUID &guid)
172 {
173 mUuid = guid;
174 updateState();
175 dbg_refresh();
176 return *this;
177 }
178
179 Guid& operator=(const GUID &guid)
180 {
181 AssertCompileSize(GUID, sizeof(RTUUID));
182 ::memcpy(&mUuid, &guid, sizeof(GUID));
183 updateState();
184 dbg_refresh();
185 return *this;
186 }
187
188 Guid& operator=(const char *str)
189 {
190 initString(str);
191 return *this;
192 }
193
194 Guid& operator=(CBSTR str)
195 {
196 initBSTR(str);
197 return *this;
198 }
199
200 Guid& operator=(const Utf8Str &str)
201 {
202 return operator=(str.c_str());
203 }
204
205 Guid& operator=(const RTCString &str)
206 {
207 return operator=(str.c_str());
208 }
209
210 Guid& operator=(const Bstr &str)
211 {
212 return operator=(str.raw());
213 }
214
215 void create()
216 {
217 ::RTUuidCreate(&mUuid);
218 mGuidState = GUID_NORMAL;
219 dbg_refresh();
220 }
221
222 void clear()
223 {
224 ::RTUuidClear(&mUuid);
225 mGuidState = GUID_ZERO;
226 dbg_refresh();
227 }
228
229 /**
230 * Convert the GUID to a string.
231 *
232 * @returns String object containing the formatted GUID.
233 * @throws std::bad_alloc
234 */
235 Utf8Str toString() const
236 {
237 if (mGuidState == GUID_INVALID)
238 {
239 /* What to return in case of wrong Guid */
240 return Utf8Str("00000000-0000-0000-0000-00000000000");
241 }
242
243 char buf[RTUUID_STR_LENGTH];
244 ::memset(buf, '\0', sizeof(buf));
245 ::RTUuidToStr(&mUuid, buf, sizeof(buf));
246
247 return Utf8Str(buf);
248 }
249
250 /**
251 * Like toString, but encloses the returned string in curly brackets.
252 *
253 * @returns String object containing the formatted GUID in curly brackets.
254 * @throws std::bad_alloc
255 */
256 Utf8Str toStringCurly() const
257 {
258 if (mGuidState == GUID_INVALID)
259 {
260 /* What to return in case of wrong Guid */
261 return Utf8Str("{00000000-0000-0000-0000-00000000000}");
262 }
263
264 char buf[RTUUID_STR_LENGTH + 2];
265 ::memset(buf, '\0', sizeof(buf));
266 ::RTUuidToStr(&mUuid, buf + 1, sizeof(buf) - 2);
267 buf[0] = '{';
268 buf[sizeof(buf) - 2] = '}';
269
270 return Utf8Str(buf);
271 }
272
273 /**
274 * Convert the GUID to a string.
275 *
276 * @returns Bstr object containing the formatted GUID.
277 * @throws std::bad_alloc
278 */
279 Bstr toUtf16() const
280 {
281 if (mGuidState == GUID_INVALID)
282 {
283 /* What to return in case of wrong Guid */
284 return Bstr("00000000-0000-0000-0000-00000000000");
285 }
286
287 RTUTF16 buf[RTUUID_STR_LENGTH];
288 ::memset(buf, '\0', sizeof(buf));
289 ::RTUuidToUtf16(&mUuid, buf, RT_ELEMENTS(buf));
290
291 return Bstr(buf);
292 }
293
294 bool isValid() const
295 {
296 return mGuidState != GUID_INVALID;
297 }
298
299 bool isZero() const
300 {
301 return mGuidState == GUID_ZERO;
302 }
303
304 bool operator==(const Guid &that) const { return ::RTUuidCompare(&mUuid, &that.mUuid) == 0; }
305 bool operator==(const RTUUID &guid) const { return ::RTUuidCompare(&mUuid, &guid) == 0; }
306 bool operator==(const GUID &guid) const { return ::RTUuidCompare(&mUuid, (PRTUUID)&guid) == 0; }
307 bool operator!=(const Guid &that) const { return !operator==(that); }
308 bool operator!=(const GUID &guid) const { return !operator==(guid); }
309 bool operator!=(const RTUUID &guid) const { return !operator==(guid); }
310 bool operator<(const Guid &that) const { return ::RTUuidCompare(&mUuid, &that.mUuid) < 0; }
311 bool operator<(const GUID &guid) const { return ::RTUuidCompare(&mUuid, (PRTUUID)&guid) < 0; }
312 bool operator<(const RTUUID &guid) const { return ::RTUuidCompare(&mUuid, &guid) < 0; }
313
314 /**
315 * To directly copy the contents to a GUID, or for passing it as an input
316 * parameter of type (const GUID *), the compiler converts. */
317 const GUID &ref() const
318 {
319 return *(const GUID *)&mUuid;
320 }
321
322 /**
323 * To pass instances to printf-like functions.
324 */
325 PCRTUUID raw() const
326 {
327 return (PCRTUUID)&mUuid;
328 }
329
330#if !defined(VBOX_WITH_XPCOM)
331
332 /** To assign instances to OUT_GUID parameters from within the interface
333 * method. */
334 const Guid &cloneTo(GUID *pguid) const
335 {
336 if (pguid)
337 ::memcpy(pguid, &mUuid, sizeof(GUID));
338 return *this;
339 }
340
341 /** To pass instances as OUT_GUID parameters to interface methods. */
342 GUID *asOutParam()
343 {
344 return (GUID *)&mUuid;
345 }
346
347#else
348
349 /** To assign instances to OUT_GUID parameters from within the
350 * interface method */
351 const Guid &cloneTo(nsID **ppGuid) const
352 {
353 if (ppGuid)
354 *ppGuid = (nsID *)nsMemory::Clone(&mUuid, sizeof(nsID));
355
356 return *this;
357 }
358
359 /**
360 * Internal helper class for asOutParam().
361 *
362 * This takes a GUID reference in the constructor and copies the mUuid from
363 * the method to that instance in its destructor.
364 */
365 class GuidOutParam
366 {
367 GuidOutParam(Guid &guid)
368 : ptr(0),
369 outer(guid)
370 {
371 outer.clear();
372 }
373
374 nsID *ptr;
375 Guid &outer;
376 GuidOutParam(const GuidOutParam &that); // disabled
377 GuidOutParam &operator=(const GuidOutParam &that); // disabled
378 public:
379 operator nsID**() { return &ptr; }
380 ~GuidOutParam()
381 {
382 if (ptr && outer.isZero())
383 {
384 outer = *ptr;
385 outer.dbg_refresh();
386 nsMemory::Free(ptr);
387 }
388 }
389 friend class Guid;
390 };
391
392 /** to pass instances as OUT_GUID parameters to interface methods */
393 GuidOutParam asOutParam() { return GuidOutParam(*this); }
394
395#endif
396
397 /**
398 * Static immutable empty (zero) object. May be used for comparison purposes.
399 */
400 static const Guid Empty;
401
402private:
403 void updateState()
404 {
405 if (::RTUuidIsNull(&mUuid))
406 mGuidState = GUID_ZERO;
407 else
408 mGuidState = GUID_NORMAL;
409 }
410
411 void initString(const char *that)
412 {
413 if (!that || !*that)
414 {
415 ::RTUuidClear(&mUuid);
416 mGuidState = GUID_ZERO;
417 }
418 else
419 {
420 int rc = ::RTUuidFromStr(&mUuid, that);
421 if (RT_FAILURE(rc))
422 {
423 ::RTUuidClear(&mUuid);
424 mGuidState = GUID_INVALID;
425 }
426 else
427 updateState();
428 }
429 dbg_refresh();
430 }
431
432 void initBSTR(CBSTR that)
433 {
434 if (!that || !*that)
435 {
436 ::RTUuidClear(&mUuid);
437 mGuidState = GUID_ZERO;
438 }
439 else
440 {
441 int rc = ::RTUuidFromUtf16(&mUuid, that);
442 if (RT_FAILURE(rc))
443 {
444 ::RTUuidClear(&mUuid);
445 mGuidState = GUID_INVALID;
446 }
447 else
448 updateState();
449 }
450 dbg_refresh();
451 }
452
453 /**
454 * Refresh the debug-only UUID string.
455 *
456 * In debug code, refresh the UUID string representatino for debugging;
457 * must be called every time the internal uuid changes; compiles to nothing
458 * in release code.
459 */
460 inline void dbg_refresh()
461 {
462#ifdef DEBUG
463 switch (mGuidState)
464 {
465 case GUID_ZERO:
466 case GUID_NORMAL:
467 ::RTUuidToStr(&mUuid, mszUuid, RTUUID_STR_LENGTH);
468 break;
469 default:
470 ::memset(mszUuid, '\0', sizeof(mszUuid));
471 ::RTStrCopy(mszUuid, sizeof(mszUuid), "INVALID");
472 break;
473 }
474 m_pcszUUID = mszUuid;
475#endif
476 }
477
478 /** The UUID. */
479 RTUUID mUuid;
480
481 GuidState_t mGuidState;
482
483#ifdef DEBUG
484 /** String representation of mUuid for printing in the debugger. */
485 char mszUuid[RTUUID_STR_LENGTH];
486 /** Another string variant for the debugger, points to szUUID. */
487 const char *m_pcszUUID;
488#endif
489};
490
491} /* namespace com */
492
493/** @} */
494
495#endif /* !___VBox_com_Guid_h */
496
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette