VirtualBox

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

Last change on this file since 229 was 1, checked in by vboxsync, 55 years ago

import

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