VirtualBox

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

Last change on this file since 104384 was 98103, checked in by vboxsync, 22 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 50.5 KB
Line 
1/* $Id: string.h 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * MS COM / XPCOM Abstraction Layer - Smart string classes declaration.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37#ifndef VBOX_INCLUDED_com_string_h
38#define VBOX_INCLUDED_com_string_h
39#ifndef RT_WITHOUT_PRAGMA_ONCE
40# pragma once
41#endif
42
43/* Make sure all the stdint.h macros are included - must come first! */
44#ifndef __STDC_LIMIT_MACROS
45# define __STDC_LIMIT_MACROS
46#endif
47#ifndef __STDC_CONSTANT_MACROS
48# define __STDC_CONSTANT_MACROS
49#endif
50
51#if defined(VBOX_WITH_XPCOM)
52# include <nsMemory.h>
53#endif
54
55#include "VBox/com/defs.h"
56#include "VBox/com/assert.h"
57
58#include <iprt/mem.h>
59#include <iprt/utf16.h>
60#include <iprt/cpp/ministring.h>
61
62
63/** @defgroup grp_com_str Smart String Classes
64 * @ingroup grp_com
65 * @{
66 */
67
68namespace com
69{
70
71class Utf8Str;
72
73// global constant in glue/string.cpp that represents an empty BSTR
74extern const BSTR g_bstrEmpty;
75
76/**
77 * String class used universally in Main for COM-style Utf-16 strings.
78 *
79 * Unfortunately COM on Windows uses UTF-16 everywhere, requiring conversions
80 * back and forth since most of VirtualBox and our libraries use UTF-8.
81 *
82 * To make things more obscure, on Windows, a COM-style BSTR is not just a
83 * pointer to a null-terminated wide character array, but the four bytes (32
84 * bits) BEFORE the memory that the pointer points to are a length DWORD. One
85 * must therefore avoid pointer arithmetic and always use SysAllocString and
86 * the like to deal with BSTR pointers, which manage that DWORD correctly.
87 *
88 * For platforms other than Windows, we provide our own versions of the Sys*
89 * functions in Main/xpcom/helpers.cpp which do NOT use length prefixes though
90 * to be compatible with how XPCOM allocates string parameters to public
91 * functions.
92 *
93 * The Bstr class hides all this handling behind a std::string-like interface
94 * and also provides automatic conversions to RTCString and Utf8Str instances.
95 *
96 * The one advantage of using the SysString* routines is that this makes it
97 * possible to use it as a type of member variables of COM/XPCOM components and
98 * pass their values to callers through component methods' output parameters
99 * using the #cloneTo() operation. Also, the class can adopt (take ownership
100 * of) string buffers returned in output parameters of COM methods using the
101 * #asOutParam() operation and correctly free them afterwards.
102 *
103 * Starting with VirtualBox 3.2, like Utf8Str, Bstr no longer differentiates
104 * between NULL strings and empty strings. In other words, Bstr("") and
105 * Bstr(NULL) behave the same. In both cases, Bstr allocates no memory,
106 * reports a zero length and zero allocated bytes for both, and returns an
107 * empty C wide string from raw().
108 *
109 * @note All Bstr methods ASSUMES valid UTF-16 or UTF-8 input strings.
110 * The VirtualBox policy in this regard is to validate strings coming
111 * from external sources before passing them to Bstr or Utf8Str.
112 */
113class Bstr
114{
115public:
116
117 Bstr()
118 : m_bstr(NULL)
119 { }
120
121 Bstr(const Bstr &that)
122 {
123 copyFrom((const OLECHAR *)that.m_bstr);
124 }
125
126 Bstr(CBSTR that)
127 {
128 copyFrom((const OLECHAR *)that);
129 }
130
131#if defined(VBOX_WITH_XPCOM)
132 Bstr(const wchar_t *that)
133 {
134 AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
135 copyFrom((const OLECHAR *)that);
136 }
137#endif
138
139 Bstr(const RTCString &that)
140 {
141 copyFrom(that.c_str());
142 }
143
144 Bstr(const char *that)
145 {
146 copyFrom(that);
147 }
148
149 Bstr(const char *a_pThat, size_t a_cchMax)
150 {
151 copyFromN(a_pThat, a_cchMax);
152 }
153
154 ~Bstr()
155 {
156 setNull();
157 }
158
159 Bstr &operator=(const Bstr &that)
160 {
161 cleanupAndCopyFrom((const OLECHAR *)that.m_bstr);
162 return *this;
163 }
164
165 Bstr &operator=(CBSTR that)
166 {
167 cleanupAndCopyFrom((const OLECHAR *)that);
168 return *this;
169 }
170
171#if defined(VBOX_WITH_XPCOM)
172 Bstr &operator=(const wchar_t *that)
173 {
174 cleanupAndCopyFrom((const OLECHAR *)that);
175 return *this;
176 }
177#endif
178
179 Bstr &setNull()
180 {
181 cleanup();
182 return *this;
183 }
184
185 /**
186 * Extended assignment method that returns a COM status code instead of an
187 * exception on failure.
188 *
189 * @returns S_OK or E_OUTOFMEMORY.
190 * @param a_rSrcStr The source string
191 */
192 HRESULT assignEx(const Bstr &a_rSrcStr) RT_NOEXCEPT
193 {
194 return cleanupAndCopyFromEx((const OLECHAR *)a_rSrcStr.m_bstr);
195 }
196
197 /**
198 * Extended assignment method that returns a COM status code instead of an
199 * exception on failure.
200 *
201 * @returns S_OK or E_OUTOFMEMORY.
202 * @param a_pSrcStr The source string
203 */
204 HRESULT assignEx(CBSTR a_pSrcStr) RT_NOEXCEPT
205 {
206 return cleanupAndCopyFromEx((const OLECHAR *)a_pSrcStr);
207 }
208
209 /**
210 * Assign the value of a RTCString/Utf8Str string, no exceptions.
211 *
212 * @returns S_OK or E_OUTOFMEMORY.
213 * @param a_rSrcStr The source string
214 */
215 HRESULT assignEx(RTCString const &a_rSrcStr) RT_NOEXCEPT
216 {
217 return cleanupAndCopyFromNoThrow(a_rSrcStr.c_str(), a_rSrcStr.length());
218 }
219
220 /**
221 * Assign the value of a RTCString/Utf8Str substring, no exceptions.
222 *
223 * @returns S_OK, E_OUTOFMEMORY or E_INVALIDARG.
224 * @param a_rSrcStr The source string
225 * @param a_offSrc The character (byte) offset of the substring.
226 * @param a_cchSrc The number of characters (bytes) to copy from the source
227 * string.
228 */
229 HRESULT assignEx(RTCString const &a_rSrcStr, size_t a_offSrc, size_t a_cchSrc) RT_NOEXCEPT
230 {
231 size_t const cchTmp = a_rSrcStr.length();
232 if ( a_offSrc + a_cchSrc < cchTmp
233 && a_offSrc < cchTmp)
234 return cleanupAndCopyFromNoThrow(a_rSrcStr.c_str() + a_offSrc, a_cchSrc);
235 return E_INVALIDARG;
236 }
237
238 /**
239 * Assign the value of a zero terminated UTF-8 string, no exceptions.
240 *
241 * @returns S_OK or E_OUTOFMEMORY.
242 * @param a_pszSrcStr The source string.
243 */
244 HRESULT assignEx(const char *a_pszSrcStr) RT_NOEXCEPT
245 {
246 return cleanupAndCopyFromNoThrow(a_pszSrcStr, RTSTR_MAX);
247 }
248
249 /**
250 * Assign the value of a UTF-8 substring, no exceptions.
251 *
252 * @returns S_OK or E_OUTOFMEMORY.
253 * @param a_pszSrcStr The source string.
254 * @param a_cchSrc The number of characters (bytes) to copy from the source
255 * string.
256 */
257 HRESULT assignEx(const char *a_pszSrcStr, size_t a_cchSrc) RT_NOEXCEPT
258 {
259 return cleanupAndCopyFromNoThrow(a_pszSrcStr, a_cchSrc);
260 }
261
262#ifdef _MSC_VER
263# if _MSC_VER >= 1400
264 RTMEMEF_NEW_AND_DELETE_OPERATORS();
265# endif
266#else
267 RTMEMEF_NEW_AND_DELETE_OPERATORS();
268#endif
269
270 /** Case sensitivity selector. */
271 enum CaseSensitivity
272 {
273 CaseSensitive,
274 CaseInsensitive
275 };
276
277 /**
278 * Compares the member string to str.
279 * @param str
280 * @param cs Whether comparison should be case-sensitive.
281 * @return
282 */
283 int compare(CBSTR str, CaseSensitivity cs = CaseSensitive) const
284 {
285 if (cs == CaseSensitive)
286 return ::RTUtf16Cmp((PRTUTF16)m_bstr, (PRTUTF16)str);
287 return ::RTUtf16LocaleICmp((PRTUTF16)m_bstr, (PRTUTF16)str);
288 }
289
290 int compare(BSTR str, CaseSensitivity cs = CaseSensitive) const
291 {
292 return compare((CBSTR)str, cs);
293 }
294
295 int compare(const Bstr &that, CaseSensitivity cs = CaseSensitive) const
296 {
297 return compare(that.m_bstr, cs);
298 }
299
300 bool operator==(const Bstr &that) const { return !compare(that.m_bstr); }
301 bool operator==(CBSTR that) const { return !compare(that); }
302 bool operator==(BSTR that) const { return !compare(that); }
303 bool operator!=(const Bstr &that) const { return !!compare(that.m_bstr); }
304 bool operator!=(CBSTR that) const { return !!compare(that); }
305 bool operator!=(BSTR that) const { return !!compare(that); }
306 bool operator<(const Bstr &that) const { return compare(that.m_bstr) < 0; }
307 bool operator<(CBSTR that) const { return compare(that) < 0; }
308 bool operator<(BSTR that) const { return compare(that) < 0; }
309 bool operator<=(const Bstr &that) const { return compare(that.m_bstr) <= 0; }
310 bool operator<=(CBSTR that) const { return compare(that) <= 0; }
311 bool operator<=(BSTR that) const { return compare(that) <= 0; }
312 bool operator>(const Bstr &that) const { return compare(that.m_bstr) > 0; }
313 bool operator>(CBSTR that) const { return compare(that) > 0; }
314 bool operator>(BSTR that) const { return compare(that) > 0; }
315 bool operator>=(const Bstr &that) const { return compare(that.m_bstr) >= 0; }
316 bool operator>=(CBSTR that) const { return compare(that) >= 0; }
317 bool operator>=(BSTR that) const { return compare(that) >= 0; }
318
319 /**
320 * Compares this string to an UTF-8 C style string.
321 *
322 * @retval 0 if equal
323 * @retval -1 if this string is smaller than the UTF-8 one.
324 * @retval 1 if the UTF-8 string is smaller than this.
325 *
326 * @param a_pszRight The string to compare with.
327 * @param a_enmCase Whether comparison should be case-sensitive.
328 */
329 int compareUtf8(const char *a_pszRight, CaseSensitivity a_enmCase = CaseSensitive) const;
330
331 /** Java style compare method.
332 * @returns true if @a a_pszRight equals this string.
333 * @param a_pszRight The (UTF-8) string to compare with. */
334 bool equals(const char *a_pszRight) const { return compareUtf8(a_pszRight, CaseSensitive) == 0; }
335
336 /** Java style case-insensitive compare method.
337 * @returns true if @a a_pszRight equals this string.
338 * @param a_pszRight The (UTF-8) string to compare with. */
339 bool equalsIgnoreCase(const char *a_pszRight) const { return compareUtf8(a_pszRight, CaseInsensitive) == 0; }
340
341 /** Java style compare method.
342 * @returns true if @a a_rThat equals this string.
343 * @param a_rThat The other Bstr instance to compare with. */
344 bool equals(const Bstr &a_rThat) const { return compare(a_rThat.m_bstr, CaseSensitive) == 0; }
345 /** Java style case-insensitive compare method.
346 * @returns true if @a a_rThat equals this string.
347 * @param a_rThat The other Bstr instance to compare with. */
348 bool equalsIgnoreCase(const Bstr &a_rThat) const { return compare(a_rThat.m_bstr, CaseInsensitive) == 0; }
349
350 /** Java style compare method.
351 * @returns true if @a a_pThat equals this string.
352 * @param a_pThat The native const BSTR to compare with. */
353 bool equals(CBSTR a_pThat) const { return compare(a_pThat, CaseSensitive) == 0; }
354 /** Java style case-insensitive compare method.
355 * @returns true if @a a_pThat equals this string.
356 * @param a_pThat The native const BSTR to compare with. */
357 bool equalsIgnoreCase(CBSTR a_pThat) const { return compare(a_pThat, CaseInsensitive) == 0; }
358
359 /** Java style compare method.
360 * @returns true if @a a_pThat equals this string.
361 * @param a_pThat The native BSTR to compare with. */
362 bool equals(BSTR a_pThat) const { return compare(a_pThat, CaseSensitive) == 0; }
363 /** Java style case-insensitive compare method.
364 * @returns true if @a a_pThat equals this string.
365 * @param a_pThat The native BSTR to compare with. */
366 bool equalsIgnoreCase(BSTR a_pThat) const { return compare(a_pThat, CaseInsensitive) == 0; }
367
368 /**
369 * Checks if the string starts with @a a_rStart.
370 */
371 bool startsWith(Bstr const &a_rStart) const;
372 /**
373 * Checks if the string starts with @a a_rStart.
374 */
375 bool startsWith(RTCString const &a_rStart) const;
376 /**
377 * Checks if the string starts with @a a_pszStart.
378 */
379 bool startsWith(const char *a_pszStart) const;
380
381 /**
382 * Returns true if the member string has no length.
383 * This is true for instances created from both NULL and "" input strings.
384 *
385 * @note Always use this method to check if an instance is empty. Do not
386 * use length() because that may need to run through the entire string
387 * (Bstr does not cache string lengths).
388 */
389 bool isEmpty() const { return m_bstr == NULL || *m_bstr == 0; }
390
391 /**
392 * Returns true if the member string has a length of one or more.
393 *
394 * @returns true if not empty, false if empty (NULL or "").
395 */
396 bool isNotEmpty() const { return m_bstr != NULL && *m_bstr != 0; }
397
398 size_t length() const { return isEmpty() ? 0 : ::RTUtf16Len((PRTUTF16)m_bstr); }
399
400 /**
401 * Assigns the output of the string format operation (RTStrPrintf).
402 *
403 * @param pszFormat Pointer to the format string,
404 * @see pg_rt_str_format.
405 * @param ... Ellipsis containing the arguments specified by
406 * the format string.
407 *
408 * @throws std::bad_alloc On allocation error. Object state is undefined.
409 *
410 * @returns Reference to the object.
411 */
412 Bstr &printf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
413
414 /**
415 * Assigns the output of the string format operation (RTStrPrintf).
416 *
417 * @param pszFormat Pointer to the format string,
418 * @see pg_rt_str_format.
419 * @param ... Ellipsis containing the arguments specified by
420 * the format string.
421 *
422 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
423 */
424 HRESULT printfNoThrow(const char *pszFormat, ...) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 2);
425
426 /**
427 * Assigns the output of the string format operation (RTStrPrintfV).
428 *
429 * @param pszFormat Pointer to the format string,
430 * @see pg_rt_str_format.
431 * @param va Argument vector containing the arguments
432 * specified by the format string.
433 *
434 * @throws std::bad_alloc On allocation error. Object state is undefined.
435 *
436 * @returns Reference to the object.
437 */
438 Bstr &printfV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
439
440 /**
441 * Assigns the output of the string format operation (RTStrPrintfV).
442 *
443 * @param pszFormat Pointer to the format string,
444 * @see pg_rt_str_format.
445 * @param va Argument vector containing the arguments
446 * specified by the format string.
447 *
448 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
449 */
450 HRESULT printfVNoThrow(const char *pszFormat, va_list va) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 0);
451
452 /** @name Append methods and operators
453 * @{ */
454
455 /**
456 * Appends the string @a that to @a rThat.
457 *
458 * @param rThat The string to append.
459 * @throws std::bad_alloc On allocation error. The object is left unchanged.
460 * @returns Reference to the object.
461 */
462 Bstr &append(const Bstr &rThat);
463
464 /**
465 * Appends the string @a that to @a rThat.
466 *
467 * @param rThat The string to append.
468 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
469 */
470 HRESULT appendNoThrow(const Bstr &rThat) RT_NOEXCEPT;
471
472 /**
473 * Appends the UTF-8 string @a that to @a rThat.
474 *
475 * @param rThat The string to append.
476 * @throws std::bad_alloc On allocation error. The object is left unchanged.
477 * @returns Reference to the object.
478 */
479 Bstr &append(const RTCString &rThat);
480
481 /**
482 * Appends the UTF-8 string @a that to @a rThat.
483 *
484 * @param rThat The string to append.
485 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
486 */
487 HRESULT appendNoThrow(const RTCString &rThat) RT_NOEXCEPT;
488
489 /**
490 * Appends the UTF-16 string @a pszSrc to @a this.
491 *
492 * @param pwszSrc The C-style UTF-16 string to append.
493 * @throws std::bad_alloc On allocation error. The object is left unchanged.
494 * @returns Reference to the object.
495 */
496 Bstr &append(CBSTR pwszSrc);
497
498 /**
499 * Appends the UTF-16 string @a pszSrc to @a this.
500 *
501 * @param pwszSrc The C-style UTF-16 string to append.
502 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
503 */
504 HRESULT appendNoThrow(CBSTR pwszSrc) RT_NOEXCEPT;
505
506 /**
507 * Appends the UTF-8 string @a pszSrc to @a this.
508 *
509 * @param pszSrc The C-style string to append.
510 * @throws std::bad_alloc On allocation error. The object is left unchanged.
511 * @returns Reference to the object.
512 */
513 Bstr &append(const char *pszSrc);
514
515 /**
516 * Appends the UTF-8 string @a pszSrc to @a this.
517 *
518 * @param pszSrc The C-style string to append.
519 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
520 */
521 HRESULT appendNoThrow(const char *pszSrc) RT_NOEXCEPT;
522
523 /**
524 * Appends the a substring from @a rThat to @a this.
525 *
526 * @param rThat The string to append a substring from.
527 * @param offStart The start of the substring to append (UTF-16
528 * offset, not codepoint).
529 * @param cwcMax The maximum number of UTF-16 units to append.
530 * @throws std::bad_alloc On allocation error. The object is left unchanged.
531 * @returns Reference to the object.
532 */
533 Bstr &append(const Bstr &rThat, size_t offStart, size_t cwcMax = RTSTR_MAX);
534
535 /**
536 * Appends the a substring from @a rThat to @a this.
537 *
538 * @param rThat The string to append a substring from.
539 * @param offStart The start of the substring to append (UTF-16
540 * offset, not codepoint).
541 * @param cwcMax The maximum number of UTF-16 units to append.
542 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
543 */
544 HRESULT appendNoThrow(const Bstr &rThat, size_t offStart, size_t cwcMax = RTSTR_MAX) RT_NOEXCEPT;
545
546 /**
547 * Appends the a substring from UTF-8 @a rThat to @a this.
548 *
549 * @param rThat The string to append a substring from.
550 * @param offStart The start of the substring to append (byte offset,
551 * not codepoint).
552 * @param cchMax The maximum number of bytes to append.
553 * @throws std::bad_alloc On allocation error. The object is left unchanged.
554 * @returns Reference to the object.
555 */
556 Bstr &append(const RTCString &rThat, size_t offStart, size_t cchMax = RTSTR_MAX);
557
558 /**
559 * Appends the a substring from UTF-8 @a rThat to @a this.
560 *
561 * @param rThat The string to append a substring from.
562 * @param offStart The start of the substring to append (byte offset,
563 * not codepoint).
564 * @param cchMax The maximum number of bytes to append.
565 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
566 */
567 HRESULT appendNoThrow(const RTCString &rThat, size_t offStart, size_t cchMax = RTSTR_MAX) RT_NOEXCEPT;
568
569 /**
570 * Appends the first @a cchMax chars from UTF-16 string @a pszThat to @a this.
571 *
572 * @param pwszThat The C-style UTF-16 string to append.
573 * @param cchMax The maximum number of bytes to append.
574 * @throws std::bad_alloc On allocation error. The object is left unchanged.
575 * @returns Reference to the object.
576 */
577 Bstr &append(CBSTR pwszThat, size_t cchMax);
578
579 /**
580 * Appends the first @a cchMax chars from UTF-16 string @a pszThat to @a this.
581 *
582 * @param pwszThat The C-style UTF-16 string to append.
583 * @param cchMax The maximum number of bytes to append.
584 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
585 */
586 HRESULT appendNoThrow(CBSTR pwszThat, size_t cchMax) RT_NOEXCEPT;
587
588 /**
589 * Appends the first @a cchMax chars from string @a pszThat to @a this.
590 *
591 * @param pszThat The C-style string to append.
592 * @param cchMax The maximum number of bytes to append.
593 * @throws std::bad_alloc On allocation error. The object is left unchanged.
594 * @returns Reference to the object.
595 */
596 Bstr &append(const char *pszThat, size_t cchMax);
597
598 /**
599 * Appends the first @a cchMax chars from string @a pszThat to @a this.
600 *
601 * @param pszThat The C-style string to append.
602 * @param cchMax The maximum number of bytes to append.
603 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
604 */
605 HRESULT appendNoThrow(const char *pszThat, size_t cchMax) RT_NOEXCEPT;
606
607 /**
608 * Appends the given character to @a this.
609 *
610 * @param ch The character to append.
611 * @throws std::bad_alloc On allocation error. The object is left unchanged.
612 * @returns Reference to the object.
613 */
614 Bstr &append(char ch);
615
616 /**
617 * Appends the given character to @a this.
618 *
619 * @param ch The character to append.
620 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
621 */
622 HRESULT appendNoThrow(char ch) RT_NOEXCEPT;
623
624 /**
625 * Appends the given unicode code point to @a this.
626 *
627 * @param uc The unicode code point to append.
628 * @throws std::bad_alloc On allocation error. The object is left unchanged.
629 * @returns Reference to the object.
630 */
631 Bstr &appendCodePoint(RTUNICP uc);
632
633 /**
634 * Appends the given unicode code point to @a this.
635 *
636 * @param uc The unicode code point to append.
637 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
638 */
639 HRESULT appendCodePointNoThrow(RTUNICP uc) RT_NOEXCEPT;
640
641 /**
642 * Appends the output of the string format operation (RTStrPrintf).
643 *
644 * @param pszFormat Pointer to the format string,
645 * @see pg_rt_str_format.
646 * @param ... Ellipsis containing the arguments specified by
647 * the format string.
648 *
649 * @throws std::bad_alloc On allocation error. Object state is undefined.
650 *
651 * @returns Reference to the object.
652 */
653 Bstr &appendPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
654
655 /**
656 * Appends the output of the string format operation (RTStrPrintf).
657 *
658 * @param pszFormat Pointer to the format string,
659 * @see pg_rt_str_format.
660 * @param ... Ellipsis containing the arguments specified by
661 * the format string.
662 *
663 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
664 */
665 HRESULT appendPrintfNoThrow(const char *pszFormat, ...) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 2);
666
667 /**
668 * Appends the output of the string format operation (RTStrPrintfV).
669 *
670 * @param pszFormat Pointer to the format string,
671 * @see pg_rt_str_format.
672 * @param va Argument vector containing the arguments
673 * specified by the format string.
674 *
675 * @throws std::bad_alloc On allocation error. Object state is undefined.
676 *
677 * @returns Reference to the object.
678 */
679 Bstr &appendPrintfV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
680
681 /**
682 * Appends the output of the string format operation (RTStrPrintfV).
683 *
684 * @param pszFormat Pointer to the format string,
685 * @see pg_rt_str_format.
686 * @param va Argument vector containing the arguments
687 * specified by the format string.
688 *
689 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
690 */
691 HRESULT appendPrintfVNoThrow(const char *pszFormat, va_list va) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 0);
692
693 /**
694 * Shortcut to append(), Bstr variant.
695 *
696 * @param rThat The string to append.
697 * @returns Reference to the object.
698 */
699 Bstr &operator+=(const Bstr &rThat)
700 {
701 return append(rThat);
702 }
703
704 /**
705 * Shortcut to append(), RTCString variant.
706 *
707 * @param rThat The string to append.
708 * @returns Reference to the object.
709 */
710 Bstr &operator+=(const RTCString &rThat)
711 {
712 return append(rThat);
713 }
714
715 /**
716 * Shortcut to append(), CBSTR variant.
717 *
718 * @param pwszThat The C-style string to append.
719 * @returns Reference to the object.
720 */
721 Bstr &operator+=(CBSTR pwszThat)
722 {
723 return append(pwszThat);
724 }
725
726 /**
727 * Shortcut to append(), const char * variant.
728 *
729 * @param pszThat The C-style string to append.
730 * @returns Reference to the object.
731 */
732 Bstr &operator+=(const char *pszThat)
733 {
734 return append(pszThat);
735 }
736
737 /**
738 * Shortcut to append(), char variant.
739 *
740 * @param ch The character to append.
741 *
742 * @returns Reference to the object.
743 */
744 Bstr &operator+=(char ch)
745 {
746 return append(ch);
747 }
748
749 /** @} */
750
751 /**
752 * Erases a sequence from the string.
753 *
754 * @returns Reference to the object.
755 * @param offStart Where in @a this string to start erasing (UTF-16
756 * units, not codepoints).
757 * @param cwcLength How much following @a offStart to erase (UTF-16
758 * units, not codepoints).
759 */
760 Bstr &erase(size_t offStart = 0, size_t cwcLength = RTSTR_MAX) RT_NOEXCEPT;
761
762
763 /** @name BASE64 related methods
764 * @{ */
765 /**
766 * Encodes the given data as BASE64.
767 *
768 * @returns S_OK or E_OUTOFMEMORY.
769 * @param pvData Pointer to the data to encode.
770 * @param cbData Number of bytes to encode.
771 * @param fLineBreaks Whether to add line breaks (true) or just encode it
772 * as a continuous string.
773 * @sa RTBase64EncodeUtf16
774 */
775 HRESULT base64Encode(const void *pvData, size_t cbData, bool fLineBreaks = false);
776
777 /**
778 * Decodes the string as BASE64.
779 *
780 * @returns IPRT status code, see RTBase64DecodeUtf16Ex.
781 * @param pvData Where to return the decoded bytes.
782 * @param cbData Size of the @a pvData return buffer.
783 * @param pcbActual Where to return number of bytes actually decoded.
784 * This is optional and if not specified, the request
785 * will fail unless @a cbData matches the data size
786 * exactly.
787 * @param ppwszEnd Where to return pointer to the first non-base64
788 * character following the encoded data. This is
789 * optional and if NULL, the request will fail if there
790 * are anything trailing the encoded bytes in the
791 * string.
792 * @sa base64DecodedSize, RTBase64DecodeUtf16
793 */
794 int base64Decode(void *pvData, size_t cbData, size_t *pcbActual = NULL, PRTUTF16 *ppwszEnd = NULL);
795
796 /**
797 * Determins the size of the BASE64 encoded data in the string.
798 *
799 * @returns The length in bytes. -1 if the encoding is bad.
800 *
801 * @param ppwszEnd If not NULL, this will point to the first char
802 * following the Base64 encoded text block. If
803 * NULL the entire string is assumed to be Base64.
804 * @sa base64Decode, RTBase64DecodedUtf16Size
805 */
806 ssize_t base64DecodedSize(PRTUTF16 *ppwszEnd = NULL);
807 /** @} */
808
809#if defined(VBOX_WITH_XPCOM)
810 /**
811 * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
812 * returns a pointer to a global variable containing an empty BSTR with a proper zero
813 * length prefix so that Windows is happy.
814 */
815 CBSTR raw() const
816 {
817 if (m_bstr)
818 return m_bstr;
819
820 return g_bstrEmpty;
821 }
822#else
823 /**
824 * Windows-only hack, as the automatically generated headers use BSTR.
825 * So if we don't want to cast like crazy we have to be more loose than
826 * on XPCOM.
827 *
828 * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
829 * returns a pointer to a global variable containing an empty BSTR with a proper zero
830 * length prefix so that Windows is happy.
831 */
832 BSTR raw() const
833 {
834 if (m_bstr)
835 return m_bstr;
836
837 return g_bstrEmpty;
838 }
839#endif
840
841 /**
842 * Returns a non-const raw pointer that allows modifying the string directly.
843 *
844 * @note As opposed to raw(), this DOES return NULL if the member string is
845 * empty because we cannot return a mutable pointer to the global variable
846 * with the empty string.
847 *
848 * @note If modifying the string size (only shrinking it is allows), #jolt() or
849 * #joltNoThrow() must be called!
850 *
851 * @note Do not modify memory beyond the #length() of the string!
852 *
853 * @sa joltNoThrow(), mutalbleRaw(), reserve(), reserveNoThrow()
854 */
855 BSTR mutableRaw() { return m_bstr; }
856
857 /**
858 * Correct the embedded length after using mutableRaw().
859 *
860 * This is needed on COM (Windows) to update the embedded string length. It is
861 * a stub on hosts using XPCOM.
862 *
863 * @param cwcNew The new string length, if handy, otherwise a negative
864 * number.
865 * @sa joltNoThrow(), mutalbleRaw(), reserve(), reserveNoThrow()
866 */
867#ifndef VBOX_WITH_XPCOM
868 void jolt(ssize_t cwcNew = -1);
869#else
870 void jolt(ssize_t cwcNew = -1)
871 {
872 Assert(cwcNew < 0 || (cwcNew == 0 && !m_bstr) || m_bstr[cwcNew] == '\0'); RT_NOREF(cwcNew);
873 }
874#endif
875
876 /**
877 * Correct the embedded length after using mutableRaw().
878 *
879 * This is needed on COM (Windows) to update the embedded string length. It is
880 * a stub on hosts using XPCOM.
881 *
882 * @returns S_OK on success, E_OUTOFMEMORY if shrinking the string failed.
883 * @param cwcNew The new string length, if handy, otherwise a negative
884 * number.
885 * @sa jolt(), mutalbleRaw(), reserve(), reserveNoThrow()
886 */
887#ifndef VBOX_WITH_XPCOM
888 HRESULT joltNoThrow(ssize_t cwcNew = -1) RT_NOEXCEPT;
889#else
890 HRESULT joltNoThrow(ssize_t cwcNew = -1) RT_NOEXCEPT
891 {
892 Assert(cwcNew < 0 || (cwcNew == 0 && !m_bstr) || m_bstr[cwcNew] == '\0'); RT_NOREF(cwcNew);
893 return S_OK;
894 }
895#endif
896
897 /**
898 * Make sure at that least @a cwc of buffer space is reserved.
899 *
900 * Requests that the contained memory buffer have at least cb bytes allocated.
901 * This may expand or shrink the string's storage, but will never truncate the
902 * contained string. In other words, cb will be ignored if it's smaller than
903 * length() + 1.
904 *
905 * @param cwcMin The new minimum string length that the can be stored. This
906 * does not include the terminator.
907 * @param fForce Force this size.
908 *
909 * @throws std::bad_alloc On allocation error. The object is left unchanged.
910 */
911 void reserve(size_t cwcMin, bool fForce = false);
912
913 /**
914 * A C like version of the #reserve() method, i.e. return code instead of throw.
915 *
916 * @returns S_OK or E_OUTOFMEMORY.
917 * @param cwcMin The new minimum string length that the can be stored. This
918 * does not include the terminator.
919 * @param fForce Force this size.
920 */
921 HRESULT reserveNoThrow(size_t cwcMin, bool fForce = false) RT_NOEXCEPT;
922
923 /**
924 * Intended to assign copies of instances to |BSTR| out parameters from
925 * within the interface method. Transfers the ownership of the duplicated
926 * string to the caller.
927 *
928 * If the member string is empty, this allocates an empty BSTR in *pstr
929 * (i.e. makes it point to a new buffer with a null byte).
930 *
931 * @deprecated Use cloneToEx instead to avoid throwing exceptions.
932 */
933 void cloneTo(BSTR *pstr) const
934 {
935 if (pstr)
936 {
937 *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty
938#ifdef RT_EXCEPTIONS_ENABLED
939 if (!*pstr)
940 throw std::bad_alloc();
941#endif
942 }
943 }
944
945 /**
946 * A version of cloneTo that does not throw any out of memory exceptions, but
947 * returns E_OUTOFMEMORY intead.
948 * @returns S_OK or E_OUTOFMEMORY.
949 */
950 HRESULT cloneToEx(BSTR *pstr) const
951 {
952 if (!pstr)
953 return S_OK;
954 *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty
955 return pstr ? S_OK : E_OUTOFMEMORY;
956 }
957
958 /**
959 * Intended to assign instances to |BSTR| out parameters from within the
960 * interface method. Transfers the ownership of the original string to the
961 * caller and resets the instance to null.
962 *
963 * As opposed to cloneTo(), this method doesn't create a copy of the
964 * string.
965 *
966 * If the member string is empty, this allocates an empty BSTR in *pstr
967 * (i.e. makes it point to a new buffer with a null byte).
968 *
969 * @param pbstrDst The BSTR variable to detach the string to.
970 *
971 * @throws std::bad_alloc if we failed to allocate a new empty string.
972 */
973 void detachTo(BSTR *pbstrDst)
974 {
975 if (m_bstr)
976 {
977 *pbstrDst = m_bstr;
978 m_bstr = NULL;
979 }
980 else
981 {
982 // allocate null BSTR
983 *pbstrDst = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
984#ifdef RT_EXCEPTIONS_ENABLED
985 if (!*pbstrDst)
986 throw std::bad_alloc();
987#endif
988 }
989 }
990
991 /**
992 * A version of detachTo that does not throw exceptions on out-of-memory
993 * conditions, but instead returns E_OUTOFMEMORY.
994 *
995 * @param pbstrDst The BSTR variable to detach the string to.
996 * @returns S_OK or E_OUTOFMEMORY.
997 */
998 HRESULT detachToEx(BSTR *pbstrDst)
999 {
1000 if (m_bstr)
1001 {
1002 *pbstrDst = m_bstr;
1003 m_bstr = NULL;
1004 }
1005 else
1006 {
1007 // allocate null BSTR
1008 *pbstrDst = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
1009 if (!*pbstrDst)
1010 return E_OUTOFMEMORY;
1011 }
1012 return S_OK;
1013 }
1014
1015 /**
1016 * Intended to pass instances as |BSTR| out parameters to methods.
1017 * Takes the ownership of the returned data.
1018 */
1019 BSTR *asOutParam()
1020 {
1021 cleanup();
1022 return &m_bstr;
1023 }
1024
1025 /**
1026 * Static immutable empty-string object. May be used for comparison purposes.
1027 */
1028 static const Bstr Empty;
1029
1030protected:
1031
1032 void cleanup();
1033
1034 /**
1035 * Protected internal helper to copy a string. This ignores the previous object
1036 * state, so either call this from a constructor or call cleanup() first.
1037 *
1038 * This variant copies from a zero-terminated UTF-16 string (which need not
1039 * be a BSTR, i.e. need not have a length prefix).
1040 *
1041 * If the source is empty, this sets the member string to NULL.
1042 *
1043 * @param a_bstrSrc The source string. The caller guarantees
1044 * that this is valid UTF-16.
1045 *
1046 * @throws std::bad_alloc - the object is representing an empty string.
1047 */
1048 void copyFrom(const OLECHAR *a_bstrSrc);
1049
1050 /** cleanup() + copyFrom() - for assignment operators. */
1051 void cleanupAndCopyFrom(const OLECHAR *a_bstrSrc);
1052
1053 /**
1054 * Protected internal helper to copy a string, implying cleanup().
1055 *
1056 * This variant copies from a zero-terminated UTF-16 string (which need not be a
1057 * BSTR, i.e. need not have a length prefix).
1058 *
1059 * If the source is empty, this sets the member string to NULL.
1060 *
1061 * @param a_bstrSrc The source string. The caller guarantees
1062 * that this is valid UTF-16.
1063 * @returns S_OK or E_OUTOFMEMORY
1064 */
1065 HRESULT cleanupAndCopyFromEx(const OLECHAR *a_bstrSrc) RT_NOEXCEPT;
1066
1067 /**
1068 * Protected internal helper to copy a string. This ignores the previous object
1069 * state, so either call this from a constructor or call cleanup() first.
1070 *
1071 * This variant copies and converts from a zero-terminated UTF-8 string.
1072 *
1073 * If the source is empty, this sets the member string to NULL.
1074 *
1075 * @param a_pszSrc The source string. The caller guarantees
1076 * that this is valid UTF-8.
1077 *
1078 * @throws std::bad_alloc - the object is representing an empty string.
1079 */
1080 void copyFrom(const char *a_pszSrc)
1081 {
1082 copyFromN(a_pszSrc, RTSTR_MAX);
1083 }
1084
1085 /**
1086 * Variant of copyFrom for sub-string constructors.
1087 *
1088 * @param a_pszSrc The source string. The caller guarantees
1089 * that this is valid UTF-8.
1090 * @param a_cchSrc The maximum number of chars (not codepoints) to
1091 * copy. If you pass RTSTR_MAX it'll be exactly
1092 * like copyFrom().
1093 *
1094 * @throws std::bad_alloc - the object is representing an empty string.
1095 */
1096 void copyFromN(const char *a_pszSrc, size_t a_cchSrc);
1097
1098 /** cleanup() + non-throwing copyFromN(). */
1099 HRESULT cleanupAndCopyFromNoThrow(const char *a_pszSrc, size_t a_cchMax) RT_NOEXCEPT;
1100
1101 Bstr &appendWorkerUtf16(PCRTUTF16 pwszSrc, size_t cwcSrc);
1102 Bstr &appendWorkerUtf8(const char *pszSrc, size_t cchSrc);
1103 HRESULT appendWorkerUtf16NoThrow(PCRTUTF16 pwszSrc, size_t cwcSrc) RT_NOEXCEPT;
1104 HRESULT appendWorkerUtf8NoThrow(const char *pszSrc, size_t cchSrc) RT_NOEXCEPT;
1105
1106 static DECLCALLBACK(size_t) printfOutputCallbackNoThrow(void *pvArg, const char *pachChars, size_t cbChars) RT_NOEXCEPT;
1107
1108 BSTR m_bstr;
1109
1110 friend class Utf8Str; /* to access our raw_copy() */
1111};
1112
1113/* symmetric compare operators */
1114inline bool operator==(CBSTR l, const Bstr &r) { return r.operator==(l); }
1115inline bool operator!=(CBSTR l, const Bstr &r) { return r.operator!=(l); }
1116inline bool operator==(BSTR l, const Bstr &r) { return r.operator==(l); }
1117inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!=(l); }
1118
1119
1120
1121
1122/**
1123 * String class used universally in Main for UTF-8 strings.
1124 *
1125 * This is based on RTCString, to which some functionality has been
1126 * moved. Here we keep things that are specific to Main, such as conversions
1127 * with UTF-16 strings (Bstr).
1128 *
1129 * Like RTCString, Utf8Str does not differentiate between NULL strings
1130 * and empty strings. In other words, Utf8Str("") and Utf8Str(NULL) behave the
1131 * same. In both cases, RTCString allocates no memory, reports
1132 * a zero length and zero allocated bytes for both, and returns an empty
1133 * C string from c_str().
1134 *
1135 * @note All Utf8Str methods ASSUMES valid UTF-8 or UTF-16 input strings.
1136 * The VirtualBox policy in this regard is to validate strings coming
1137 * from external sources before passing them to Utf8Str or Bstr.
1138 */
1139class Utf8Str : public RTCString
1140{
1141public:
1142
1143 Utf8Str() {}
1144
1145 Utf8Str(const RTCString &that)
1146 : RTCString(that)
1147 {}
1148
1149 Utf8Str(const char *that)
1150 : RTCString(that)
1151 {}
1152
1153 Utf8Str(const Bstr &that)
1154 {
1155 copyFrom(that.raw());
1156 }
1157
1158 Utf8Str(CBSTR that, size_t a_cwcSize = RTSTR_MAX)
1159 {
1160 copyFrom(that, a_cwcSize);
1161 }
1162
1163 Utf8Str(const char *a_pszSrc, size_t a_cchSrc)
1164 : RTCString(a_pszSrc, a_cchSrc)
1165 {
1166 }
1167
1168 /**
1169 * Constructs a new string given the format string and the list of the
1170 * arguments for the format string.
1171 *
1172 * @param a_pszFormat Pointer to the format string (UTF-8),
1173 * @see pg_rt_str_format.
1174 * @param a_va Argument vector containing the arguments
1175 * specified by the format string.
1176 * @sa RTCString::printfV
1177 */
1178 Utf8Str(const char *a_pszFormat, va_list a_va) RT_IPRT_FORMAT_ATTR(1, 0)
1179 : RTCString(a_pszFormat, a_va)
1180 {
1181 }
1182
1183 Utf8Str& operator=(const RTCString &that)
1184 {
1185 RTCString::operator=(that);
1186 return *this;
1187 }
1188
1189 Utf8Str& operator=(const char *that)
1190 {
1191 RTCString::operator=(that);
1192 return *this;
1193 }
1194
1195 Utf8Str& operator=(const Bstr &that)
1196 {
1197 cleanup();
1198 copyFrom(that.raw());
1199 return *this;
1200 }
1201
1202 Utf8Str& operator=(CBSTR that)
1203 {
1204 cleanup();
1205 copyFrom(that);
1206 return *this;
1207 }
1208
1209 /**
1210 * Extended assignment method that returns a COM status code instead of an
1211 * exception on failure.
1212 *
1213 * @returns S_OK or E_OUTOFMEMORY.
1214 * @param a_rSrcStr The source string
1215 */
1216 HRESULT assignEx(Utf8Str const &a_rSrcStr)
1217 {
1218 return copyFromExNComRC(a_rSrcStr.m_psz, 0, a_rSrcStr.m_cch);
1219 }
1220
1221 /**
1222 * Extended assignment method that returns a COM status code instead of an
1223 * exception on failure.
1224 *
1225 * @returns S_OK, E_OUTOFMEMORY or E_INVALIDARG.
1226 * @param a_rSrcStr The source string
1227 * @param a_offSrc The character (byte) offset of the substring.
1228 * @param a_cchSrc The number of characters (bytes) to copy from the source
1229 * string.
1230 */
1231 HRESULT assignEx(Utf8Str const &a_rSrcStr, size_t a_offSrc, size_t a_cchSrc)
1232 {
1233 if ( a_offSrc + a_cchSrc > a_rSrcStr.m_cch
1234 || a_offSrc > a_rSrcStr.m_cch)
1235 return E_INVALIDARG;
1236 return copyFromExNComRC(a_rSrcStr.m_psz, a_offSrc, a_cchSrc);
1237 }
1238
1239 /**
1240 * Extended assignment method that returns a COM status code instead of an
1241 * exception on failure.
1242 *
1243 * @returns S_OK or E_OUTOFMEMORY.
1244 * @param a_pcszSrc The source string
1245 */
1246 HRESULT assignEx(const char *a_pcszSrc)
1247 {
1248 return copyFromExNComRC(a_pcszSrc, 0, a_pcszSrc ? strlen(a_pcszSrc) : 0);
1249 }
1250
1251 /**
1252 * Extended assignment method that returns a COM status code instead of an
1253 * exception on failure.
1254 *
1255 * @returns S_OK or E_OUTOFMEMORY.
1256 * @param a_pcszSrc The source string
1257 * @param a_cchSrc The number of characters (bytes) to copy from the source
1258 * string.
1259 */
1260 HRESULT assignEx(const char *a_pcszSrc, size_t a_cchSrc)
1261 {
1262 return copyFromExNComRC(a_pcszSrc, 0, a_cchSrc);
1263 }
1264
1265 RTMEMEF_NEW_AND_DELETE_OPERATORS();
1266
1267#if defined(VBOX_WITH_XPCOM)
1268 /**
1269 * Intended to assign instances to |char *| out parameters from within the
1270 * interface method. Transfers the ownership of the duplicated string to the
1271 * caller.
1272 *
1273 * This allocates a single 0 byte in the target if the member string is empty.
1274 *
1275 * This uses XPCOM memory allocation and thus only works on XPCOM. MSCOM doesn't
1276 * like char* strings anyway.
1277 */
1278 void cloneTo(char **pstr) const;
1279
1280 /**
1281 * A version of cloneTo that does not throw allocation errors but returns
1282 * E_OUTOFMEMORY instead.
1283 * @returns S_OK or E_OUTOFMEMORY (COM status codes).
1284 */
1285 HRESULT cloneToEx(char **pstr) const;
1286#endif
1287
1288 /**
1289 * Intended to assign instances to |BSTR| out parameters from within the
1290 * interface method. Transfers the ownership of the duplicated string to the
1291 * caller.
1292 */
1293 void cloneTo(BSTR *pstr) const
1294 {
1295 if (pstr)
1296 {
1297 Bstr bstr(*this);
1298 bstr.cloneTo(pstr);
1299 }
1300 }
1301
1302 /**
1303 * A version of cloneTo that does not throw allocation errors but returns
1304 * E_OUTOFMEMORY instead.
1305 *
1306 * @param pbstr Where to store a clone of the string.
1307 * @returns S_OK or E_OUTOFMEMORY (COM status codes).
1308 */
1309 HRESULT cloneToEx(BSTR *pbstr) const RT_NOEXCEPT;
1310
1311 /**
1312 * Safe assignment from BSTR.
1313 *
1314 * @param pbstrSrc The source string.
1315 * @returns S_OK or E_OUTOFMEMORY (COM status codes).
1316 */
1317 HRESULT cloneEx(CBSTR pbstrSrc)
1318 {
1319 cleanup();
1320 return copyFromEx(pbstrSrc);
1321 }
1322
1323 /**
1324 * Removes a trailing slash from the member string, if present.
1325 * Calls RTPathStripTrailingSlash() without having to mess with mutableRaw().
1326 */
1327 Utf8Str& stripTrailingSlash();
1328
1329 /**
1330 * Removes a trailing filename from the member string, if present.
1331 * Calls RTPathStripFilename() without having to mess with mutableRaw().
1332 */
1333 Utf8Str& stripFilename();
1334
1335 /**
1336 * Removes the path component from the member string, if present.
1337 * Calls RTPathFilename() without having to mess with mutableRaw().
1338 */
1339 Utf8Str& stripPath();
1340
1341 /**
1342 * Removes a trailing file name suffix from the member string, if present.
1343 * Calls RTPathStripSuffix() without having to mess with mutableRaw().
1344 */
1345 Utf8Str& stripSuffix();
1346
1347 /**
1348 * Parses key=value pairs.
1349 *
1350 * @returns offset of the @a a_rPairSeparator following the returned value.
1351 * @retval npos is returned if there are no more key/value pairs.
1352 *
1353 * @param a_rKey Reference to variable that should receive
1354 * the key substring. This is set to null if
1355 * no key/value found. (It's also possible the
1356 * key is an empty string, so be careful.)
1357 * @param a_rValue Reference to variable that should receive
1358 * the value substring. This is set to null if
1359 * no key/value found. (It's also possible the
1360 * value is an empty string, so be careful.)
1361 * @param a_offStart The offset to start searching from. This is
1362 * typically 0 for the first call, and the
1363 * return value of the previous call for the
1364 * subsequent ones.
1365 * @param a_rPairSeparator The pair separator string. If this is an
1366 * empty string, the whole string will be
1367 * considered as a single key/value pair.
1368 * @param a_rKeyValueSeparator The key/value separator string.
1369 */
1370 size_t parseKeyValue(Utf8Str &a_rKey, Utf8Str &a_rValue, size_t a_offStart = 0,
1371 const Utf8Str &a_rPairSeparator = ",", const Utf8Str &a_rKeyValueSeparator = "=") const;
1372
1373 /**
1374 * Static immutable empty-string object. May be used for comparison purposes.
1375 */
1376 static const Utf8Str Empty;
1377protected:
1378
1379 void copyFrom(CBSTR a_pbstr, size_t a_cwcMax = RTSTR_MAX);
1380 HRESULT copyFromEx(CBSTR a_pbstr);
1381 HRESULT copyFromExNComRC(const char *a_pcszSrc, size_t a_offSrc, size_t a_cchSrc);
1382
1383 friend class Bstr; /* to access our raw_copy() */
1384};
1385
1386/**
1387 * Class with RTCString::printf as constructor for your convenience.
1388 *
1389 * Constructing a Utf8Str string object from a format string and a variable
1390 * number of arguments can easily be confused with the other Utf8Str
1391 * constructures, thus this child class.
1392 *
1393 * The usage of this class is like the following:
1394 * @code
1395 Utf8StrFmt strName("program name = %s", argv[0]);
1396 @endcode
1397 *
1398 * @note Do not use in assignments to Utf8Str variables. Instead use
1399 * RTCString::printf directly on the variable! This avoid an extra
1400 * temporary Utf8Str instance and assignment operation.
1401 */
1402class Utf8StrFmt : public Utf8Str
1403{
1404public:
1405
1406 /**
1407 * Constructs a new string given the format string and the list of the
1408 * arguments for the format string.
1409 *
1410 * @param a_pszFormat Pointer to the format string (UTF-8),
1411 * @see pg_rt_str_format.
1412 * @param ... Ellipsis containing the arguments specified by
1413 * the format string.
1414 */
1415 explicit Utf8StrFmt(const char *a_pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2)
1416 {
1417 va_list va;
1418 va_start(va, a_pszFormat);
1419 printfV(a_pszFormat, va);
1420 va_end(va);
1421 }
1422
1423 RTMEMEF_NEW_AND_DELETE_OPERATORS();
1424
1425protected:
1426 Utf8StrFmt()
1427 { }
1428
1429private:
1430};
1431
1432/**
1433 * Class with Bstr::printf as constructor for your convenience.
1434 */
1435class BstrFmt : public Bstr
1436{
1437public:
1438
1439 /**
1440 * Constructs a new string given the format string and the list of the
1441 * arguments for the format string.
1442 *
1443 * @param a_pszFormat printf-like format string (in UTF-8 encoding), see
1444 * iprt/string.h for details.
1445 * @param ... List of the arguments for the format string.
1446 */
1447 explicit BstrFmt(const char *a_pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2)
1448 {
1449 va_list va;
1450 va_start(va, a_pszFormat);
1451 printfV(a_pszFormat, va);
1452 va_end(va);
1453 }
1454
1455 RTMEMEF_NEW_AND_DELETE_OPERATORS();
1456
1457protected:
1458 BstrFmt()
1459 { }
1460};
1461
1462/**
1463 * Class with Bstr::printfV as constructor for your convenience.
1464 */
1465class BstrFmtVA : public Bstr
1466{
1467public:
1468
1469 /**
1470 * Constructs a new string given the format string and the list of the
1471 * arguments for the format string.
1472 *
1473 * @param a_pszFormat printf-like format string (in UTF-8 encoding), see
1474 * iprt/string.h for details.
1475 * @param a_va List of arguments for the format string
1476 */
1477 BstrFmtVA(const char *a_pszFormat, va_list a_va) RT_IPRT_FORMAT_ATTR(1, 0)
1478 {
1479 printfV(a_pszFormat, a_va);
1480 }
1481
1482 RTMEMEF_NEW_AND_DELETE_OPERATORS();
1483
1484protected:
1485 BstrFmtVA()
1486 { }
1487};
1488
1489} /* namespace com */
1490
1491/** @} */
1492
1493#endif /* !VBOX_INCLUDED_com_string_h */
1494
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