VirtualBox

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

Last change on this file since 36254 was 35128, checked in by vboxsync, 14 years ago

Main: more backslash conversion in settings read/write, so add generic methods to XML classes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.5 KB
Line 
1/* $Id: string.h 35128 2010-12-15 12:38:41Z vboxsync $ */
2
3/** @file
4 * MS COM / XPCOM Abstraction Layer:
5 * Smart string classes declaration
6 */
7
8/*
9 * Copyright (C) 2006-2010 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * The contents of this file may alternatively be used under the terms
20 * of the Common Development and Distribution License Version 1.0
21 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
22 * VirtualBox OSE distribution, in which case the provisions of the
23 * CDDL are applicable instead of those of the GPL.
24 *
25 * You may elect to license modified versions of this file under the
26 * terms and conditions of either the GPL or the CDDL or both.
27 */
28
29#ifndef ___VBox_com_string_h
30#define ___VBox_com_string_h
31
32/* Make sure all the stdint.h macros are included - must come first! */
33#ifndef __STDC_LIMIT_MACROS
34# define __STDC_LIMIT_MACROS
35#endif
36#ifndef __STDC_CONSTANT_MACROS
37# define __STDC_CONSTANT_MACROS
38#endif
39
40#if defined(VBOX_WITH_XPCOM)
41# include <nsMemory.h>
42#endif
43
44#include "VBox/com/defs.h"
45#include "VBox/com/assert.h"
46
47#include <iprt/mem.h>
48#include <iprt/cpp/ministring.h>
49
50namespace com
51{
52
53class Utf8Str;
54
55// global constant in glue/string.cpp that represents an empty BSTR
56extern const BSTR g_bstrEmpty;
57
58/**
59 * String class used universally in Main for COM-style Utf-16 strings.
60 * Unfortunately COM on Windows uses UTF-16 everywhere, requiring conversions
61 * back and forth since most of VirtualBox and our libraries use UTF-8.
62 *
63 * To make things more obscure, on Windows, a COM-style BSTR is not just a
64 * pointer to a null-terminated wide character array, but the four bytes
65 * (32 bits) BEFORE the memory that the pointer points to are a length
66 * DWORD. One must therefore avoid pointer arithmetic and always use
67 * SysAllocString and the like to deal with BSTR pointers, which manage
68 * that DWORD correctly.
69 *
70 * For platforms other than Windows, we provide our own versions of the
71 * Sys* functions in Main/xpcom/helpers.cpp which do NOT use length
72 * prefixes though to be compatible with how XPCOM allocates string
73 * parameters to public functions.
74 *
75 * The Bstr class hides all this handling behind a std::string-like interface
76 * and also provides automatic conversions to MiniString and Utf8Str instances.
77 *
78 * The one advantage of using the SysString* routines is that this makes it
79 * possible to use it as a type of member variables of COM/XPCOM components
80 * and pass their values to callers through component methods' output parameters
81 * using the #cloneTo() operation. Also, the class can adopt (take ownership of)
82 * string buffers returned in output parameters of COM methods using the
83 * #asOutParam() operation and correctly free them afterwards.
84 *
85 * Starting with VirtualBox 3.2, like Utf8Str, Bstr no longer differentiates
86 * between NULL strings and empty strings. In other words, Bstr("") and
87 * Bstr(NULL) behave the same. In both cases, Bstr allocates no memory,
88 * reports a zero length and zero allocated bytes for both, and returns an
89 * empty C wide string from raw().
90 */
91class Bstr
92{
93public:
94
95 Bstr()
96 : m_bstr(NULL)
97 { }
98
99 Bstr(const Bstr &that)
100 {
101 copyFrom((const OLECHAR *)that.m_bstr);
102 }
103
104 Bstr(CBSTR that)
105 {
106 copyFrom((const OLECHAR *)that);
107 }
108
109#if defined(VBOX_WITH_XPCOM)
110 Bstr(const wchar_t *that)
111 {
112 AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
113 copyFrom((const OLECHAR *)that);
114 }
115#endif
116
117 Bstr(const iprt::MiniString &that)
118 {
119 copyFrom(that.c_str());
120 }
121
122 Bstr(const char *that)
123 {
124 copyFrom(that);
125 }
126
127 Bstr(const char *a_pThat, size_t a_cchMax)
128 {
129 copyFromN(a_pThat, a_cchMax);
130 }
131
132 ~Bstr()
133 {
134 setNull();
135 }
136
137 Bstr& operator=(const Bstr &that)
138 {
139 cleanup();
140 copyFrom((const OLECHAR *)that.m_bstr);
141 return *this;
142 }
143
144 Bstr& operator=(CBSTR that)
145 {
146 cleanup();
147 copyFrom((const OLECHAR *)that);
148 return *this;
149 }
150
151#if defined(VBOX_WITH_XPCOM)
152 Bstr& operator=(const wchar_t *that)
153 {
154 cleanup();
155 copyFrom((const OLECHAR *)that);
156 return *this;
157 }
158#endif
159
160 Bstr& setNull()
161 {
162 cleanup();
163 return *this;
164 }
165
166 RTMEMEF_NEW_AND_DELETE_OPERATORS();
167
168 /** Case sensitivity selector. */
169 enum CaseSensitivity
170 {
171 CaseSensitive,
172 CaseInsensitive
173 };
174
175 /**
176 * Compares the member string to str.
177 * @param str
178 * @param cs Whether comparison should be case-sensitive.
179 * @return
180 */
181 int compare(CBSTR str, CaseSensitivity cs = CaseSensitive) const
182 {
183 if (cs == CaseSensitive)
184 return ::RTUtf16Cmp((PRTUTF16)m_bstr, (PRTUTF16)str);
185 return ::RTUtf16LocaleICmp((PRTUTF16)m_bstr, (PRTUTF16)str);
186 }
187
188 int compare(BSTR str, CaseSensitivity cs = CaseSensitive) const
189 {
190 return compare((CBSTR)str, cs);
191 }
192
193 int compare(const Bstr &that, CaseSensitivity cs = CaseSensitive) const
194 {
195 return compare(that.m_bstr, cs);
196 }
197
198 bool operator==(const Bstr &that) const { return !compare(that.m_bstr); }
199 bool operator!=(const Bstr &that) const { return !!compare(that.m_bstr); }
200 bool operator==(CBSTR that) const { return !compare(that); }
201 bool operator==(BSTR that) const { return !compare(that); }
202
203 bool operator!=(CBSTR that) const { return !!compare(that); }
204 bool operator!=(BSTR that) const { return !!compare(that); }
205 bool operator<(const Bstr &that) const { return compare(that.m_bstr) < 0; }
206 bool operator<(CBSTR that) const { return compare(that) < 0; }
207 bool operator<(BSTR that) const { return compare(that) < 0; }
208
209 /**
210 * Returns true if the member string has no length.
211 * This is true for instances created from both NULL and "" input strings.
212 *
213 * @note Always use this method to check if an instance is empty. Do not
214 * use length() because that may need to run through the entire string
215 * (Bstr does not cache string lengths).
216 */
217 bool isEmpty() const { return m_bstr == NULL || *m_bstr == 0; }
218
219 /**
220 * Returns true if the member string has a length of one or more.
221 *
222 * @returns true if not empty, false if empty (NULL or "").
223 */
224 bool isNotEmpty() const { return m_bstr != NULL && *m_bstr != 0; }
225
226 size_t length() const { return isEmpty() ? 0 : ::RTUtf16Len((PRTUTF16)m_bstr); }
227
228#if defined(VBOX_WITH_XPCOM)
229 /**
230 * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
231 * returns a pointer to a global variable containing an empty BSTR with a proper zero
232 * length prefix so that Windows is happy.
233 */
234 CBSTR raw() const
235 {
236 if (m_bstr)
237 return m_bstr;
238
239 return g_bstrEmpty;
240 }
241#else
242 /**
243 * Windows-only hack, as the automatically generated headers use BSTR.
244 * So if we don't want to cast like crazy we have to be more loose than
245 * on XPCOM.
246 *
247 * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
248 * returns a pointer to a global variable containing an empty BSTR with a proper zero
249 * length prefix so that Windows is happy.
250 */
251 BSTR raw() const
252 {
253 if (m_bstr)
254 return m_bstr;
255
256 return g_bstrEmpty;
257 }
258#endif
259
260 /**
261 * Returns a non-const raw pointer that allows to modify the string directly.
262 * As opposed to raw(), this DOES return NULL if the member string is empty
263 * because we cannot return a mutable pointer to the global variable with the
264 * empty string.
265 *
266 * @warning
267 * Be sure not to modify data beyond the allocated memory! The
268 * guaranteed size of the allocated memory is at least #length()
269 * bytes after creation and after every assignment operation.
270 */
271 BSTR mutableRaw() { return m_bstr; }
272
273 /**
274 * Intended to assign copies of instances to |BSTR| out parameters from
275 * within the interface method. Transfers the ownership of the duplicated
276 * string to the caller.
277 *
278 * If the member string is empty, this allocates an empty BSTR in *pstr
279 * (i.e. makes it point to a new buffer with a null byte).
280 */
281 void cloneTo(BSTR *pstr) const
282 {
283 if (pstr)
284 {
285 *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty
286#ifdef RT_EXCEPTIONS_ENABLED
287 if (!*pstr)
288 throw std::bad_alloc();
289#endif
290 }
291 }
292
293 /**
294 * Intended to assign instances to |BSTR| out parameters from within the
295 * interface method. Transfers the ownership of the original string to the
296 * caller and resets the instance to null.
297 *
298 * As opposed to cloneTo(), this method doesn't create a copy of the
299 * string.
300 *
301 * If the member string is empty, this allocates an empty BSTR in *pstr
302 * (i.e. makes it point to a new buffer with a null byte).
303 */
304 void detachTo(BSTR *pstr)
305 {
306 if (m_bstr)
307 *pstr = m_bstr;
308 else
309 {
310 // allocate null BSTR
311 *pstr = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
312#ifdef RT_EXCEPTIONS_ENABLED
313 if (!*pstr)
314 throw std::bad_alloc();
315#endif
316 }
317 m_bstr = NULL;
318 }
319
320 /**
321 * Intended to pass instances as |BSTR| out parameters to methods.
322 * Takes the ownership of the returned data.
323 */
324 BSTR* asOutParam()
325 {
326 cleanup();
327 return &m_bstr;
328 }
329
330 /**
331 * Static immutable empty-string object. May be used for comparison purposes.
332 */
333 static const Bstr Empty;
334
335protected:
336
337 void cleanup()
338 {
339 if (m_bstr)
340 {
341 ::SysFreeString(m_bstr);
342 m_bstr = NULL;
343 }
344 }
345
346 /**
347 * Protected internal helper to copy a string. This ignores the previous object
348 * state, so either call this from a constructor or call cleanup() first.
349 *
350 * This variant copies from a zero-terminated UTF-16 string (which need not
351 * be a BSTR, i.e. need not have a length prefix).
352 *
353 * If the source is empty, this sets the member string to NULL.
354 * @param rs
355 */
356 void copyFrom(const OLECHAR *rs)
357 {
358 if (rs && *rs)
359 {
360 m_bstr = ::SysAllocString(rs);
361#ifdef RT_EXCEPTIONS_ENABLED
362 if (!m_bstr)
363 throw std::bad_alloc();
364#endif
365 }
366 else
367 m_bstr = NULL;
368 }
369
370 /**
371 * Protected internal helper to copy a string. This ignores the previous object
372 * state, so either call this from a constructor or call cleanup() first.
373 *
374 * This variant copies and converts from a zero-terminated UTF-8 string.
375 *
376 * If the source is empty, this sets the member string to NULL.
377 * @param rs
378 */
379 void copyFrom(const char *rs)
380 {
381 if (rs && *rs)
382 {
383 PRTUTF16 s = NULL;
384 ::RTStrToUtf16(rs, &s);
385#ifdef RT_EXCEPTIONS_ENABLED
386 if (!s)
387 throw std::bad_alloc();
388#endif
389 copyFrom((const OLECHAR *)s); // allocates BSTR from zero-terminated input string
390 ::RTUtf16Free(s);
391 }
392 else
393 m_bstr = NULL;
394 }
395
396 /**
397 * Variant of copyFrom for sub-string constructors.
398 *
399 * @param a_pszSrc The source string.
400 * @param a_cchMax The maximum number of chars (not
401 * codepoints) to copy. If you pass RTSTR_MAX
402 * it'll be exactly like copyFrom().
403 * @throws std::bad_alloc
404 */
405 void copyFromN(const char *a_pszSrc, size_t a_cchSrc);
406
407 BSTR m_bstr;
408
409 friend class Utf8Str; /* to access our raw_copy() */
410};
411
412/* symmetric compare operators */
413inline bool operator==(CBSTR l, const Bstr &r) { return r.operator==(l); }
414inline bool operator!=(CBSTR l, const Bstr &r) { return r.operator!=(l); }
415inline bool operator==(BSTR l, const Bstr &r) { return r.operator==(l); }
416inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!=(l); }
417
418
419////////////////////////////////////////////////////////////////////////////////
420
421/**
422 * String class used universally in Main for UTF-8 strings.
423 *
424 * This is based on iprt::MiniString, to which some functionality has been
425 * moved. Here we keep things that are specific to Main, such as conversions
426 * with UTF-16 strings (Bstr).
427 *
428 * Like iprt::MiniString, Utf8Str does not differentiate between NULL strings
429 * and empty strings. In other words, Utf8Str("") and Utf8Str(NULL)
430 * behave the same. In both cases, MiniString allocates no memory, reports
431 * a zero length and zero allocated bytes for both, and returns an empty
432 * C string from c_str().
433 */
434class Utf8Str : public iprt::MiniString
435{
436public:
437
438 Utf8Str() {}
439
440 Utf8Str(const MiniString &that)
441 : MiniString(that)
442 {}
443
444 Utf8Str(const char *that)
445 : MiniString(that)
446 {}
447
448 Utf8Str(const Bstr &that)
449 {
450 copyFrom(that.raw());
451 }
452
453 Utf8Str(CBSTR that)
454 {
455 copyFrom(that);
456 }
457
458 /**
459 * Constructs a new string given the format string and the list of the
460 * arguments for the format string.
461 *
462 * @param a_pszFormat Pointer to the format string (UTF-8),
463 * @see pg_rt_str_format.
464 * @param a_va Argument vector containing the arguments
465 * specified by the format string.
466 * @sa iprt::MiniString::printfV
467 */
468 Utf8Str(const char *a_pszFormat, va_list a_va)
469 : MiniString(a_pszFormat, a_va)
470 {
471 }
472
473 Utf8Str& operator=(const MiniString &that)
474 {
475 MiniString::operator=(that);
476 return *this;
477 }
478
479 Utf8Str& operator=(const char *that)
480 {
481 MiniString::operator=(that);
482 return *this;
483 }
484
485 Utf8Str& operator=(const Bstr &that)
486 {
487 cleanup();
488 copyFrom(that.raw());
489 return *this;
490 }
491
492 Utf8Str& operator=(CBSTR that)
493 {
494 cleanup();
495 copyFrom(that);
496 return *this;
497 }
498
499 RTMEMEF_NEW_AND_DELETE_OPERATORS();
500
501#if defined(VBOX_WITH_XPCOM)
502 /**
503 * Intended to assign instances to |char *| out parameters from within the
504 * interface method. Transfers the ownership of the duplicated string to the
505 * caller.
506 *
507 * This allocates a single 0 byte in the target if the member string is empty.
508 *
509 * This uses XPCOM memory allocation and thus only works on XPCOM. MSCOM doesn't
510 * like char* strings anyway.
511 */
512 void cloneTo(char **pstr) const;
513#endif
514
515 /**
516 * Intended to assign instances to |BSTR| out parameters from within the
517 * interface method. Transfers the ownership of the duplicated string to the
518 * caller.
519 */
520 void cloneTo(BSTR *pstr) const
521 {
522 if (pstr)
523 {
524 Bstr bstr(*this);
525 bstr.cloneTo(pstr);
526 }
527 }
528
529 /**
530 * Removes a trailing slash from the member string, if present.
531 * Calls RTPathStripTrailingSlash() without having to mess with mutableRaw().
532 */
533 Utf8Str& stripTrailingSlash();
534
535 /**
536 * Removes a trailing filename from the member string, if present.
537 * Calls RTPathStripFilename() without having to mess with mutableRaw().
538 */
539 Utf8Str& stripFilename();
540
541 /**
542 * Removes the path component from the member string, if present.
543 * Calls RTPathFilename() without having to mess with mutableRaw().
544 */
545 Utf8Str& stripPath();
546
547 /**
548 * Removes a trailing file name extension from the member string, if present.
549 * Calls RTPathStripExt() without having to mess with mutableRaw().
550 */
551 Utf8Str& stripExt();
552
553 /**
554 * Static immutable empty-string object. May be used for comparison purposes.
555 */
556 static const Utf8Str Empty;
557
558protected:
559
560 void copyFrom(CBSTR s);
561
562 friend class Bstr; /* to access our raw_copy() */
563};
564
565/**
566 * Class with iprt::MiniString::printf as constructor for your convenience.
567 *
568 * Constructing a Utf8Str string object from a format string and a variable
569 * number of arguments can easily be confused with the other Utf8Str
570 * constructures, thus this child class.
571 *
572 * The usage of this class is like the following:
573 * @code
574 Utf8StrFmt strName("program name = %s", argv[0]);
575 @endcode
576 */
577class Utf8StrFmt : public Utf8Str
578{
579public:
580
581 /**
582 * Constructs a new string given the format string and the list of the
583 * arguments for the format string.
584 *
585 * @param a_pszFormat Pointer to the format string (UTF-8),
586 * @see pg_rt_str_format.
587 * @param ... Ellipsis containing the arguments specified by
588 * the format string.
589 */
590 explicit Utf8StrFmt(const char *a_pszFormat, ...)
591 {
592 va_list va;
593 va_start(va, a_pszFormat);
594 printfV(a_pszFormat, va);
595 va_end(va);
596 }
597
598 RTMEMEF_NEW_AND_DELETE_OPERATORS();
599
600protected:
601 Utf8StrFmt()
602 { }
603
604private:
605};
606
607/**
608 * The BstrFmt class is a shortcut to <tt>Bstr(Utf8StrFmt(...))</tt>.
609 */
610class BstrFmt : public Bstr
611{
612public:
613
614 /**
615 * Constructs a new string given the format string and the list of the
616 * arguments for the format string.
617 *
618 * @param aFormat printf-like format string (in UTF-8 encoding).
619 * @param ... List of the arguments for the format string.
620 */
621 explicit BstrFmt(const char *aFormat, ...)
622 {
623 va_list args;
624 va_start(args, aFormat);
625 copyFrom(Utf8Str(aFormat, args).c_str());
626 va_end(args);
627 }
628
629 RTMEMEF_NEW_AND_DELETE_OPERATORS();
630};
631
632/**
633 * The BstrFmtVA class is a shortcut to <tt>Bstr(Utf8Str(format,va))</tt>.
634 */
635class BstrFmtVA : public Bstr
636{
637public:
638
639 /**
640 * Constructs a new string given the format string and the list of the
641 * arguments for the format string.
642 *
643 * @param aFormat printf-like format string (in UTF-8 encoding).
644 * @param aArgs List of arguments for the format string
645 */
646 BstrFmtVA(const char *aFormat, va_list aArgs)
647 {
648 copyFrom(Utf8Str(aFormat, aArgs).c_str());
649 }
650
651 RTMEMEF_NEW_AND_DELETE_OPERATORS();
652};
653
654} /* namespace com */
655
656#endif /* !___VBox_com_string_h */
657
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