VirtualBox

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

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

*: scm --fix-header-guard-endif

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