VirtualBox

source: vbox/trunk/include/VBox/com/string.h@ 6065

Last change on this file since 6065 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.5 KB
Line 
1/** @file
2 * MS COM / XPCOM Abstraction Layer:
3 * Smart string classes declaration
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
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_string_h
28#define ___VBox_com_string_h
29
30#if !defined(RT_OS_WINDOWS)
31#include <nsMemory.h>
32#endif
33
34#include "VBox/com/defs.h"
35#include "VBox/com/assert.h"
36
37#include <iprt/string.h>
38#include <iprt/alloc.h>
39
40namespace com
41{
42
43class Utf8Str;
44
45/**
46 * Helper class that represents the |BSTR| type and hides platform-specific
47 * implementation details.
48 *
49 * This class uses COM/XPCOM-provided memory management routines to allocate
50 * and free string buffers. This makes it possible to:
51 * - use it as a type of member variables of COM/XPCOM components and pass
52 * their values to callers through component methods' output parameters
53 * using the #cloneTo() operation;
54 * - adopt (take ownership of) string buffers returned in output parameters
55 * of COM methods using the #asOutParam() operation and correctly free them
56 * afterwards.
57 */
58class Bstr
59{
60public:
61
62 typedef BSTR String;
63 typedef const BSTR ConstString;
64
65 Bstr () : bstr (NULL) {}
66
67 Bstr (const Bstr &that) : bstr (NULL) { raw_copy (bstr, that.bstr); }
68 Bstr (const BSTR that) : bstr (NULL) { raw_copy (bstr, that); }
69 Bstr (const wchar_t *that) : bstr (NULL)
70 {
71 AssertCompile (sizeof (wchar_t) == sizeof (OLECHAR));
72 raw_copy (bstr, (const BSTR) that);
73 }
74
75 Bstr (const Utf8Str &that);
76 Bstr (const char *that);
77
78 /** Shortcut that calls #alloc(aSize) right after object creation. */
79 Bstr (size_t aSize) : bstr (NULL) { alloc (aSize); }
80
81 ~Bstr () { setNull(); }
82
83 Bstr &operator = (const Bstr &that) { safe_assign (that.bstr); return *this; }
84 Bstr &operator = (const BSTR that) { safe_assign (that); return *this; }
85
86 Bstr &operator = (const Utf8Str &that);
87 Bstr &operator = (const char *that);
88
89 Bstr &setNull()
90 {
91 if (bstr)
92 {
93 ::SysFreeString (bstr);
94 bstr = NULL;
95 }
96 return *this;
97 }
98
99 Bstr &setNullIfEmpty()
100 {
101 if (bstr && *bstr == 0)
102 {
103 ::SysFreeString (bstr);
104 bstr = NULL;
105 }
106 return *this;
107 }
108
109 /**
110 * Allocates memory for a string capable to store \a aSize - 1 characters
111 * plus the terminating zero character. If \a aSize is zero, or if a
112 * memory allocation error occurs, this object will become null.
113 */
114 Bstr &alloc (size_t aSize)
115 {
116 setNull();
117 if (aSize)
118 {
119 unsigned int size = (unsigned int) aSize; Assert (size == aSize);
120 bstr = ::SysAllocStringLen (NULL, size - 1);
121 if (bstr)
122 bstr [0] = 0;
123 }
124 return *this;
125 }
126
127 int compare (const BSTR str) const
128 {
129 return ::RTStrUcs2Cmp ((PRTUCS2) bstr, (PRTUCS2) str);
130 }
131
132 bool operator == (const Bstr &that) const { return !compare (that.bstr); }
133 bool operator != (const Bstr &that) const { return !!compare (that.bstr); }
134 bool operator == (const BSTR that) const { return !compare (that); }
135 bool operator != (const wchar_t *that) const
136 {
137 AssertCompile (sizeof (wchar_t) == sizeof (OLECHAR));
138 return !!compare ((const BSTR) that);
139 }
140 bool operator == (const wchar_t *that) const
141 {
142 AssertCompile (sizeof (wchar_t) == sizeof (OLECHAR));
143 return !compare ((const BSTR) that);
144 }
145 bool operator != (const BSTR that) const { return !!compare (that); }
146 bool operator < (const Bstr &that) const { return compare (that.bstr) < 0; }
147 bool operator < (const BSTR that) const { return compare (that) < 0; }
148 bool operator < (const wchar_t *that) const
149 {
150 AssertCompile (sizeof (wchar_t) == sizeof (OLECHAR));
151 return compare ((const BSTR) that) < 0;
152 }
153
154 int compareIgnoreCase (const BSTR str) const
155 {
156 return ::RTUtf16LocaleICmp (bstr, str);
157 }
158
159 bool isNull() const { return bstr == NULL; }
160 operator bool() const { return !isNull(); }
161
162 bool isEmpty() const { return isNull() || *bstr == 0; }
163
164 size_t length() const { return isNull() ? 0 : ::RTStrUcs2Len ((PRTUCS2) bstr); }
165
166 /** Intended to to pass instances as |BSTR| input parameters to methods. */
167 operator const BSTR () const { return bstr; }
168
169 /** The same as operator const BSTR(), but for situations where the compiler
170 cannot typecast implicitly (for example, in printf() argument list). */
171 const BSTR raw() const { return bstr; }
172
173 /**
174 * Returns a non-const raw pointer that allows to modify the string directly.
175 * @warning
176 * Be sure not to modify data beyond the allocated memory! The
177 * guaranteed size of the allocated memory is at least #length()
178 * bytes after creation and after every assignment operation.
179 */
180 BSTR mutableRaw() { return bstr; }
181
182 /**
183 * Intended to assign instances to |BSTR| out parameters from within the
184 * interface method. Transfers the ownership of the duplicated string to
185 * the caller.
186 */
187 const Bstr &cloneTo (BSTR *pstr) const
188 {
189 if (pstr)
190 {
191 *pstr = NULL;
192 raw_copy (*pstr, bstr);
193 }
194 return *this;
195 }
196
197 /**
198 * Intended to assign instances to |char *| out parameters from within the
199 * interface method. Transfers the ownership of the duplicated string to
200 * the caller.
201 */
202 const Bstr &cloneTo (char **pstr) const;
203
204 /**
205 * Intended to pass instances as |BSTR| out parameters to methods.
206 * Takes the ownership of the returned data.
207 */
208 BSTR *asOutParam() { setNull(); return &bstr; }
209
210private:
211
212 void safe_assign (const BSTR str)
213 {
214 if (bstr != str)
215 {
216 setNull();
217 raw_copy (bstr, str);
218 }
219 }
220
221 inline static void raw_copy (BSTR &ls, const BSTR rs)
222 {
223 if (rs)
224 ls = ::SysAllocString ((const OLECHAR *) rs);
225 }
226
227 inline static void raw_copy (BSTR &ls, const char *rs)
228 {
229 if (rs)
230 {
231 PRTUCS2 s = NULL;
232 ::RTStrUtf8ToUcs2 (&s, rs);
233 raw_copy (ls, (BSTR) s);
234 ::RTStrUcs2Free (s);
235 }
236 }
237
238 BSTR bstr;
239
240 friend class Utf8Str; // to access our raw_copy()
241};
242
243// symmetric compare operators
244inline bool operator== (const BSTR l, const Bstr &r) { return r.operator== (l); }
245inline bool operator!= (const BSTR l, const Bstr &r) { return r.operator!= (l); }
246
247////////////////////////////////////////////////////////////////////////////////
248
249/**
250 * Helper class that represents UTF8 (|char *|) strings. Useful in
251 * conjunction with Bstr to simplify conversions beetween UCS2 (|BSTR|)
252 * and UTF8.
253 *
254 * This class uses COM/XPCOM-provided memory management routines to allocate
255 * and free string buffers. This makes it possible to:
256 * - use it as a type of member variables of COM/XPCOM components and pass
257 * their values to callers through component methods' output parameters
258 * using the #cloneTo() operation;
259 * - adopt (take ownership of) string buffers returned in output parameters
260 * of COM methods using the #asOutParam() operation and correctly free them
261 * afterwards.
262 */
263class Utf8Str
264{
265public:
266
267 typedef char *String;
268 typedef const char *ConstString;
269
270 Utf8Str () : str (NULL) {}
271
272 Utf8Str (const Utf8Str &that) : str (NULL) { raw_copy (str, that.str); }
273 Utf8Str (const char *that) : str (NULL) { raw_copy (str, that); }
274
275 Utf8Str (const Bstr &that) : str (NULL) { raw_copy (str, that); }
276 Utf8Str (const BSTR that) : str (NULL) { raw_copy (str, that); }
277
278 /** Shortcut that calls #alloc(aSize) right after object creation. */
279 Utf8Str (size_t aSize) : str (NULL) { alloc(aSize); }
280
281 virtual ~Utf8Str () { setNull(); }
282
283 Utf8Str &operator = (const Utf8Str &that) { safe_assign (that.str); return *this; }
284 Utf8Str &operator = (const char *that) { safe_assign (that); return *this; }
285
286 Utf8Str &operator = (const Bstr &that)
287 {
288 setNull();
289 raw_copy (str, that);
290 return *this;
291 }
292 Utf8Str &operator = (const BSTR that)
293 {
294 setNull();
295 raw_copy (str, that);
296 return *this;
297 }
298
299 Utf8Str &setNull()
300 {
301 if (str)
302 {
303#if defined (RT_OS_WINDOWS)
304 ::RTStrFree (str);
305#else
306 nsMemory::Free (str);
307#endif
308 str = NULL;
309 }
310 return *this;
311 }
312
313 Utf8Str &setNullIfEmpty()
314 {
315 if (str && *str == 0)
316 {
317#if defined (RT_OS_WINDOWS)
318 ::RTStrFree (str);
319#else
320 nsMemory::Free (str);
321#endif
322 str = NULL;
323 }
324 return *this;
325 }
326
327 /**
328 * Allocates memory for a string capable to store \a aSize - 1 characters
329 * plus the terminating zero character. If \a aSize is zero, or if a
330 * memory allocation error occurs, this object will become null.
331 */
332 Utf8Str &alloc (size_t aSize)
333 {
334 setNull();
335 if (aSize)
336 {
337#if defined (RT_OS_WINDOWS)
338 str = (char *) ::RTMemTmpAlloc (aSize);
339#else
340 str = (char *) nsMemory::Alloc (aSize);
341#endif
342 if (str)
343 str [0] = 0;
344 }
345 return *this;
346 }
347
348 int compare (const char *s) const
349 {
350 return str == s ? 0 : ::strcmp (str, s);
351 }
352
353 bool operator == (const Utf8Str &that) const { return !compare (that.str); }
354 bool operator != (const Utf8Str &that) const { return !!compare (that.str); }
355 bool operator == (const char *that) const { return !compare (that); }
356 bool operator != (const char *that) const { return !!compare (that); }
357 bool operator < (const Utf8Str &that) const { return compare (that.str) < 0; }
358 bool operator < (const char *that) const { return compare (that) < 0; }
359
360 bool isNull() const { return str == NULL; }
361 operator bool() const { return !isNull(); }
362
363 bool isEmpty() const { return isNull() || *str == 0; }
364
365 size_t length() const { return isNull() ? 0 : ::strlen (str); }
366
367 /** Intended to to pass instances as input (|char *|) parameters to methods. */
368 operator const char *() const { return str; }
369
370 /** The same as operator const char *(), but for situations where the compiler
371 cannot typecast implicitly (for example, in printf() argument list). */
372 const char *raw() const { return str; }
373
374 /**
375 * Returns a non-const raw pointer that allows to modify the string directly.
376 * @warning
377 * Be sure not to modify data beyond the allocated memory! The
378 * guaranteed size of the allocated memory is at least #length()
379 * bytes after creation and after every assignment operation.
380 */
381 char *mutableRaw() { return str; }
382
383 /**
384 * Intended to assign instances to |char *| out parameters from within the
385 * interface method. Transfers the ownership of the duplicated string to the
386 * caller.
387 */
388 const Utf8Str &cloneTo (char **pstr) const
389 {
390 if (pstr)
391 {
392 *pstr = NULL;
393 raw_copy (*pstr, str);
394 }
395 return *this;
396 }
397
398 /**
399 * Intended to assign instances to |BSTR| out parameters from within the
400 * interface method. Transfers the ownership of the duplicated string to the
401 * caller.
402 */
403 const Utf8Str &cloneTo (BSTR *pstr) const
404 {
405 if (pstr)
406 {
407 *pstr = NULL;
408 Bstr::raw_copy (*pstr, str);
409 }
410 return *this;
411 }
412
413 /**
414 * Intended to pass instances as out (|char **|) parameters to methods.
415 * Takes the ownership of the returned data.
416 */
417 char **asOutParam() { setNull(); return &str; }
418
419private:
420
421 void safe_assign (const char *s)
422 {
423 if (str != s)
424 {
425 setNull();
426 raw_copy (str, s);
427 }
428 }
429
430 inline static void raw_copy (char *&ls, const char *rs)
431 {
432 if (rs)
433#if defined (RT_OS_WINDOWS)
434 ::RTStrDupEx (&ls, rs);
435#else
436 ls = (char *) nsMemory::Clone (rs, strlen (rs) + 1);
437#endif
438 }
439
440 inline static void raw_copy (char *&ls, const BSTR rs)
441 {
442 if (rs)
443 {
444#if defined (RT_OS_WINDOWS)
445 ::RTStrUcs2ToUtf8 (&ls, (PRTUCS2) rs);
446#else
447 char *s = NULL;
448 ::RTStrUcs2ToUtf8 (&s, (PRTUCS2) rs);
449 raw_copy (ls, s);
450 ::RTStrFree (s);
451#endif
452 }
453 }
454
455 char *str;
456
457 friend class Bstr; // to access our raw_copy()
458};
459
460// symmetric compare operators
461inline bool operator== (const char *l, const Utf8Str &r) { return r.operator== (l); }
462inline bool operator!= (const char *l, const Utf8Str &r) { return r.operator!= (l); }
463
464// work around error C2593 of the stupid MSVC 7.x ambiguity resolver
465WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP (Bstr)
466WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP (Utf8Str)
467
468////////////////////////////////////////////////////////////////////////////////
469
470// inlined Bstr members that depend on Utf8Str
471
472inline Bstr::Bstr (const Utf8Str &that) : bstr (NULL) { raw_copy (bstr, that); }
473inline Bstr::Bstr (const char *that) : bstr (NULL) { raw_copy (bstr, that); }
474
475inline Bstr &Bstr::operator = (const Utf8Str &that)
476{
477 setNull();
478 raw_copy (bstr, that);
479 return *this;
480}
481inline Bstr &Bstr::operator = (const char *that)
482{
483 setNull();
484 raw_copy (bstr, that);
485 return *this;
486}
487
488inline const Bstr &Bstr::cloneTo (char **pstr) const
489{
490 if (pstr) {
491 *pstr = NULL;
492 Utf8Str::raw_copy (*pstr, bstr);
493 }
494 return *this;
495}
496
497////////////////////////////////////////////////////////////////////////////////
498
499/**
500 * This class is a printf-like formatter for Utf8Str strings. Its purpose is
501 * to construct Utf8Str objects from a format string and a list of arguments
502 * for the format string.
503 *
504 * The usage of this class is like the following:
505 * <code>
506 * Utf8StrFmt string ("program name = %s", argv[0]);
507 * </code>
508 */
509class Utf8StrFmt : public Utf8Str
510{
511public:
512
513 /**
514 * Constructs a new string given the format string and the list
515 * of the arguments for the format string.
516 *
517 * @param format printf-like format string (in UTF-8 encoding)
518 * @param ... list of the arguments for the format string
519 */
520 explicit Utf8StrFmt (const char *format, ...)
521 {
522 va_list args;
523 va_start (args, format);
524 init (format, args);
525 va_end (args);
526 }
527
528protected:
529
530 Utf8StrFmt() {}
531
532 void init (const char *format, va_list args);
533
534private:
535
536 static DECLCALLBACK(size_t) strOutput (void *pvArg, const char *pachChars,
537 size_t cbChars);
538};
539
540/**
541 * This class is a vprintf-like formatter for Utf8Str strings. It is
542 * identical to Utf8StrFmt except that its constructor takes a va_list
543 * argument instead of ellipsis.
544 *
545 * Note that a separate class is necessary because va_list is defined as
546 * |char *| on most platforms. For this reason, if we had two overloaded
547 * constructors in Utf8StrFmt (one taking ellipsis and another one taking
548 * va_list) then composing a constructor call using exactly two |char *|
549 * arguments would cause the compiler to use the va_list overload instead of
550 * the ellipsis one which is obviously wrong. The compiler would choose
551 * va_list because ellipsis has the lowest rank when it comes to resolving
552 * overloads, as opposed to va_list which is an exact match for |char *|.
553 */
554class Utf8StrFmtVA : public Utf8StrFmt
555{
556public:
557
558 /**
559 * Constructs a new string given the format string and the list
560 * of the arguments for the format string.
561 *
562 * @param format printf-like format string (in UTF-8 encoding)
563 * @param args list of arguments for the format string
564 */
565 Utf8StrFmtVA (const char *format, va_list args) { init (format, args); }
566};
567
568} /* namespace com */
569
570#endif
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