VirtualBox

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

Last change on this file since 73768 was 72906, checked in by vboxsync, 6 years ago

com::Guid: be optimistic, test for RT_SUCCESS when parsing strings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 KB
Line 
1/* $Id: Guid.h 72906 2018-07-04 22:22:16Z 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 clear();
70 }
71
72 Guid(const Guid &that)
73 {
74 mUuid = that.mUuid;
75 mGuidState = that.mGuidState;
76 dbg_refresh();
77 }
78
79 Guid(const RTUUID &that)
80 {
81 mUuid = that;
82 updateState();
83 dbg_refresh();
84 }
85
86 Guid(const GUID &that)
87 {
88 AssertCompileSize(GUID, sizeof(RTUUID));
89 ::memcpy(&mUuid, &that, sizeof(GUID));
90 updateState();
91 dbg_refresh();
92 }
93
94 /**
95 * Construct a GUID from a string.
96 *
97 * @param that The UUID string. Can be with or without the curly
98 * brackets. Empty strings are translated to a zero
99 * GUID, and strings which are not confirming to
100 * valid GUID string representations are marked as
101 * invalid.
102 */
103 Guid(const char *that)
104 {
105 initString(that);
106 }
107
108 /**
109 * Construct a GUID from a BSTR.
110 *
111 * @param that The UUID BSTR. Can be with or without the curly
112 * brackets. Empty strings are translated to a zero
113 * GUID, and strings which are not confirming to
114 * valid GUID string representations are marked as
115 * invalid.
116 */
117 Guid(CBSTR that)
118 {
119 initBSTR(that);
120 }
121
122 /**
123 * Construct a GUID from a Utf8Str.
124 *
125 * @param that The UUID Utf8Str. Can be with or without the curly
126 * brackets. Empty strings are translated to a zero
127 * GUID, and strings which are not confirming to
128 * valid GUID string representations are marked as
129 */
130 Guid(const Utf8Str &that)
131 {
132 initString(that.c_str());
133 }
134
135 /**
136 * Construct a GUID from a RTCString.
137 *
138 * @param that The UUID RTCString. Can be with or without the curly
139 * brackets. Empty strings are translated to a zero
140 * GUID, and strings which are not confirming to
141 * valid GUID string representations are marked as
142 */
143 Guid(const RTCString &that)
144 {
145 initString(that.c_str());
146 }
147
148 /**
149 * Construct a GUID from a Bstr.
150 *
151 * @param that The UUID Bstr. Can be with or without the curly
152 * brackets. Empty strings are translated to a zero
153 * GUID, and strings which are not confirming to
154 * valid GUID string representations are marked as
155 */
156 Guid(const Bstr &that)
157 {
158 initBSTR(that.raw());
159 }
160
161 Guid& operator=(const Guid &that)
162 {
163 mUuid = that.mUuid;
164 mGuidState = that.mGuidState;
165 dbg_refresh();
166 return *this;
167 }
168
169 Guid& operator=(const RTUUID &guid)
170 {
171 mUuid = guid;
172 updateState();
173 dbg_refresh();
174 return *this;
175 }
176
177 Guid& operator=(const GUID &guid)
178 {
179 AssertCompileSize(GUID, sizeof(RTUUID));
180 ::memcpy(&mUuid, &guid, sizeof(GUID));
181 updateState();
182 dbg_refresh();
183 return *this;
184 }
185
186 Guid& operator=(const char *str)
187 {
188 initString(str);
189 return *this;
190 }
191
192 Guid& operator=(CBSTR str)
193 {
194 initBSTR(str);
195 return *this;
196 }
197
198 Guid& operator=(const Utf8Str &str)
199 {
200 return operator=(str.c_str());
201 }
202
203 Guid& operator=(const RTCString &str)
204 {
205 return operator=(str.c_str());
206 }
207
208 Guid& operator=(const Bstr &str)
209 {
210 return operator=(str.raw());
211 }
212
213 void create()
214 {
215 ::RTUuidCreate(&mUuid);
216 mGuidState = GUID_NORMAL;
217 dbg_refresh();
218 }
219
220 void clear()
221 {
222 makeClear();
223 dbg_refresh();
224 }
225
226 /**
227 * Convert the GUID to a string.
228 *
229 * @returns String object containing the formatted GUID.
230 * @throws std::bad_alloc
231 */
232 Utf8Str toString() const
233 {
234 if (mGuidState == GUID_INVALID)
235 {
236 /* What to return in case of wrong Guid */
237 return Utf8Str("00000000-0000-0000-0000-00000000000");
238 }
239
240 char buf[RTUUID_STR_LENGTH];
241 ::memset(buf, '\0', sizeof(buf));
242 ::RTUuidToStr(&mUuid, buf, sizeof(buf));
243
244 return Utf8Str(buf);
245 }
246
247 /**
248 * Like toString, but encloses the returned string in curly brackets.
249 *
250 * @returns String object containing the formatted GUID in curly brackets.
251 * @throws std::bad_alloc
252 */
253 Utf8Str toStringCurly() const
254 {
255 if (mGuidState == GUID_INVALID)
256 {
257 /* What to return in case of wrong Guid */
258 return Utf8Str("{00000000-0000-0000-0000-00000000000}");
259 }
260
261 char buf[RTUUID_STR_LENGTH + 2];
262 ::memset(buf, '\0', sizeof(buf));
263 ::RTUuidToStr(&mUuid, buf + 1, sizeof(buf) - 2);
264 buf[0] = '{';
265 buf[sizeof(buf) - 2] = '}';
266
267 return Utf8Str(buf);
268 }
269
270 /**
271 * Convert the GUID to a string.
272 *
273 * @returns Bstr object containing the formatted GUID.
274 * @throws std::bad_alloc
275 */
276 Bstr toUtf16() const
277 {
278 if (mGuidState == GUID_INVALID)
279 {
280 /* What to return in case of wrong Guid */
281 return Bstr("00000000-0000-0000-0000-00000000000");
282 }
283
284 RTUTF16 buf[RTUUID_STR_LENGTH];
285 ::memset(buf, '\0', sizeof(buf));
286 ::RTUuidToUtf16(&mUuid, buf, RT_ELEMENTS(buf));
287
288 return Bstr(buf);
289 }
290
291 bool isValid() const
292 {
293 return mGuidState != GUID_INVALID;
294 }
295
296 bool isZero() const
297 {
298 return mGuidState == GUID_ZERO;
299 }
300
301 bool operator==(const Guid &that) const { return ::RTUuidCompare(&mUuid, &that.mUuid) == 0; }
302 bool operator==(const RTUUID &guid) const { return ::RTUuidCompare(&mUuid, &guid) == 0; }
303 bool operator==(const GUID &guid) const { return ::RTUuidCompare(&mUuid, (PRTUUID)&guid) == 0; }
304 bool operator!=(const Guid &that) const { return !operator==(that); }
305 bool operator!=(const GUID &guid) const { return !operator==(guid); }
306 bool operator!=(const RTUUID &guid) const { return !operator==(guid); }
307 bool operator<(const Guid &that) const { return ::RTUuidCompare(&mUuid, &that.mUuid) < 0; }
308 bool operator<(const GUID &guid) const { return ::RTUuidCompare(&mUuid, (PRTUUID)&guid) < 0; }
309 bool operator<(const RTUUID &guid) const { return ::RTUuidCompare(&mUuid, &guid) < 0; }
310
311 /**
312 * To directly copy the contents to a GUID, or for passing it as an input
313 * parameter of type (const GUID *), the compiler converts. */
314 const GUID &ref() const
315 {
316 return *(const GUID *)&mUuid;
317 }
318
319 /**
320 * To pass instances to printf-like functions.
321 */
322 PCRTUUID raw() const
323 {
324 return (PCRTUUID)&mUuid;
325 }
326
327#if !defined(VBOX_WITH_XPCOM)
328
329 /** To assign instances to OUT_GUID parameters from within the interface
330 * method. */
331 const Guid &cloneTo(GUID *pguid) const
332 {
333 if (pguid)
334 ::memcpy(pguid, &mUuid, sizeof(GUID));
335 return *this;
336 }
337
338 /** To pass instances as OUT_GUID parameters to interface methods. */
339 GUID *asOutParam()
340 {
341 return (GUID *)&mUuid;
342 }
343
344#else
345
346 /** To assign instances to OUT_GUID parameters from within the
347 * interface method */
348 const Guid &cloneTo(nsID **ppGuid) const
349 {
350 if (ppGuid)
351 *ppGuid = (nsID *)nsMemory::Clone(&mUuid, sizeof(nsID));
352
353 return *this;
354 }
355
356 /**
357 * Internal helper class for asOutParam().
358 *
359 * This takes a GUID reference in the constructor and copies the mUuid from
360 * the method to that instance in its destructor.
361 */
362 class GuidOutParam
363 {
364 GuidOutParam(Guid &guid)
365 : ptr(0),
366 outer(guid)
367 {
368 outer.clear();
369 }
370
371 nsID *ptr;
372 Guid &outer;
373 GuidOutParam(const GuidOutParam &that); // disabled
374 GuidOutParam &operator=(const GuidOutParam &that); // disabled
375 public:
376 operator nsID**() { return &ptr; }
377 ~GuidOutParam()
378 {
379 if (ptr && outer.isZero())
380 {
381 outer = *ptr;
382 outer.dbg_refresh();
383 nsMemory::Free(ptr);
384 }
385 }
386 friend class Guid;
387 };
388
389 /** to pass instances as OUT_GUID parameters to interface methods */
390 GuidOutParam asOutParam() { return GuidOutParam(*this); }
391
392#endif
393
394 /**
395 * Static immutable empty (zero) object. May be used for comparison purposes.
396 */
397 static const Guid Empty;
398
399private:
400 void makeClear()
401 {
402 ::RTUuidClear(&mUuid);
403 mGuidState = GUID_ZERO;
404 }
405
406 void makeInvalid()
407 {
408 ::RTUuidClear(&mUuid);
409 mGuidState = GUID_INVALID;
410 }
411
412 void updateState()
413 {
414 if (::RTUuidIsNull(&mUuid))
415 mGuidState = GUID_ZERO;
416 else
417 mGuidState = GUID_NORMAL;
418 }
419
420 void initString(const char *that)
421 {
422 if (!that || !*that)
423 {
424 makeClear();
425 }
426 else
427 {
428 int rc = ::RTUuidFromStr(&mUuid, that);
429 if (RT_SUCCESS(rc))
430 updateState();
431 else
432 makeInvalid();
433 }
434 dbg_refresh();
435 }
436
437 void initBSTR(CBSTR that)
438 {
439 if (!that || !*that)
440 {
441 makeClear();
442 }
443 else
444 {
445 int rc = ::RTUuidFromUtf16(&mUuid, that);
446 if (RT_SUCCESS(rc))
447 updateState();
448 else
449 makeInvalid();
450 }
451 dbg_refresh();
452 }
453
454 /**
455 * Refresh the debug-only UUID string.
456 *
457 * In debug code, refresh the UUID string representatino for debugging;
458 * must be called every time the internal uuid changes; compiles to nothing
459 * in release code.
460 */
461 inline void dbg_refresh()
462 {
463#ifdef DEBUG
464 switch (mGuidState)
465 {
466 case GUID_ZERO:
467 case GUID_NORMAL:
468 ::RTUuidToStr(&mUuid, mszUuid, RTUUID_STR_LENGTH);
469 break;
470 default:
471 ::memset(mszUuid, '\0', sizeof(mszUuid));
472 ::RTStrCopy(mszUuid, sizeof(mszUuid), "INVALID");
473 break;
474 }
475 m_pcszUUID = mszUuid;
476#endif
477 }
478
479 /** The UUID. */
480 RTUUID mUuid;
481
482 GuidState_t mGuidState;
483
484#ifdef DEBUG
485 /** String representation of mUuid for printing in the debugger. */
486 char mszUuid[RTUUID_STR_LENGTH];
487 /** Another string variant for the debugger, points to szUUID. */
488 const char *m_pcszUUID;
489#endif
490};
491
492} /* namespace com */
493
494/** @} */
495
496#endif /* !___VBox_com_Guid_h */
497
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use