VirtualBox

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

Last change on this file since 34801 was 34785, checked in by vboxsync, 14 years ago

iprt/cpp/ministring.h,VBox/com/string.h: Use RTMEMEF_NEW_AND_DELETE_OPERATORS.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.0 KB
Line 
1/* $Id: string.h 34785 2010-12-07 14:48:46Z 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()
128 {
129 setNull();
130 }
131
132 Bstr& operator=(const Bstr &that)
133 {
134 cleanup();
135 copyFrom((const OLECHAR *)that.m_bstr);
136 return *this;
137 }
138
139 Bstr& operator=(CBSTR that)
140 {
141 cleanup();
142 copyFrom((const OLECHAR *)that);
143 return *this;
144 }
145
146#if defined(VBOX_WITH_XPCOM)
147 Bstr& operator=(const wchar_t *that)
148 {
149 cleanup();
150 copyFrom((const OLECHAR *)that);
151 return *this;
152 }
153#endif
154
155 Bstr& setNull()
156 {
157 cleanup();
158 return *this;
159 }
160
161 RTMEMEF_NEW_AND_DELETE_OPERATORS();
162
163 /** Case sensitivity selector. */
164 enum CaseSensitivity
165 {
166 CaseSensitive,
167 CaseInsensitive
168 };
169
170 /**
171 * Compares the member string to str.
172 * @param str
173 * @param cs Whether comparison should be case-sensitive.
174 * @return
175 */
176 int compare(CBSTR str, CaseSensitivity cs = CaseSensitive) const
177 {
178 if (cs == CaseSensitive)
179 return ::RTUtf16Cmp((PRTUTF16)m_bstr, (PRTUTF16)str);
180 return ::RTUtf16LocaleICmp((PRTUTF16)m_bstr, (PRTUTF16)str);
181 }
182
183 int compare(BSTR str, CaseSensitivity cs = CaseSensitive) const
184 {
185 return compare((CBSTR)str, cs);
186 }
187
188 int compare(const Bstr &that, CaseSensitivity cs = CaseSensitive) const
189 {
190 return compare(that.m_bstr, cs);
191 }
192
193 bool operator==(const Bstr &that) const { return !compare(that.m_bstr); }
194 bool operator!=(const Bstr &that) const { return !!compare(that.m_bstr); }
195 bool operator==(CBSTR that) const { return !compare(that); }
196 bool operator==(BSTR that) const { return !compare(that); }
197
198 bool operator!=(CBSTR that) const { return !!compare(that); }
199 bool operator!=(BSTR that) const { return !!compare(that); }
200 bool operator<(const Bstr &that) const { return compare(that.m_bstr) < 0; }
201 bool operator<(CBSTR that) const { return compare(that) < 0; }
202 bool operator<(BSTR that) const { return compare(that) < 0; }
203
204 /**
205 * Returns true if the member string has no length.
206 * This is true for instances created from both NULL and "" input strings.
207 *
208 * @note Always use this method to check if an instance is empty. Do not
209 * use length() because that may need to run through the entire string
210 * (Bstr does not cache string lengths).
211 */
212 bool isEmpty() const { return m_bstr == NULL || *m_bstr == 0; }
213
214 /**
215 * Returns true if the member string has a length of one or more.
216 *
217 * @returns true if not empty, false if empty (NULL or "").
218 */
219 bool isNotEmpty() const { return m_bstr != NULL && *m_bstr != 0; }
220
221 size_t length() const { return isEmpty() ? 0 : ::RTUtf16Len((PRTUTF16)m_bstr); }
222
223#if defined(VBOX_WITH_XPCOM)
224 /**
225 * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
226 * returns a pointer to a global variable containing an empty BSTR with a proper zero
227 * length prefix so that Windows is happy.
228 */
229 CBSTR raw() const
230 {
231 if (m_bstr)
232 return m_bstr;
233
234 return g_bstrEmpty;
235 }
236#else
237 /**
238 * Windows-only hack, as the automatically generated headers use BSTR.
239 * So if we don't want to cast like crazy we have to be more loose than
240 * on XPCOM.
241 *
242 * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
243 * returns a pointer to a global variable containing an empty BSTR with a proper zero
244 * length prefix so that Windows is happy.
245 */
246 BSTR raw() const
247 {
248 if (m_bstr)
249 return m_bstr;
250
251 return g_bstrEmpty;
252 }
253#endif
254
255 /**
256 * Returns a non-const raw pointer that allows to modify the string directly.
257 * As opposed to raw(), this DOES return NULL if the member string is empty
258 * because we cannot return a mutable pointer to the global variable with the
259 * empty string.
260 *
261 * @warning
262 * Be sure not to modify data beyond the allocated memory! The
263 * guaranteed size of the allocated memory is at least #length()
264 * bytes after creation and after every assignment operation.
265 */
266 BSTR mutableRaw() { return m_bstr; }
267
268 /**
269 * Intended to assign copies of instances to |BSTR| out parameters from
270 * within the interface method. Transfers the ownership of the duplicated
271 * string to the caller.
272 *
273 * If the member string is empty, this allocates an empty BSTR in *pstr
274 * (i.e. makes it point to a new buffer with a null byte).
275 */
276 void cloneTo(BSTR *pstr) const
277 {
278 if (pstr)
279 {
280 *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty
281#ifdef RT_EXCEPTIONS_ENABLED
282 if (!*pstr)
283 throw std::bad_alloc();
284#endif
285 }
286 }
287
288 /**
289 * Intended to assign instances to |BSTR| out parameters from within the
290 * interface method. Transfers the ownership of the original string to the
291 * caller and resets the instance to null.
292 *
293 * As opposed to cloneTo(), this method doesn't create a copy of the
294 * string.
295 *
296 * If the member string is empty, this allocates an empty BSTR in *pstr
297 * (i.e. makes it point to a new buffer with a null byte).
298 */
299 void detachTo(BSTR *pstr)
300 {
301 if (m_bstr)
302 *pstr = m_bstr;
303 else
304 {
305 // allocate null BSTR
306 *pstr = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
307#ifdef RT_EXCEPTIONS_ENABLED
308 if (!*pstr)
309 throw std::bad_alloc();
310#endif
311 }
312 m_bstr = NULL;
313 }
314
315 /**
316 * Intended to pass instances as |BSTR| out parameters to methods.
317 * Takes the ownership of the returned data.
318 */
319 BSTR* asOutParam()
320 {
321 cleanup();
322 return &m_bstr;
323 }
324
325 /**
326 * Static immutable empty-string object. May be used for comparison purposes.
327 */
328 static const Bstr Empty;
329
330protected:
331
332 void cleanup()
333 {
334 if (m_bstr)
335 {
336 ::SysFreeString(m_bstr);
337 m_bstr = NULL;
338 }
339 }
340
341 /**
342 * Protected internal helper to copy a string. This ignores the previous object
343 * state, so either call this from a constructor or call cleanup() first.
344 *
345 * This variant copies from a zero-terminated UTF-16 string (which need not
346 * be a BSTR, i.e. need not have a length prefix).
347 *
348 * If the source is empty, this sets the member string to NULL.
349 * @param rs
350 */
351 void copyFrom(const OLECHAR *rs)
352 {
353 if (rs && *rs)
354 {
355 m_bstr = ::SysAllocString(rs);
356#ifdef RT_EXCEPTIONS_ENABLED
357 if (!m_bstr)
358 throw std::bad_alloc();
359#endif
360 }
361 else
362 m_bstr = NULL;
363 }
364
365 /**
366 * Protected internal helper to copy a string. This ignores the previous object
367 * state, so either call this from a constructor or call cleanup() first.
368 *
369 * This variant copies and converts from a zero-terminated UTF-8 string.
370 *
371 * If the source is empty, this sets the member string to NULL.
372 * @param rs
373 */
374 void copyFrom(const char *rs)
375 {
376 if (rs && *rs)
377 {
378 PRTUTF16 s = NULL;
379 ::RTStrToUtf16(rs, &s);
380#ifdef RT_EXCEPTIONS_ENABLED
381 if (!s)
382 throw std::bad_alloc();
383#endif
384 copyFrom((const OLECHAR *)s); // allocates BSTR from zero-terminated input string
385 ::RTUtf16Free(s);
386 }
387 else
388 m_bstr = NULL;
389 }
390
391 BSTR m_bstr;
392
393 friend class Utf8Str; /* to access our raw_copy() */
394};
395
396/* symmetric compare operators */
397inline bool operator==(CBSTR l, const Bstr &r) { return r.operator==(l); }
398inline bool operator!=(CBSTR l, const Bstr &r) { return r.operator!=(l); }
399inline bool operator==(BSTR l, const Bstr &r) { return r.operator==(l); }
400inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!=(l); }
401
402
403////////////////////////////////////////////////////////////////////////////////
404
405/**
406 * String class used universally in Main for UTF-8 strings.
407 *
408 * This is based on iprt::MiniString, to which some functionality has been
409 * moved. Here we keep things that are specific to Main, such as conversions
410 * with UTF-16 strings (Bstr).
411 *
412 * Like iprt::MiniString, Utf8Str does not differentiate between NULL strings
413 * and empty strings. In other words, Utf8Str("") and Utf8Str(NULL)
414 * behave the same. In both cases, MiniString allocates no memory, reports
415 * a zero length and zero allocated bytes for both, and returns an empty
416 * C string from c_str().
417 */
418class Utf8Str : public iprt::MiniString
419{
420public:
421
422 Utf8Str() {}
423
424 Utf8Str(const MiniString &that)
425 : MiniString(that)
426 {}
427
428 Utf8Str(const char *that)
429 : MiniString(that)
430 {}
431
432 Utf8Str(const Bstr &that)
433 {
434 copyFrom(that.raw());
435 }
436
437 Utf8Str(CBSTR that)
438 {
439 copyFrom(that);
440 }
441
442 /**
443 * Constructs a new string given the format string and the list of the
444 * arguments for the format string.
445 *
446 * @param a_pszFormat Pointer to the format string (UTF-8),
447 * @see pg_rt_str_format.
448 * @param a_va Argument vector containing the arguments
449 * specified by the format string.
450 * @sa iprt::MiniString::printfV
451 */
452 Utf8Str(const char *a_pszFormat, va_list a_va)
453 : MiniString(a_pszFormat, a_va)
454 {
455 }
456
457 Utf8Str& operator=(const MiniString &that)
458 {
459 MiniString::operator=(that);
460 return *this;
461 }
462
463 Utf8Str& operator=(const char *that)
464 {
465 MiniString::operator=(that);
466 return *this;
467 }
468
469 Utf8Str& operator=(const Bstr &that)
470 {
471 cleanup();
472 copyFrom(that.raw());
473 return *this;
474 }
475
476 Utf8Str& operator=(CBSTR that)
477 {
478 cleanup();
479 copyFrom(that);
480 return *this;
481 }
482
483 RTMEMEF_NEW_AND_DELETE_OPERATORS();
484
485#if defined(VBOX_WITH_XPCOM)
486 /**
487 * Intended to assign instances to |char *| out parameters from within the
488 * interface method. Transfers the ownership of the duplicated string to the
489 * caller.
490 *
491 * This allocates a single 0 byte in the target if the member string is empty.
492 *
493 * This uses XPCOM memory allocation and thus only works on XPCOM. MSCOM doesn't
494 * like char* strings anyway.
495 */
496 void cloneTo(char **pstr) const;
497#endif
498
499 /**
500 * Intended to assign instances to |BSTR| out parameters from within the
501 * interface method. Transfers the ownership of the duplicated string to the
502 * caller.
503 */
504 void cloneTo(BSTR *pstr) const
505 {
506 if (pstr)
507 {
508 Bstr bstr(*this);
509 bstr.cloneTo(pstr);
510 }
511 }
512
513 /**
514 * Removes a trailing slash from the member string, if present.
515 * Calls RTPathStripTrailingSlash() without having to mess with mutableRaw().
516 */
517 Utf8Str& stripTrailingSlash();
518
519 /**
520 * Removes a trailing filename from the member string, if present.
521 * Calls RTPathStripFilename() without having to mess with mutableRaw().
522 */
523 Utf8Str& stripFilename();
524
525 /**
526 * Removes the path component from the member string, if present.
527 * Calls RTPathFilename() without having to mess with mutableRaw().
528 */
529 Utf8Str& stripPath();
530
531 /**
532 * Removes a trailing file name extension from the member string, if present.
533 * Calls RTPathStripExt() without having to mess with mutableRaw().
534 */
535 Utf8Str& stripExt();
536
537 /**
538 * Static immutable empty-string object. May be used for comparison purposes.
539 */
540 static const Utf8Str Empty;
541
542protected:
543
544 void copyFrom(CBSTR s);
545
546 friend class Bstr; /* to access our raw_copy() */
547};
548
549/**
550 * Class with iprt::MiniString::printf as constructor for your convenience.
551 *
552 * Constructing a Utf8Str string object from a format string and a variable
553 * number of arguments can easily be confused with the other Utf8Str
554 * constructures, thus this child class.
555 *
556 * The usage of this class is like the following:
557 * @code
558 Utf8StrFmt strName("program name = %s", argv[0]);
559 @endcode
560 */
561class Utf8StrFmt : public Utf8Str
562{
563public:
564
565 /**
566 * Constructs a new string given the format string and the list of the
567 * arguments for the format string.
568 *
569 * @param a_pszFormat Pointer to the format string (UTF-8),
570 * @see pg_rt_str_format.
571 * @param ... Ellipsis containing the arguments specified by
572 * the format string.
573 */
574 explicit Utf8StrFmt(const char *a_pszFormat, ...)
575 {
576 va_list va;
577 va_start(va, a_pszFormat);
578 printfV(a_pszFormat, va);
579 va_end(va);
580 }
581
582 RTMEMEF_NEW_AND_DELETE_OPERATORS();
583
584protected:
585 Utf8StrFmt()
586 { }
587
588private:
589};
590
591/**
592 * The BstrFmt class is a shortcut to <tt>Bstr(Utf8StrFmt(...))</tt>.
593 */
594class BstrFmt : public Bstr
595{
596public:
597
598 /**
599 * Constructs a new string given the format string and the list of the
600 * arguments for the format string.
601 *
602 * @param aFormat printf-like format string (in UTF-8 encoding).
603 * @param ... List of the arguments for the format string.
604 */
605 explicit BstrFmt(const char *aFormat, ...)
606 {
607 va_list args;
608 va_start(args, aFormat);
609 copyFrom(Utf8Str(aFormat, args).c_str());
610 va_end(args);
611 }
612
613 RTMEMEF_NEW_AND_DELETE_OPERATORS();
614};
615
616/**
617 * The BstrFmtVA class is a shortcut to <tt>Bstr(Utf8Str(format,va))</tt>.
618 */
619class BstrFmtVA : public Bstr
620{
621public:
622
623 /**
624 * Constructs a new string given the format string and the list of the
625 * arguments for the format string.
626 *
627 * @param aFormat printf-like format string (in UTF-8 encoding).
628 * @param aArgs List of arguments for the format string
629 */
630 BstrFmtVA(const char *aFormat, va_list aArgs)
631 {
632 copyFrom(Utf8Str(aFormat, aArgs).c_str());
633 }
634
635 RTMEMEF_NEW_AND_DELETE_OPERATORS();
636};
637
638} /* namespace com */
639
640#endif /* !___VBox_com_string_h */
641
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