VirtualBox

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

Last change on this file since 84823 was 84341, checked in by vboxsync, 5 years ago

Glue/Bstr: Added base64DecodedLength and base64Decode methods too. Put the implementation in a separate file for extpack and others who don't really need this code. [doxygen] bugref:9224

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 46.6 KB
Line 
1/* $Id: string.h 84341 2020-05-18 17:40:10Z vboxsync $ */
2/** @file
3 * MS COM / XPCOM Abstraction Layer - Smart string classes declaration.
4 */
5
6/*
7 * Copyright (C) 2006-2020 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 cleanupAndCopyFrom((const OLECHAR *)that.m_bstr);
152 return *this;
153 }
154
155 Bstr &operator=(CBSTR that)
156 {
157 cleanupAndCopyFrom((const OLECHAR *)that);
158 return *this;
159 }
160
161#if defined(VBOX_WITH_XPCOM)
162 Bstr &operator=(const wchar_t *that)
163 {
164 cleanupAndCopyFrom((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 /**
301 * Assigns the output of the string format operation (RTStrPrintf).
302 *
303 * @param pszFormat Pointer to the format string,
304 * @see pg_rt_str_format.
305 * @param ... Ellipsis containing the arguments specified by
306 * the format string.
307 *
308 * @throws std::bad_alloc On allocation error. Object state is undefined.
309 *
310 * @returns Reference to the object.
311 */
312 Bstr &printf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
313
314 /**
315 * Assigns the output of the string format operation (RTStrPrintf).
316 *
317 * @param pszFormat Pointer to the format string,
318 * @see pg_rt_str_format.
319 * @param ... Ellipsis containing the arguments specified by
320 * the format string.
321 *
322 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
323 */
324 HRESULT printfNoThrow(const char *pszFormat, ...) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 2);
325
326 /**
327 * Assigns the output of the string format operation (RTStrPrintfV).
328 *
329 * @param pszFormat Pointer to the format string,
330 * @see pg_rt_str_format.
331 * @param va Argument vector containing the arguments
332 * specified by the format string.
333 *
334 * @throws std::bad_alloc On allocation error. Object state is undefined.
335 *
336 * @returns Reference to the object.
337 */
338 Bstr &printfV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
339
340 /**
341 * Assigns the output of the string format operation (RTStrPrintfV).
342 *
343 * @param pszFormat Pointer to the format string,
344 * @see pg_rt_str_format.
345 * @param va Argument vector containing the arguments
346 * specified by the format string.
347 *
348 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
349 */
350 HRESULT printfVNoThrow(const char *pszFormat, va_list va) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 0);
351
352 /** @name Append methods and operators
353 * @{ */
354
355 /**
356 * Appends the string @a that to @a rThat.
357 *
358 * @param rThat The string to append.
359 * @throws std::bad_alloc On allocation error. The object is left unchanged.
360 * @returns Reference to the object.
361 */
362 Bstr &append(const Bstr &rThat);
363
364 /**
365 * Appends the string @a that to @a rThat.
366 *
367 * @param rThat The string to append.
368 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
369 */
370 HRESULT appendNoThrow(const Bstr &rThat) RT_NOEXCEPT;
371
372 /**
373 * Appends the UTF-8 string @a that to @a rThat.
374 *
375 * @param rThat The string to append.
376 * @throws std::bad_alloc On allocation error. The object is left unchanged.
377 * @returns Reference to the object.
378 */
379 Bstr &append(const RTCString &rThat);
380
381 /**
382 * Appends the UTF-8 string @a that to @a rThat.
383 *
384 * @param rThat The string to append.
385 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
386 */
387 HRESULT appendNoThrow(const RTCString &rThat) RT_NOEXCEPT;
388
389 /**
390 * Appends the UTF-16 string @a pszSrc to @a this.
391 *
392 * @param pwszSrc The C-style UTF-16 string to append.
393 * @throws std::bad_alloc On allocation error. The object is left unchanged.
394 * @returns Reference to the object.
395 */
396 Bstr &append(CBSTR pwszSrc);
397
398 /**
399 * Appends the UTF-16 string @a pszSrc to @a this.
400 *
401 * @param pwszSrc The C-style UTF-16 string to append.
402 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
403 */
404 HRESULT appendNoThrow(CBSTR pwszSrc) RT_NOEXCEPT;
405
406 /**
407 * Appends the UTF-8 string @a pszSrc to @a this.
408 *
409 * @param pszSrc The C-style string to append.
410 * @throws std::bad_alloc On allocation error. The object is left unchanged.
411 * @returns Reference to the object.
412 */
413 Bstr &append(const char *pszSrc);
414
415 /**
416 * Appends the UTF-8 string @a pszSrc to @a this.
417 *
418 * @param pszSrc The C-style string to append.
419 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
420 */
421 HRESULT appendNoThrow(const char *pszSrc) RT_NOEXCEPT;
422
423 /**
424 * Appends the a substring from @a rThat to @a this.
425 *
426 * @param rThat The string to append a substring from.
427 * @param offStart The start of the substring to append (UTF-16
428 * offset, not codepoint).
429 * @param cwcMax The maximum number of UTF-16 units to append.
430 * @throws std::bad_alloc On allocation error. The object is left unchanged.
431 * @returns Reference to the object.
432 */
433 Bstr &append(const Bstr &rThat, size_t offStart, size_t cwcMax = RTSTR_MAX);
434
435 /**
436 * Appends the a substring from @a rThat to @a this.
437 *
438 * @param rThat The string to append a substring from.
439 * @param offStart The start of the substring to append (UTF-16
440 * offset, not codepoint).
441 * @param cwcMax The maximum number of UTF-16 units to append.
442 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
443 */
444 HRESULT appendNoThrow(const Bstr &rThat, size_t offStart, size_t cwcMax = RTSTR_MAX) RT_NOEXCEPT;
445
446 /**
447 * Appends the a substring from UTF-8 @a rThat to @a this.
448 *
449 * @param rThat The string to append a substring from.
450 * @param offStart The start of the substring to append (byte offset,
451 * not codepoint).
452 * @param cchMax The maximum number of bytes to append.
453 * @throws std::bad_alloc On allocation error. The object is left unchanged.
454 * @returns Reference to the object.
455 */
456 Bstr &append(const RTCString &rThat, size_t offStart, size_t cchMax = RTSTR_MAX);
457
458 /**
459 * Appends the a substring from UTF-8 @a rThat to @a this.
460 *
461 * @param rThat The string to append a substring from.
462 * @param offStart The start of the substring to append (byte offset,
463 * not codepoint).
464 * @param cchMax The maximum number of bytes to append.
465 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
466 */
467 HRESULT appendNoThrow(const RTCString &rThat, size_t offStart, size_t cchMax = RTSTR_MAX) RT_NOEXCEPT;
468
469 /**
470 * Appends the first @a cchMax chars from UTF-16 string @a pszThat to @a this.
471 *
472 * @param pwszThat The C-style UTF-16 string to append.
473 * @param cchMax The maximum number of bytes to append.
474 * @throws std::bad_alloc On allocation error. The object is left unchanged.
475 * @returns Reference to the object.
476 */
477 Bstr &append(CBSTR pwszThat, size_t cchMax);
478
479 /**
480 * Appends the first @a cchMax chars from UTF-16 string @a pszThat to @a this.
481 *
482 * @param pwszThat The C-style UTF-16 string to append.
483 * @param cchMax The maximum number of bytes to append.
484 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
485 */
486 HRESULT appendNoThrow(CBSTR pwszThat, size_t cchMax) RT_NOEXCEPT;
487
488 /**
489 * Appends the first @a cchMax chars from string @a pszThat to @a this.
490 *
491 * @param pszThat The C-style string to append.
492 * @param cchMax The maximum number of bytes 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(const char *pszThat, size_t cchMax);
497
498 /**
499 * Appends the first @a cchMax chars from string @a pszThat to @a this.
500 *
501 * @param pszThat The C-style string to append.
502 * @param cchMax The maximum number of bytes to append.
503 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
504 */
505 HRESULT appendNoThrow(const char *pszThat, size_t cchMax) RT_NOEXCEPT;
506
507 /**
508 * Appends the given character to @a this.
509 *
510 * @param ch The character to append.
511 * @throws std::bad_alloc On allocation error. The object is left unchanged.
512 * @returns Reference to the object.
513 */
514 Bstr &append(char ch);
515
516 /**
517 * Appends the given character to @a this.
518 *
519 * @param ch The character to append.
520 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
521 */
522 HRESULT appendNoThrow(char ch) RT_NOEXCEPT;
523
524 /**
525 * Appends the given unicode code point to @a this.
526 *
527 * @param uc The unicode code point to append.
528 * @throws std::bad_alloc On allocation error. The object is left unchanged.
529 * @returns Reference to the object.
530 */
531 Bstr &appendCodePoint(RTUNICP uc);
532
533 /**
534 * Appends the given unicode code point to @a this.
535 *
536 * @param uc The unicode code point to append.
537 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
538 */
539 HRESULT appendCodePointNoThrow(RTUNICP uc) RT_NOEXCEPT;
540
541 /**
542 * Appends the output of the string format operation (RTStrPrintf).
543 *
544 * @param pszFormat Pointer to the format string,
545 * @see pg_rt_str_format.
546 * @param ... Ellipsis containing the arguments specified by
547 * the format string.
548 *
549 * @throws std::bad_alloc On allocation error. Object state is undefined.
550 *
551 * @returns Reference to the object.
552 */
553 Bstr &appendPrintf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
554
555 /**
556 * Appends the output of the string format operation (RTStrPrintf).
557 *
558 * @param pszFormat Pointer to the format string,
559 * @see pg_rt_str_format.
560 * @param ... Ellipsis containing the arguments specified by
561 * the format string.
562 *
563 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
564 */
565 HRESULT appendPrintfNoThrow(const char *pszFormat, ...) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 2);
566
567 /**
568 * Appends the output of the string format operation (RTStrPrintfV).
569 *
570 * @param pszFormat Pointer to the format string,
571 * @see pg_rt_str_format.
572 * @param va Argument vector containing the arguments
573 * specified by the format string.
574 *
575 * @throws std::bad_alloc On allocation error. Object state is undefined.
576 *
577 * @returns Reference to the object.
578 */
579 Bstr &appendPrintfV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
580
581 /**
582 * Appends the output of the string format operation (RTStrPrintfV).
583 *
584 * @param pszFormat Pointer to the format string,
585 * @see pg_rt_str_format.
586 * @param va Argument vector containing the arguments
587 * specified by the format string.
588 *
589 * @returns S_OK, E_OUTOFMEMORY or E_INVAL (bad encoding).
590 */
591 HRESULT appendPrintfVNoThrow(const char *pszFormat, va_list va) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 0);
592
593 /**
594 * Shortcut to append(), Bstr variant.
595 *
596 * @param rThat The string to append.
597 * @returns Reference to the object.
598 */
599 Bstr &operator+=(const Bstr &rThat)
600 {
601 return append(rThat);
602 }
603
604 /**
605 * Shortcut to append(), RTCString variant.
606 *
607 * @param rThat The string to append.
608 * @returns Reference to the object.
609 */
610 Bstr &operator+=(const RTCString &rThat)
611 {
612 return append(rThat);
613 }
614
615 /**
616 * Shortcut to append(), CBSTR variant.
617 *
618 * @param pwszThat The C-style string to append.
619 * @returns Reference to the object.
620 */
621 Bstr &operator+=(CBSTR pwszThat)
622 {
623 return append(pwszThat);
624 }
625
626 /**
627 * Shortcut to append(), const char * variant.
628 *
629 * @param pszThat The C-style string to append.
630 * @returns Reference to the object.
631 */
632 Bstr &operator+=(const char *pszThat)
633 {
634 return append(pszThat);
635 }
636
637 /**
638 * Shortcut to append(), char variant.
639 *
640 * @param ch The character to append.
641 *
642 * @returns Reference to the object.
643 */
644 Bstr &operator+=(char ch)
645 {
646 return append(ch);
647 }
648
649 /** @} */
650
651 /**
652 * Erases a sequence from the string.
653 *
654 * @returns Reference to the object.
655 * @param offStart Where in @a this string to start erasing (UTF-16
656 * units, not codepoints).
657 * @param cwcLength How much following @a offStart to erase (UTF-16
658 * units, not codepoints).
659 */
660 Bstr &erase(size_t offStart = 0, size_t cwcLength = RTSTR_MAX) RT_NOEXCEPT;
661
662
663 /** @name BASE64 related methods
664 * @{ */
665 /**
666 * Encodes the given data as BASE64.
667 *
668 * @returns S_OK or E_OUTOFMEMORY.
669 * @param pvData Pointer to the data to encode.
670 * @param cbData Number of bytes to encode.
671 * @param fLineBreaks Whether to add line breaks (true) or just encode it
672 * as a continuous string.
673 * @sa RTBase64EncodeUtf16
674 */
675 HRESULT base64Encode(const void *pvData, size_t cbData, bool fLineBreaks = false);
676
677 /**
678 * Decodes the string as BASE64.
679 *
680 * @returns IPRT status code, see RTBase64DecodeUtf16Ex.
681 * @param pvData Where to return the decoded bytes.
682 * @param cbData Size of the @a pvData return buffer.
683 * @param pcbActual Where to return number of bytes actually decoded.
684 * This is optional and if not specified, the request
685 * will fail unless @a cbData matches the data size
686 * exactly.
687 * @param ppwszEnd Where to return pointer to the first non-base64
688 * character following the encoded data. This is
689 * optional and if NULL, the request will fail if there
690 * are anything trailing the encoded bytes in the
691 * string.
692 * @sa base64DecodedSize, RTBase64DecodeUtf16
693 */
694 int base64Decode(void *pvData, size_t cbData, size_t *pcbActual = NULL, PRTUTF16 *ppwszEnd = NULL);
695
696 /**
697 * Determins the size of the BASE64 encoded data in the string.
698 *
699 * @returns The length in bytes. -1 if the encoding is bad.
700 *
701 * @param ppwszEnd If not NULL, this will point to the first char
702 * following the Base64 encoded text block. If
703 * NULL the entire string is assumed to be Base64.
704 * @sa base64Decode, RTBase64DecodedUtf16Size
705 */
706 ssize_t base64DecodedSize(PRTUTF16 *ppwszEnd = NULL);
707 /** @} */
708
709#if defined(VBOX_WITH_XPCOM)
710 /**
711 * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
712 * returns a pointer to a global variable containing an empty BSTR with a proper zero
713 * length prefix so that Windows is happy.
714 */
715 CBSTR raw() const
716 {
717 if (m_bstr)
718 return m_bstr;
719
720 return g_bstrEmpty;
721 }
722#else
723 /**
724 * Windows-only hack, as the automatically generated headers use BSTR.
725 * So if we don't want to cast like crazy we have to be more loose than
726 * on XPCOM.
727 *
728 * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
729 * returns a pointer to a global variable containing an empty BSTR with a proper zero
730 * length prefix so that Windows is happy.
731 */
732 BSTR raw() const
733 {
734 if (m_bstr)
735 return m_bstr;
736
737 return g_bstrEmpty;
738 }
739#endif
740
741 /**
742 * Returns a non-const raw pointer that allows modifying the string directly.
743 *
744 * @note As opposed to raw(), this DOES return NULL if the member string is
745 * empty because we cannot return a mutable pointer to the global variable
746 * with the empty string.
747 *
748 * @note If modifying the string size (only shrinking it is allows), #jolt() or
749 * #joltNoThrow() must be called!
750 *
751 * @note Do not modify memory beyond the #length() of the string!
752 *
753 * @sa joltNoThrow(), mutalbleRaw(), reserve(), reserveNoThrow()
754 */
755 BSTR mutableRaw() { return m_bstr; }
756
757 /**
758 * Correct the embedded length after using mutableRaw().
759 *
760 * This is needed on COM (Windows) to update the embedded string length. It is
761 * a stub on hosts using XPCOM.
762 *
763 * @param cwcNew The new string length, if handy, otherwise a negative
764 * number.
765 * @sa joltNoThrow(), mutalbleRaw(), reserve(), reserveNoThrow()
766 */
767#ifndef VBOX_WITH_XPCOM
768 void jolt(ssize_t cwcNew = -1);
769#else
770 void jolt(ssize_t cwcNew = -1)
771 {
772 Assert(cwcNew < 0 || (cwcNew == 0 && !m_bstr) || m_bstr[cwcNew] == '\0'); RT_NOREF(cwcNew);
773 }
774#endif
775
776 /**
777 * Correct the embedded length after using mutableRaw().
778 *
779 * This is needed on COM (Windows) to update the embedded string length. It is
780 * a stub on hosts using XPCOM.
781 *
782 * @returns S_OK on success, E_OUTOFMEMORY if shrinking the string failed.
783 * @param cwcNew The new string length, if handy, otherwise a negative
784 * number.
785 * @sa jolt(), mutalbleRaw(), reserve(), reserveNoThrow()
786 */
787#ifndef VBOX_WITH_XPCOM
788 HRESULT joltNoThrow(ssize_t cwcNew = -1) RT_NOEXCEPT;
789#else
790 HRESULT joltNoThrow(ssize_t cwcNew = -1) RT_NOEXCEPT
791 {
792 Assert(cwcNew < 0 || (cwcNew == 0 && !m_bstr) || m_bstr[cwcNew] == '\0'); RT_NOREF(cwcNew);
793 return S_OK;
794 }
795#endif
796
797 /**
798 * Make sure at that least @a cwc of buffer space is reserved.
799 *
800 * Requests that the contained memory buffer have at least cb bytes allocated.
801 * This may expand or shrink the string's storage, but will never truncate the
802 * contained string. In other words, cb will be ignored if it's smaller than
803 * length() + 1.
804 *
805 * @param cwcMin The new minimum string length that the can be stored. This
806 * does not include the terminator.
807 * @param fForce Force this size.
808 *
809 * @throws std::bad_alloc On allocation error. The object is left unchanged.
810 */
811 void reserve(size_t cwcMin, bool fForce = false);
812
813 /**
814 * A C like version of the #reserve() method, i.e. return code instead of throw.
815 *
816 * @returns S_OK or E_OUTOFMEMORY.
817 * @param cwcMin The new minimum string length that the can be stored. This
818 * does not include the terminator.
819 * @param fForce Force this size.
820 */
821 HRESULT reserveNoThrow(size_t cwcMin, bool fForce = false) RT_NOEXCEPT;
822
823 /**
824 * Intended to assign copies of instances to |BSTR| out parameters from
825 * within the interface method. Transfers the ownership of the duplicated
826 * string to the caller.
827 *
828 * If the member string is empty, this allocates an empty BSTR in *pstr
829 * (i.e. makes it point to a new buffer with a null byte).
830 *
831 * @deprecated Use cloneToEx instead to avoid throwing exceptions.
832 */
833 void cloneTo(BSTR *pstr) const
834 {
835 if (pstr)
836 {
837 *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty
838#ifdef RT_EXCEPTIONS_ENABLED
839 if (!*pstr)
840 throw std::bad_alloc();
841#endif
842 }
843 }
844
845 /**
846 * A version of cloneTo that does not throw any out of memory exceptions, but
847 * returns E_OUTOFMEMORY intead.
848 * @returns S_OK or E_OUTOFMEMORY.
849 */
850 HRESULT cloneToEx(BSTR *pstr) const
851 {
852 if (!pstr)
853 return S_OK;
854 *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty
855 return pstr ? S_OK : E_OUTOFMEMORY;
856 }
857
858 /**
859 * Intended to assign instances to |BSTR| out parameters from within the
860 * interface method. Transfers the ownership of the original string to the
861 * caller and resets the instance to null.
862 *
863 * As opposed to cloneTo(), this method doesn't create a copy of the
864 * string.
865 *
866 * If the member string is empty, this allocates an empty BSTR in *pstr
867 * (i.e. makes it point to a new buffer with a null byte).
868 *
869 * @param pbstrDst The BSTR variable to detach the string to.
870 *
871 * @throws std::bad_alloc if we failed to allocate a new empty string.
872 */
873 void detachTo(BSTR *pbstrDst)
874 {
875 if (m_bstr)
876 {
877 *pbstrDst = m_bstr;
878 m_bstr = NULL;
879 }
880 else
881 {
882 // allocate null BSTR
883 *pbstrDst = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
884#ifdef RT_EXCEPTIONS_ENABLED
885 if (!*pbstrDst)
886 throw std::bad_alloc();
887#endif
888 }
889 }
890
891 /**
892 * A version of detachTo that does not throw exceptions on out-of-memory
893 * conditions, but instead returns E_OUTOFMEMORY.
894 *
895 * @param pbstrDst The BSTR variable to detach the string to.
896 * @returns S_OK or E_OUTOFMEMORY.
897 */
898 HRESULT detachToEx(BSTR *pbstrDst)
899 {
900 if (m_bstr)
901 {
902 *pbstrDst = m_bstr;
903 m_bstr = NULL;
904 }
905 else
906 {
907 // allocate null BSTR
908 *pbstrDst = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
909 if (!*pbstrDst)
910 return E_OUTOFMEMORY;
911 }
912 return S_OK;
913 }
914
915 /**
916 * Intended to pass instances as |BSTR| out parameters to methods.
917 * Takes the ownership of the returned data.
918 */
919 BSTR *asOutParam()
920 {
921 cleanup();
922 return &m_bstr;
923 }
924
925 /**
926 * Static immutable empty-string object. May be used for comparison purposes.
927 */
928 static const Bstr Empty;
929
930protected:
931
932 void cleanup();
933
934 /**
935 * Protected internal helper to copy a string. This ignores the previous object
936 * state, so either call this from a constructor or call cleanup() first.
937 *
938 * This variant copies from a zero-terminated UTF-16 string (which need not
939 * be a BSTR, i.e. need not have a length prefix).
940 *
941 * If the source is empty, this sets the member string to NULL.
942 *
943 * @param a_bstrSrc The source string. The caller guarantees
944 * that this is valid UTF-16.
945 *
946 * @throws std::bad_alloc - the object is representing an empty string.
947 */
948 void copyFrom(const OLECHAR *a_bstrSrc);
949
950 /** cleanup() + copyFrom() - for assignment operators. */
951 void cleanupAndCopyFrom(const OLECHAR *a_bstrSrc);
952
953 /**
954 * Protected internal helper to copy a string. This ignores the previous object
955 * state, so either call this from a constructor or call cleanup() first.
956 *
957 * This variant copies and converts from a zero-terminated UTF-8 string.
958 *
959 * If the source is empty, this sets the member string to NULL.
960 *
961 * @param a_pszSrc The source string. The caller guarantees
962 * that this is valid UTF-8.
963 *
964 * @throws std::bad_alloc - the object is representing an empty string.
965 */
966 void copyFrom(const char *a_pszSrc)
967 {
968 copyFromN(a_pszSrc, RTSTR_MAX);
969 }
970
971 /**
972 * Variant of copyFrom for sub-string constructors.
973 *
974 * @param a_pszSrc The source string. The caller guarantees
975 * that this is valid UTF-8.
976 * @param a_cchSrc The maximum number of chars (not codepoints) to
977 * copy. If you pass RTSTR_MAX it'll be exactly
978 * like copyFrom().
979 *
980 * @throws std::bad_alloc - the object is representing an empty string.
981 */
982 void copyFromN(const char *a_pszSrc, size_t a_cchSrc);
983
984 Bstr &appendWorkerUtf16(PCRTUTF16 pwszSrc, size_t cwcSrc);
985 Bstr &appendWorkerUtf8(const char *pszSrc, size_t cchSrc);
986 HRESULT appendWorkerUtf16NoThrow(PCRTUTF16 pwszSrc, size_t cwcSrc) RT_NOEXCEPT;
987 HRESULT appendWorkerUtf8NoThrow(const char *pszSrc, size_t cchSrc) RT_NOEXCEPT;
988
989 static DECLCALLBACK(size_t) printfOutputCallbackNoThrow(void *pvArg, const char *pachChars, size_t cbChars) RT_NOEXCEPT;
990
991 BSTR m_bstr;
992
993 friend class Utf8Str; /* to access our raw_copy() */
994};
995
996/* symmetric compare operators */
997inline bool operator==(CBSTR l, const Bstr &r) { return r.operator==(l); }
998inline bool operator!=(CBSTR l, const Bstr &r) { return r.operator!=(l); }
999inline bool operator==(BSTR l, const Bstr &r) { return r.operator==(l); }
1000inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!=(l); }
1001
1002
1003
1004
1005/**
1006 * String class used universally in Main for UTF-8 strings.
1007 *
1008 * This is based on RTCString, to which some functionality has been
1009 * moved. Here we keep things that are specific to Main, such as conversions
1010 * with UTF-16 strings (Bstr).
1011 *
1012 * Like RTCString, Utf8Str does not differentiate between NULL strings
1013 * and empty strings. In other words, Utf8Str("") and Utf8Str(NULL) behave the
1014 * same. In both cases, RTCString allocates no memory, reports
1015 * a zero length and zero allocated bytes for both, and returns an empty
1016 * C string from c_str().
1017 *
1018 * @note All Utf8Str methods ASSUMES valid UTF-8 or UTF-16 input strings.
1019 * The VirtualBox policy in this regard is to validate strings coming
1020 * from external sources before passing them to Utf8Str or Bstr.
1021 */
1022class Utf8Str : public RTCString
1023{
1024public:
1025
1026 Utf8Str() {}
1027
1028 Utf8Str(const RTCString &that)
1029 : RTCString(that)
1030 {}
1031
1032 Utf8Str(const char *that)
1033 : RTCString(that)
1034 {}
1035
1036 Utf8Str(const Bstr &that)
1037 {
1038 copyFrom(that.raw());
1039 }
1040
1041 Utf8Str(CBSTR that, size_t a_cwcSize = RTSTR_MAX)
1042 {
1043 copyFrom(that, a_cwcSize);
1044 }
1045
1046 Utf8Str(const char *a_pszSrc, size_t a_cchSrc)
1047 : RTCString(a_pszSrc, a_cchSrc)
1048 {
1049 }
1050
1051 /**
1052 * Constructs a new string given the format string and the list of the
1053 * arguments for the format string.
1054 *
1055 * @param a_pszFormat Pointer to the format string (UTF-8),
1056 * @see pg_rt_str_format.
1057 * @param a_va Argument vector containing the arguments
1058 * specified by the format string.
1059 * @sa RTCString::printfV
1060 */
1061 Utf8Str(const char *a_pszFormat, va_list a_va) RT_IPRT_FORMAT_ATTR(1, 0)
1062 : RTCString(a_pszFormat, a_va)
1063 {
1064 }
1065
1066 Utf8Str& operator=(const RTCString &that)
1067 {
1068 RTCString::operator=(that);
1069 return *this;
1070 }
1071
1072 Utf8Str& operator=(const char *that)
1073 {
1074 RTCString::operator=(that);
1075 return *this;
1076 }
1077
1078 Utf8Str& operator=(const Bstr &that)
1079 {
1080 cleanup();
1081 copyFrom(that.raw());
1082 return *this;
1083 }
1084
1085 Utf8Str& operator=(CBSTR that)
1086 {
1087 cleanup();
1088 copyFrom(that);
1089 return *this;
1090 }
1091
1092 /**
1093 * Extended assignment method that returns a COM status code instead of an
1094 * exception on failure.
1095 *
1096 * @returns S_OK or E_OUTOFMEMORY.
1097 * @param a_rSrcStr The source string
1098 */
1099 HRESULT assignEx(Utf8Str const &a_rSrcStr)
1100 {
1101 return copyFromExNComRC(a_rSrcStr.m_psz, 0, a_rSrcStr.m_cch);
1102 }
1103
1104 /**
1105 * Extended assignment method that returns a COM status code instead of an
1106 * exception on failure.
1107 *
1108 * @returns S_OK, E_OUTOFMEMORY or E_INVALIDARG.
1109 * @param a_rSrcStr The source string
1110 * @param a_offSrc The character (byte) offset of the substring.
1111 * @param a_cchSrc The number of characters (bytes) to copy from the source
1112 * string.
1113 */
1114 HRESULT assignEx(Utf8Str const &a_rSrcStr, size_t a_offSrc, size_t a_cchSrc)
1115 {
1116 if ( a_offSrc + a_cchSrc > a_rSrcStr.m_cch
1117 || a_offSrc > a_rSrcStr.m_cch)
1118 return E_INVALIDARG;
1119 return copyFromExNComRC(a_rSrcStr.m_psz, a_offSrc, a_cchSrc);
1120 }
1121
1122 /**
1123 * Extended assignment method that returns a COM status code instead of an
1124 * exception on failure.
1125 *
1126 * @returns S_OK or E_OUTOFMEMORY.
1127 * @param a_pcszSrc The source string
1128 */
1129 HRESULT assignEx(const char *a_pcszSrc)
1130 {
1131 return copyFromExNComRC(a_pcszSrc, 0, a_pcszSrc ? strlen(a_pcszSrc) : 0);
1132 }
1133
1134 /**
1135 * Extended assignment method that returns a COM status code instead of an
1136 * exception on failure.
1137 *
1138 * @returns S_OK or E_OUTOFMEMORY.
1139 * @param a_pcszSrc The source string
1140 * @param a_cchSrc The number of characters (bytes) to copy from the source
1141 * string.
1142 */
1143 HRESULT assignEx(const char *a_pcszSrc, size_t a_cchSrc)
1144 {
1145 return copyFromExNComRC(a_pcszSrc, 0, a_cchSrc);
1146 }
1147
1148 RTMEMEF_NEW_AND_DELETE_OPERATORS();
1149
1150#if defined(VBOX_WITH_XPCOM)
1151 /**
1152 * Intended to assign instances to |char *| out parameters from within the
1153 * interface method. Transfers the ownership of the duplicated string to the
1154 * caller.
1155 *
1156 * This allocates a single 0 byte in the target if the member string is empty.
1157 *
1158 * This uses XPCOM memory allocation and thus only works on XPCOM. MSCOM doesn't
1159 * like char* strings anyway.
1160 */
1161 void cloneTo(char **pstr) const;
1162
1163 /**
1164 * A version of cloneTo that does not throw allocation errors but returns
1165 * E_OUTOFMEMORY instead.
1166 * @returns S_OK or E_OUTOFMEMORY (COM status codes).
1167 */
1168 HRESULT cloneToEx(char **pstr) const;
1169#endif
1170
1171 /**
1172 * Intended to assign instances to |BSTR| out parameters from within the
1173 * interface method. Transfers the ownership of the duplicated string to the
1174 * caller.
1175 */
1176 void cloneTo(BSTR *pstr) const
1177 {
1178 if (pstr)
1179 {
1180 Bstr bstr(*this);
1181 bstr.cloneTo(pstr);
1182 }
1183 }
1184
1185 /**
1186 * A version of cloneTo that does not throw allocation errors but returns
1187 * E_OUTOFMEMORY instead.
1188 *
1189 * @param pbstr Where to store a clone of the string.
1190 * @returns S_OK or E_OUTOFMEMORY (COM status codes).
1191 */
1192 HRESULT cloneToEx(BSTR *pbstr) const
1193 {
1194 if (!pbstr)
1195 return S_OK;
1196 Bstr bstr(*this);
1197 return bstr.detachToEx(pbstr);
1198 }
1199
1200 /**
1201 * Safe assignment from BSTR.
1202 *
1203 * @param pbstrSrc The source string.
1204 * @returns S_OK or E_OUTOFMEMORY (COM status codes).
1205 */
1206 HRESULT cloneEx(CBSTR pbstrSrc)
1207 {
1208 cleanup();
1209 return copyFromEx(pbstrSrc);
1210 }
1211
1212 /**
1213 * Removes a trailing slash from the member string, if present.
1214 * Calls RTPathStripTrailingSlash() without having to mess with mutableRaw().
1215 */
1216 Utf8Str& stripTrailingSlash();
1217
1218 /**
1219 * Removes a trailing filename from the member string, if present.
1220 * Calls RTPathStripFilename() without having to mess with mutableRaw().
1221 */
1222 Utf8Str& stripFilename();
1223
1224 /**
1225 * Removes the path component from the member string, if present.
1226 * Calls RTPathFilename() without having to mess with mutableRaw().
1227 */
1228 Utf8Str& stripPath();
1229
1230 /**
1231 * Removes a trailing file name suffix from the member string, if present.
1232 * Calls RTPathStripSuffix() without having to mess with mutableRaw().
1233 */
1234 Utf8Str& stripSuffix();
1235
1236 /**
1237 * Parses key=value pairs.
1238 *
1239 * @returns offset of the @a a_rPairSeparator following the returned value.
1240 * @retval npos is returned if there are no more key/value pairs.
1241 *
1242 * @param a_rKey Reference to variable that should receive
1243 * the key substring. This is set to null if
1244 * no key/value found. (It's also possible the
1245 * key is an empty string, so be careful.)
1246 * @param a_rValue Reference to variable that should receive
1247 * the value substring. This is set to null if
1248 * no key/value found. (It's also possible the
1249 * value is an empty string, so be careful.)
1250 * @param a_offStart The offset to start searching from. This is
1251 * typically 0 for the first call, and the
1252 * return value of the previous call for the
1253 * subsequent ones.
1254 * @param a_rPairSeparator The pair separator string. If this is an
1255 * empty string, the whole string will be
1256 * considered as a single key/value pair.
1257 * @param a_rKeyValueSeparator The key/value separator string.
1258 */
1259 size_t parseKeyValue(Utf8Str &a_rKey, Utf8Str &a_rValue, size_t a_offStart = 0,
1260 const Utf8Str &a_rPairSeparator = ",", const Utf8Str &a_rKeyValueSeparator = "=") const;
1261
1262 /**
1263 * Static immutable empty-string object. May be used for comparison purposes.
1264 */
1265 static const Utf8Str Empty;
1266protected:
1267
1268 void copyFrom(CBSTR a_pbstr, size_t a_cwcMax = RTSTR_MAX);
1269 HRESULT copyFromEx(CBSTR a_pbstr);
1270 HRESULT copyFromExNComRC(const char *a_pcszSrc, size_t a_offSrc, size_t a_cchSrc);
1271
1272 friend class Bstr; /* to access our raw_copy() */
1273};
1274
1275/**
1276 * Class with RTCString::printf as constructor for your convenience.
1277 *
1278 * Constructing a Utf8Str string object from a format string and a variable
1279 * number of arguments can easily be confused with the other Utf8Str
1280 * constructures, thus this child class.
1281 *
1282 * The usage of this class is like the following:
1283 * @code
1284 Utf8StrFmt strName("program name = %s", argv[0]);
1285 @endcode
1286 */
1287class Utf8StrFmt : public Utf8Str
1288{
1289public:
1290
1291 /**
1292 * Constructs a new string given the format string and the list of the
1293 * arguments for the format string.
1294 *
1295 * @param a_pszFormat Pointer to the format string (UTF-8),
1296 * @see pg_rt_str_format.
1297 * @param ... Ellipsis containing the arguments specified by
1298 * the format string.
1299 */
1300 explicit Utf8StrFmt(const char *a_pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2)
1301 {
1302 va_list va;
1303 va_start(va, a_pszFormat);
1304 printfV(a_pszFormat, va);
1305 va_end(va);
1306 }
1307
1308 RTMEMEF_NEW_AND_DELETE_OPERATORS();
1309
1310protected:
1311 Utf8StrFmt()
1312 { }
1313
1314private:
1315};
1316
1317/**
1318 * Class with Bstr::printf as constructor for your convenience.
1319 */
1320class BstrFmt : public Bstr
1321{
1322public:
1323
1324 /**
1325 * Constructs a new string given the format string and the list of the
1326 * arguments for the format string.
1327 *
1328 * @param a_pszFormat printf-like format string (in UTF-8 encoding), see
1329 * iprt/string.h for details.
1330 * @param ... List of the arguments for the format string.
1331 */
1332 explicit BstrFmt(const char *a_pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2)
1333 {
1334 va_list va;
1335 va_start(va, a_pszFormat);
1336 printfV(a_pszFormat, va);
1337 va_end(va);
1338 }
1339
1340 RTMEMEF_NEW_AND_DELETE_OPERATORS();
1341
1342protected:
1343 BstrFmt()
1344 { }
1345};
1346
1347/**
1348 * Class with Bstr::printfV as constructor for your convenience.
1349 */
1350class BstrFmtVA : public Bstr
1351{
1352public:
1353
1354 /**
1355 * Constructs a new string given the format string and the list of the
1356 * arguments for the format string.
1357 *
1358 * @param a_pszFormat printf-like format string (in UTF-8 encoding), see
1359 * iprt/string.h for details.
1360 * @param a_va List of arguments for the format string
1361 */
1362 BstrFmtVA(const char *a_pszFormat, va_list a_va) RT_IPRT_FORMAT_ATTR(1, 0)
1363 {
1364 printfV(a_pszFormat, a_va);
1365 }
1366
1367 RTMEMEF_NEW_AND_DELETE_OPERATORS();
1368
1369protected:
1370 BstrFmtVA()
1371 { }
1372};
1373
1374} /* namespace com */
1375
1376/** @} */
1377
1378#endif /* !VBOX_INCLUDED_com_string_h */
1379
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette