VirtualBox

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

Last change on this file since 76408 was 76408, checked in by vboxsync, 6 years ago

iprt/string.h: Dropped including utf16.h and let those who need it include it themselves. bugref:9344

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