VirtualBox

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

Last change on this file since 103224 was 98103, checked in by vboxsync, 2 years ago

Copyright year updates by scm.

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

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