VirtualBox

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

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

AMD64 -> RT_ARCH_AMD64; X86 -> RT_ARCH_X86; [OS] -> RT_OS_[OS].

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