VirtualBox

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

Last change on this file since 62361 was 60409, checked in by vboxsync, 9 years ago

com::Bstr: Added compareUtf8() for optimal comparsions with UTF-8 strings. Also added a few equals() and equalsIgnoreCase() method for convenience.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.3 KB
Line 
1/* $Id: string.h 60409 2016-04-10 15:40:07Z vboxsync $ */
2/** @file
3 * MS COM / XPCOM Abstraction Layer - Smart string classes declaration.
4 */
5
6/*
7 * Copyright (C) 2006-2015 Oracle Corporation
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 (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27#ifndef ___VBox_com_string_h
28#define ___VBox_com_string_h
29
30/* Make sure all the stdint.h macros are included - must come first! */
31#ifndef __STDC_LIMIT_MACROS
32# define __STDC_LIMIT_MACROS
33#endif
34#ifndef __STDC_CONSTANT_MACROS
35# define __STDC_CONSTANT_MACROS
36#endif
37
38#if defined(VBOX_WITH_XPCOM)
39# include <nsMemory.h>
40#endif
41
42#include "VBox/com/defs.h"
43#include "VBox/com/assert.h"
44
45#include <iprt/mem.h>
46#include <iprt/cpp/ministring.h>
47
48
49/** @defgroup grp_com_str Smart String Classes
50 * @ingroup grp_com
51 * @{
52 */
53
54namespace com
55{
56
57class Utf8Str;
58
59// global constant in glue/string.cpp that represents an empty BSTR
60extern const BSTR g_bstrEmpty;
61
62/**
63 * String class used universally in Main for COM-style Utf-16 strings.
64 *
65 * Unfortunately COM on Windows uses UTF-16 everywhere, requiring conversions
66 * back and forth since most of VirtualBox and our libraries use UTF-8.
67 *
68 * To make things more obscure, on Windows, a COM-style BSTR is not just a
69 * pointer to a null-terminated wide character array, but the four bytes (32
70 * bits) BEFORE the memory that the pointer points to are a length DWORD. One
71 * must therefore avoid pointer arithmetic and always use SysAllocString and
72 * the like to deal with BSTR pointers, which manage that DWORD correctly.
73 *
74 * For platforms other than Windows, we provide our own versions of the Sys*
75 * functions in Main/xpcom/helpers.cpp which do NOT use length prefixes though
76 * to be compatible with how XPCOM allocates string parameters to public
77 * functions.
78 *
79 * The Bstr class hides all this handling behind a std::string-like interface
80 * and also provides automatic conversions to RTCString and Utf8Str instances.
81 *
82 * The one advantage of using the SysString* routines is that this makes it
83 * possible to use it as a type of member variables of COM/XPCOM components and
84 * pass their values to callers through component methods' output parameters
85 * using the #cloneTo() operation. Also, the class can adopt (take ownership
86 * of) string buffers returned in output parameters of COM methods using the
87 * #asOutParam() operation and correctly free them afterwards.
88 *
89 * Starting with VirtualBox 3.2, like Utf8Str, Bstr no longer differentiates
90 * between NULL strings and empty strings. In other words, Bstr("") and
91 * Bstr(NULL) behave the same. In both cases, Bstr allocates no memory,
92 * reports a zero length and zero allocated bytes for both, and returns an
93 * empty C wide string from raw().
94 *
95 * @note All Bstr methods ASSUMES valid UTF-16 or UTF-8 input strings.
96 * The VirtualBox policy in this regard is to validate strings coming
97 * from external sources before passing them to Bstr or Utf8Str.
98 */
99class Bstr
100{
101public:
102
103 Bstr()
104 : m_bstr(NULL)
105 { }
106
107 Bstr(const Bstr &that)
108 {
109 copyFrom((const OLECHAR *)that.m_bstr);
110 }
111
112 Bstr(CBSTR that)
113 {
114 copyFrom((const OLECHAR *)that);
115 }
116
117#if defined(VBOX_WITH_XPCOM)
118 Bstr(const wchar_t *that)
119 {
120 AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
121 copyFrom((const OLECHAR *)that);
122 }
123#endif
124
125 Bstr(const RTCString &that)
126 {
127 copyFrom(that.c_str());
128 }
129
130 Bstr(const char *that)
131 {
132 copyFrom(that);
133 }
134
135 Bstr(const char *a_pThat, size_t a_cchMax)
136 {
137 copyFromN(a_pThat, a_cchMax);
138 }
139
140 ~Bstr()
141 {
142 setNull();
143 }
144
145 Bstr& operator=(const Bstr &that)
146 {
147 cleanup();
148 copyFrom((const OLECHAR *)that.m_bstr);
149 return *this;
150 }
151
152 Bstr& operator=(CBSTR that)
153 {
154 cleanup();
155 copyFrom((const OLECHAR *)that);
156 return *this;
157 }
158
159#if defined(VBOX_WITH_XPCOM)
160 Bstr& operator=(const wchar_t *that)
161 {
162 cleanup();
163 copyFrom((const OLECHAR *)that);
164 return *this;
165 }
166#endif
167
168 Bstr& setNull()
169 {
170 cleanup();
171 return *this;
172 }
173
174#ifdef _MSC_VER
175# if _MSC_VER >= 1400
176 RTMEMEF_NEW_AND_DELETE_OPERATORS();
177# endif
178#else
179 RTMEMEF_NEW_AND_DELETE_OPERATORS();
180#endif
181
182 /** Case sensitivity selector. */
183 enum CaseSensitivity
184 {
185 CaseSensitive,
186 CaseInsensitive
187 };
188
189 /**
190 * Compares the member string to str.
191 * @param str
192 * @param cs Whether comparison should be case-sensitive.
193 * @return
194 */
195 int compare(CBSTR str, CaseSensitivity cs = CaseSensitive) const
196 {
197 if (cs == CaseSensitive)
198 return ::RTUtf16Cmp((PRTUTF16)m_bstr, (PRTUTF16)str);
199 return ::RTUtf16LocaleICmp((PRTUTF16)m_bstr, (PRTUTF16)str);
200 }
201
202 int compare(BSTR str, CaseSensitivity cs = CaseSensitive) const
203 {
204 return compare((CBSTR)str, cs);
205 }
206
207 int compare(const Bstr &that, CaseSensitivity cs = CaseSensitive) const
208 {
209 return compare(that.m_bstr, cs);
210 }
211
212 bool operator==(const Bstr &that) const { return !compare(that.m_bstr); }
213 bool operator==(CBSTR that) const { return !compare(that); }
214 bool operator==(BSTR that) const { return !compare(that); }
215 bool operator!=(const Bstr &that) const { return !!compare(that.m_bstr); }
216 bool operator!=(CBSTR that) const { return !!compare(that); }
217 bool operator!=(BSTR that) const { return !!compare(that); }
218 bool operator<(const Bstr &that) const { return compare(that.m_bstr) < 0; }
219 bool operator<(CBSTR that) const { return compare(that) < 0; }
220 bool operator<(BSTR that) const { return compare(that) < 0; }
221 bool operator<=(const Bstr &that) const { return compare(that.m_bstr) <= 0; }
222 bool operator<=(CBSTR that) const { return compare(that) <= 0; }
223 bool operator<=(BSTR that) const { return compare(that) <= 0; }
224 bool operator>(const Bstr &that) const { return compare(that.m_bstr) > 0; }
225 bool operator>(CBSTR that) const { return compare(that) > 0; }
226 bool operator>(BSTR that) const { return compare(that) > 0; }
227 bool operator>=(const Bstr &that) const { return compare(that.m_bstr) >= 0; }
228 bool operator>=(CBSTR that) const { return compare(that) >= 0; }
229 bool operator>=(BSTR that) const { return compare(that) >= 0; }
230
231 /**
232 * Compares this string to an UTF-8 C style string.
233 *
234 * @retval 0 if equal
235 * @retval -1 if this string is smaller than the UTF-8 one.
236 * @retval 1 if the UTF-8 string is smaller than this.
237 *
238 * @param a_pszRight The string to compare with.
239 * @param a_enmCase Whether comparison should be case-sensitive.
240 */
241 int compareUtf8(const char *a_pszRight, CaseSensitivity a_enmCase = CaseSensitive) const;
242
243 /** Java style compare method.
244 * @returns true if @a a_pszRight equals this string.
245 * @param a_pszRight The (UTF-8) string to compare with. */
246 bool equals(const char *a_pszRight) const { return compareUtf8(a_pszRight, CaseSensitive) == 0; }
247
248 /** Java style case-insensitive compare method.
249 * @returns true if @a a_pszRight equals this string.
250 * @param a_pszRight The (UTF-8) string to compare with. */
251 bool equalsIgnoreCase(const char *a_pszRight) const { return compareUtf8(a_pszRight, CaseInsensitive) == 0; }
252
253 /** Java style compare method.
254 * @returns true if @a a_rThat equals this string.
255 * @param a_rThat The other Bstr instance to compare with. */
256 bool equals(const Bstr &a_rThat) const { return compare(a_rThat.m_bstr, CaseSensitive) == 0; }
257 /** Java style case-insensitive compare method.
258 * @returns true if @a a_rThat equals this string.
259 * @param a_rThat The other Bstr instance to compare with. */
260 bool equalsIgnoreCase(const Bstr &a_rThat) const { return compare(a_rThat.m_bstr, CaseInsensitive) == 0; }
261
262 /** Java style compare method.
263 * @returns true if @a a_pThat equals this string.
264 * @param a_pThat The native const BSTR to compare with. */
265 bool equals(CBSTR a_pThat) const { return compare(a_pThat, CaseSensitive) == 0; }
266 /** Java style case-insensitive compare method.
267 * @returns true if @a a_pThat equals this string.
268 * @param a_pThat The native const BSTR to compare with. */
269 bool equalsIgnoreCase(CBSTR a_pThat) const { return compare(a_pThat, CaseInsensitive) == 0; }
270
271 /** Java style compare method.
272 * @returns true if @a a_pThat equals this string.
273 * @param a_pThat The native BSTR to compare with. */
274 bool equals(BSTR a_pThat) const { return compare(a_pThat, CaseSensitive) == 0; }
275 /** Java style case-insensitive compare method.
276 * @returns true if @a a_pThat equals this string.
277 * @param a_pThat The native BSTR to compare with. */
278 bool equalsIgnoreCase(BSTR a_pThat) const { return compare(a_pThat, CaseInsensitive) == 0; }
279
280 /**
281 * Returns true if the member string has no length.
282 * This is true for instances created from both NULL and "" input strings.
283 *
284 * @note Always use this method to check if an instance is empty. Do not
285 * use length() because that may need to run through the entire string
286 * (Bstr does not cache string lengths).
287 */
288 bool isEmpty() const { return m_bstr == NULL || *m_bstr == 0; }
289
290 /**
291 * Returns true if the member string has a length of one or more.
292 *
293 * @returns true if not empty, false if empty (NULL or "").
294 */
295 bool isNotEmpty() const { return m_bstr != NULL && *m_bstr != 0; }
296
297 size_t length() const { return isEmpty() ? 0 : ::RTUtf16Len((PRTUTF16)m_bstr); }
298
299#if defined(VBOX_WITH_XPCOM)
300 /**
301 * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
302 * returns a pointer to a global variable containing an empty BSTR with a proper zero
303 * length prefix so that Windows is happy.
304 */
305 CBSTR raw() const
306 {
307 if (m_bstr)
308 return m_bstr;
309
310 return g_bstrEmpty;
311 }
312#else
313 /**
314 * Windows-only hack, as the automatically generated headers use BSTR.
315 * So if we don't want to cast like crazy we have to be more loose than
316 * on XPCOM.
317 *
318 * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
319 * returns a pointer to a global variable containing an empty BSTR with a proper zero
320 * length prefix so that Windows is happy.
321 */
322 BSTR raw() const
323 {
324 if (m_bstr)
325 return m_bstr;
326
327 return g_bstrEmpty;
328 }
329#endif
330
331 /**
332 * Returns a non-const raw pointer that allows to modify the string directly.
333 * As opposed to raw(), this DOES return NULL if the member string is empty
334 * because we cannot return a mutable pointer to the global variable with the
335 * empty string.
336 *
337 * @warning
338 * Be sure not to modify data beyond the allocated memory! The
339 * guaranteed size of the allocated memory is at least #length()
340 * bytes after creation and after every assignment operation.
341 */
342 BSTR mutableRaw() { return m_bstr; }
343
344 /**
345 * Intended to assign copies of instances to |BSTR| out parameters from
346 * within the interface method. Transfers the ownership of the duplicated
347 * string to the caller.
348 *
349 * If the member string is empty, this allocates an empty BSTR in *pstr
350 * (i.e. makes it point to a new buffer with a null byte).
351 *
352 * @deprecated Use cloneToEx instead to avoid throwing exceptions.
353 */
354 void cloneTo(BSTR *pstr) const
355 {
356 if (pstr)
357 {
358 *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty
359#ifdef RT_EXCEPTIONS_ENABLED
360 if (!*pstr)
361 throw std::bad_alloc();
362#endif
363 }
364 }
365
366 /**
367 * A version of cloneTo that does not throw any out of memory exceptions, but
368 * returns E_OUTOFMEMORY intead.
369 * @returns S_OK or E_OUTOFMEMORY.
370 */
371 HRESULT cloneToEx(BSTR *pstr) const
372 {
373 if (!pstr)
374 return S_OK;
375 *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty
376 return pstr ? S_OK : E_OUTOFMEMORY;
377 }
378
379 /**
380 * Intended to assign instances to |BSTR| out parameters from within the
381 * interface method. Transfers the ownership of the original string to the
382 * caller and resets the instance to null.
383 *
384 * As opposed to cloneTo(), this method doesn't create a copy of the
385 * string.
386 *
387 * If the member string is empty, this allocates an empty BSTR in *pstr
388 * (i.e. makes it point to a new buffer with a null byte).
389 *
390 * @param pbstrDst The BSTR variable to detach the string to.
391 *
392 * @throws std::bad_alloc if we failed to allocate a new empty string.
393 */
394 void detachTo(BSTR *pbstrDst)
395 {
396 if (m_bstr)
397 {
398 *pbstrDst = m_bstr;
399 m_bstr = NULL;
400 }
401 else
402 {
403 // allocate null BSTR
404 *pbstrDst = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
405#ifdef RT_EXCEPTIONS_ENABLED
406 if (!*pbstrDst)
407 throw std::bad_alloc();
408#endif
409 }
410 }
411
412 /**
413 * A version of detachTo that does not throw exceptions on out-of-memory
414 * conditions, but instead returns E_OUTOFMEMORY.
415 *
416 * @param pbstrDst The BSTR variable to detach the string to.
417 * @returns S_OK or E_OUTOFMEMORY.
418 */
419 HRESULT detachToEx(BSTR *pbstrDst)
420 {
421 if (m_bstr)
422 {
423 *pbstrDst = m_bstr;
424 m_bstr = NULL;
425 }
426 else
427 {
428 // allocate null BSTR
429 *pbstrDst = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
430 if (!*pbstrDst)
431 return E_OUTOFMEMORY;
432 }
433 return S_OK;
434 }
435
436 /**
437 * Intended to pass instances as |BSTR| out parameters to methods.
438 * Takes the ownership of the returned data.
439 */
440 BSTR *asOutParam()
441 {
442 cleanup();
443 return &m_bstr;
444 }
445
446 /**
447 * Static immutable empty-string object. May be used for comparison purposes.
448 */
449 static const Bstr Empty;
450
451protected:
452
453 void cleanup()
454 {
455 if (m_bstr)
456 {
457 ::SysFreeString(m_bstr);
458 m_bstr = NULL;
459 }
460 }
461
462 /**
463 * Protected internal helper to copy a string. This ignores the previous object
464 * state, so either call this from a constructor or call cleanup() first.
465 *
466 * This variant copies from a zero-terminated UTF-16 string (which need not
467 * be a BSTR, i.e. need not have a length prefix).
468 *
469 * If the source is empty, this sets the member string to NULL.
470 *
471 * @param a_bstrSrc The source string. The caller guarantees
472 * that this is valid UTF-16.
473 *
474 * @throws std::bad_alloc - the object is representing an empty string.
475 */
476 void copyFrom(const OLECHAR *a_bstrSrc)
477 {
478 if (a_bstrSrc && *a_bstrSrc)
479 {
480 m_bstr = ::SysAllocString(a_bstrSrc);
481#ifdef RT_EXCEPTIONS_ENABLED
482 if (!m_bstr)
483 throw std::bad_alloc();
484#endif
485 }
486 else
487 m_bstr = NULL;
488 }
489
490 /**
491 * Protected internal helper to copy a string. This ignores the previous object
492 * state, so either call this from a constructor or call cleanup() first.
493 *
494 * This variant copies and converts from a zero-terminated UTF-8 string.
495 *
496 * If the source is empty, this sets the member string to NULL.
497 *
498 * @param a_pszSrc The source string. The caller guarantees
499 * that this is valid UTF-8.
500 *
501 * @throws std::bad_alloc - the object is representing an empty string.
502 */
503 void copyFrom(const char *a_pszSrc)
504 {
505 copyFromN(a_pszSrc, RTSTR_MAX);
506 }
507
508 /**
509 * Variant of copyFrom for sub-string constructors.
510 *
511 * @param a_pszSrc The source string. The caller guarantees
512 * that this is valid UTF-8.
513 * @param a_cchSrc The maximum number of chars (not codepoints) to
514 * copy. If you pass RTSTR_MAX it'll be exactly
515 * like copyFrom().
516 *
517 * @throws std::bad_alloc - the object is representing an empty string.
518 */
519 void copyFromN(const char *a_pszSrc, size_t a_cchSrc);
520
521 BSTR m_bstr;
522
523 friend class Utf8Str; /* to access our raw_copy() */
524};
525
526/* symmetric compare operators */
527inline bool operator==(CBSTR l, const Bstr &r) { return r.operator==(l); }
528inline bool operator!=(CBSTR l, const Bstr &r) { return r.operator!=(l); }
529inline bool operator==(BSTR l, const Bstr &r) { return r.operator==(l); }
530inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!=(l); }
531
532
533
534
535/**
536 * String class used universally in Main for UTF-8 strings.
537 *
538 * This is based on RTCString, to which some functionality has been
539 * moved. Here we keep things that are specific to Main, such as conversions
540 * with UTF-16 strings (Bstr).
541 *
542 * Like RTCString, Utf8Str does not differentiate between NULL strings
543 * and empty strings. In other words, Utf8Str("") and Utf8Str(NULL) behave the
544 * same. In both cases, RTCString allocates no memory, reports
545 * a zero length and zero allocated bytes for both, and returns an empty
546 * C string from c_str().
547 *
548 * @note All Utf8Str methods ASSUMES valid UTF-8 or UTF-16 input strings.
549 * The VirtualBox policy in this regard is to validate strings coming
550 * from external sources before passing them to Utf8Str or Bstr.
551 */
552class Utf8Str : public RTCString
553{
554public:
555
556 Utf8Str() {}
557
558 Utf8Str(const RTCString &that)
559 : RTCString(that)
560 {}
561
562 Utf8Str(const char *that)
563 : RTCString(that)
564 {}
565
566 Utf8Str(const Bstr &that)
567 {
568 copyFrom(that.raw());
569 }
570
571 Utf8Str(CBSTR that, size_t a_cwcSize = RTSTR_MAX)
572 {
573 copyFrom(that, a_cwcSize);
574 }
575
576 Utf8Str(const char *a_pszSrc, size_t a_cchSrc)
577 : RTCString(a_pszSrc, a_cchSrc)
578 {
579 }
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 a_va Argument vector containing the arguments
588 * specified by the format string.
589 * @sa RTCString::printfV
590 */
591 Utf8Str(const char *a_pszFormat, va_list a_va) RT_IPRT_FORMAT_ATTR(1, 0)
592 : RTCString(a_pszFormat, a_va)
593 {
594 }
595
596 Utf8Str& operator=(const RTCString &that)
597 {
598 RTCString::operator=(that);
599 return *this;
600 }
601
602 Utf8Str& operator=(const char *that)
603 {
604 RTCString::operator=(that);
605 return *this;
606 }
607
608 Utf8Str& operator=(const Bstr &that)
609 {
610 cleanup();
611 copyFrom(that.raw());
612 return *this;
613 }
614
615 Utf8Str& operator=(CBSTR that)
616 {
617 cleanup();
618 copyFrom(that);
619 return *this;
620 }
621
622 /**
623 * Extended assignment method that returns a COM status code instead of an
624 * exception on failure.
625 *
626 * @returns S_OK or E_OUTOFMEMORY.
627 * @param a_rSrcStr The source string
628 */
629 HRESULT assignEx(Utf8Str const &a_rSrcStr)
630 {
631 return copyFromExNComRC(a_rSrcStr.m_psz, 0, a_rSrcStr.m_cch);
632 }
633
634 /**
635 * Extended assignment method that returns a COM status code instead of an
636 * exception on failure.
637 *
638 * @returns S_OK, E_OUTOFMEMORY or E_INVALIDARG.
639 * @param a_rSrcStr The source string
640 * @param a_offSrc The character (byte) offset of the substring.
641 * @param a_cchSrc The number of characters (bytes) to copy from the source
642 * string.
643 */
644 HRESULT assignEx(Utf8Str const &a_rSrcStr, size_t a_offSrc, size_t a_cchSrc)
645 {
646 if ( a_offSrc + a_cchSrc > a_rSrcStr.m_cch
647 || a_offSrc > a_rSrcStr.m_cch)
648 return E_INVALIDARG;
649 return copyFromExNComRC(a_rSrcStr.m_psz, a_offSrc, a_cchSrc);
650 }
651
652 /**
653 * Extended assignment method that returns a COM status code instead of an
654 * exception on failure.
655 *
656 * @returns S_OK or E_OUTOFMEMORY.
657 * @param a_pcszSrc The source string
658 */
659 HRESULT assignEx(const char *a_pcszSrc)
660 {
661 return copyFromExNComRC(a_pcszSrc, 0, a_pcszSrc ? strlen(a_pcszSrc) : 0);
662 }
663
664 /**
665 * Extended assignment method that returns a COM status code instead of an
666 * exception on failure.
667 *
668 * @returns S_OK or E_OUTOFMEMORY.
669 * @param a_pcszSrc The source string
670 * @param a_cchSrc The number of characters (bytes) to copy from the source
671 * string.
672 */
673 HRESULT assignEx(const char *a_pcszSrc, size_t a_cchSrc)
674 {
675 return copyFromExNComRC(a_pcszSrc, 0, a_cchSrc);
676 }
677
678 RTMEMEF_NEW_AND_DELETE_OPERATORS();
679
680#if defined(VBOX_WITH_XPCOM)
681 /**
682 * Intended to assign instances to |char *| out parameters from within the
683 * interface method. Transfers the ownership of the duplicated string to the
684 * caller.
685 *
686 * This allocates a single 0 byte in the target if the member string is empty.
687 *
688 * This uses XPCOM memory allocation and thus only works on XPCOM. MSCOM doesn't
689 * like char* strings anyway.
690 */
691 void cloneTo(char **pstr) const;
692
693 /**
694 * A version of cloneTo that does not throw allocation errors but returns
695 * E_OUTOFMEMORY instead.
696 * @returns S_OK or E_OUTOFMEMORY (COM status codes).
697 */
698 HRESULT cloneToEx(char **pstr) const;
699#endif
700
701 /**
702 * Intended to assign instances to |BSTR| out parameters from within the
703 * interface method. Transfers the ownership of the duplicated string to the
704 * caller.
705 */
706 void cloneTo(BSTR *pstr) const
707 {
708 if (pstr)
709 {
710 Bstr bstr(*this);
711 bstr.cloneTo(pstr);
712 }
713 }
714
715 /**
716 * A version of cloneTo that does not throw allocation errors but returns
717 * E_OUTOFMEMORY instead.
718 *
719 * @param pbstr Where to store a clone of the string.
720 * @returns S_OK or E_OUTOFMEMORY (COM status codes).
721 */
722 HRESULT cloneToEx(BSTR *pbstr) const
723 {
724 if (!pbstr)
725 return S_OK;
726 Bstr bstr(*this);
727 return bstr.detachToEx(pbstr);
728 }
729
730 /**
731 * Safe assignment from BSTR.
732 *
733 * @param pbstrSrc The source string.
734 * @returns S_OK or E_OUTOFMEMORY (COM status codes).
735 */
736 HRESULT cloneEx(CBSTR pbstrSrc)
737 {
738 cleanup();
739 return copyFromEx(pbstrSrc);
740 }
741
742 /**
743 * Removes a trailing slash from the member string, if present.
744 * Calls RTPathStripTrailingSlash() without having to mess with mutableRaw().
745 */
746 Utf8Str& stripTrailingSlash();
747
748 /**
749 * Removes a trailing filename from the member string, if present.
750 * Calls RTPathStripFilename() without having to mess with mutableRaw().
751 */
752 Utf8Str& stripFilename();
753
754 /**
755 * Removes the path component from the member string, if present.
756 * Calls RTPathFilename() without having to mess with mutableRaw().
757 */
758 Utf8Str& stripPath();
759
760 /**
761 * Removes a trailing file name suffix from the member string, if present.
762 * Calls RTPathStripSuffix() without having to mess with mutableRaw().
763 */
764 Utf8Str& stripSuffix();
765
766 // Parse key=value pairs from string
767 size_t parseKeyValue(Utf8Str &key, Utf8Str &value, size_t pos = 0, const Utf8Str &pairSeparator = ",", const Utf8Str &keyValueSeparator = "=") const;
768
769 /**
770 * Static immutable empty-string object. May be used for comparison purposes.
771 */
772 static const Utf8Str Empty;
773protected:
774
775 void copyFrom(CBSTR a_pbstr, size_t a_cwcMax = RTSTR_MAX);
776 HRESULT copyFromEx(CBSTR a_pbstr);
777 HRESULT copyFromExNComRC(const char *a_pcszSrc, size_t a_offSrc, size_t a_cchSrc);
778
779 friend class Bstr; /* to access our raw_copy() */
780};
781
782/**
783 * Class with RTCString::printf as constructor for your convenience.
784 *
785 * Constructing a Utf8Str string object from a format string and a variable
786 * number of arguments can easily be confused with the other Utf8Str
787 * constructures, thus this child class.
788 *
789 * The usage of this class is like the following:
790 * @code
791 Utf8StrFmt strName("program name = %s", argv[0]);
792 @endcode
793 */
794class Utf8StrFmt : public Utf8Str
795{
796public:
797
798 /**
799 * Constructs a new string given the format string and the list of the
800 * arguments for the format string.
801 *
802 * @param a_pszFormat Pointer to the format string (UTF-8),
803 * @see pg_rt_str_format.
804 * @param ... Ellipsis containing the arguments specified by
805 * the format string.
806 */
807 explicit Utf8StrFmt(const char *a_pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2)
808 {
809 va_list va;
810 va_start(va, a_pszFormat);
811 printfV(a_pszFormat, va);
812 va_end(va);
813 }
814
815 RTMEMEF_NEW_AND_DELETE_OPERATORS();
816
817protected:
818 Utf8StrFmt()
819 { }
820
821private:
822};
823
824/**
825 * The BstrFmt class is a shortcut to <tt>Bstr(Utf8StrFmt(...))</tt>.
826 */
827class BstrFmt : public Bstr
828{
829public:
830
831 /**
832 * Constructs a new string given the format string and the list of the
833 * arguments for the format string.
834 *
835 * @param aFormat printf-like format string (in UTF-8 encoding).
836 * @param ... List of the arguments for the format string.
837 */
838 explicit BstrFmt(const char *aFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2)
839 {
840 va_list args;
841 va_start(args, aFormat);
842 copyFrom(Utf8Str(aFormat, args).c_str());
843 va_end(args);
844 }
845
846 RTMEMEF_NEW_AND_DELETE_OPERATORS();
847};
848
849/**
850 * The BstrFmtVA class is a shortcut to <tt>Bstr(Utf8Str(format,va))</tt>.
851 */
852class BstrFmtVA : public Bstr
853{
854public:
855
856 /**
857 * Constructs a new string given the format string and the list of the
858 * arguments for the format string.
859 *
860 * @param aFormat printf-like format string (in UTF-8 encoding).
861 * @param aArgs List of arguments for the format string
862 */
863 BstrFmtVA(const char *aFormat, va_list aArgs) RT_IPRT_FORMAT_ATTR(1, 0)
864 {
865 copyFrom(Utf8Str(aFormat, aArgs).c_str());
866 }
867
868 RTMEMEF_NEW_AND_DELETE_OPERATORS();
869};
870
871} /* namespace com */
872
873/** @} */
874
875#endif /* !___VBox_com_string_h */
876
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