VirtualBox

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

Last change on this file since 3387 was 3387, checked in by vboxsync, 18 years ago

Main: com::GetVBoxUserHomeDirectory() now takes char * instead of Utf8Str because on XPCOM platforms, this function may be called before XPCOM has been initialized, when Utf8Str functionality is not yet available (because it uses XPCOM memory management).

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