VirtualBox

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

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

InnoTek -> innotek: all the headers and comments.

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