VirtualBox

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

最後變更 在這個檔案從84339是 84339,由 vboxsync 提交於 5 年 前

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. bugref:9224

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 46.7 KB
 
1/* $Id: string.h 84339 2020-05-18 17:35:01Z 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.alldomusa.eu.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 pwszString The Base64 encoded UTF-16 string.
702 * @param ppwszEnd If not NULL, this will point to the first char
703 * following the Base64 encoded text block. If
704 * NULL the entire string is assumed to be Base64.
705 * @sa base64Decode, RTBase64DecodedUtf16Size
706 */
707 ssize_t base64DecodedSize(PRTUTF16 *ppwszEnd = NULL);
708 /** @} */
709
710#if defined(VBOX_WITH_XPCOM)
711 /**
712 * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
713 * returns a pointer to a global variable containing an empty BSTR with a proper zero
714 * length prefix so that Windows is happy.
715 */
716 CBSTR raw() const
717 {
718 if (m_bstr)
719 return m_bstr;
720
721 return g_bstrEmpty;
722 }
723#else
724 /**
725 * Windows-only hack, as the automatically generated headers use BSTR.
726 * So if we don't want to cast like crazy we have to be more loose than
727 * on XPCOM.
728 *
729 * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
730 * returns a pointer to a global variable containing an empty BSTR with a proper zero
731 * length prefix so that Windows is happy.
732 */
733 BSTR raw() const
734 {
735 if (m_bstr)
736 return m_bstr;
737
738 return g_bstrEmpty;
739 }
740#endif
741
742 /**
743 * Returns a non-const raw pointer that allows modifying the string directly.
744 *
745 * @note As opposed to raw(), this DOES return NULL if the member string is
746 * empty because we cannot return a mutable pointer to the global variable
747 * with the empty string.
748 *
749 * @note If modifying the string size (only shrinking it is allows), #jolt() or
750 * #joltNoThrow() must be called!
751 *
752 * @note Do not modify memory beyond the #length() of the string!
753 *
754 * @sa joltNoThrow(), mutalbleRaw(), reserve(), reserveNoThrow()
755 */
756 BSTR mutableRaw() { return m_bstr; }
757
758 /**
759 * Correct the embedded length after using mutableRaw().
760 *
761 * This is needed on COM (Windows) to update the embedded string length. It is
762 * a stub on hosts using XPCOM.
763 *
764 * @param cwcNew The new string length, if handy, otherwise a negative
765 * number.
766 * @sa joltNoThrow(), mutalbleRaw(), reserve(), reserveNoThrow()
767 */
768#ifndef VBOX_WITH_XPCOM
769 void jolt(ssize_t cwcNew = -1);
770#else
771 void jolt(ssize_t cwcNew = -1)
772 {
773 Assert(cwcNew < 0 || (cwcNew == 0 && !m_bstr) || m_bstr[cwcNew] == '\0'); RT_NOREF(cwcNew);
774 }
775#endif
776
777 /**
778 * Correct the embedded length after using mutableRaw().
779 *
780 * This is needed on COM (Windows) to update the embedded string length. It is
781 * a stub on hosts using XPCOM.
782 *
783 * @returns S_OK on success, E_OUTOFMEMORY if shrinking the string failed.
784 * @param cwcNew The new string length, if handy, otherwise a negative
785 * number.
786 * @sa jolt(), mutalbleRaw(), reserve(), reserveNoThrow()
787 */
788#ifndef VBOX_WITH_XPCOM
789 HRESULT joltNoThrow(ssize_t cwcNew = -1) RT_NOEXCEPT;
790#else
791 HRESULT joltNoThrow(ssize_t cwcNew = -1) RT_NOEXCEPT
792 {
793 Assert(cwcNew < 0 || (cwcNew == 0 && !m_bstr) || m_bstr[cwcNew] == '\0'); RT_NOREF(cwcNew);
794 return S_OK;
795 }
796#endif
797
798 /**
799 * Make sure at that least @a cwc of buffer space is reserved.
800 *
801 * Requests that the contained memory buffer have at least cb bytes allocated.
802 * This may expand or shrink the string's storage, but will never truncate the
803 * contained string. In other words, cb will be ignored if it's smaller than
804 * length() + 1.
805 *
806 * @param cwcMin The new minimum string length that the can be stored. This
807 * does not include the terminator.
808 * @param fForce Force this size.
809 *
810 * @throws std::bad_alloc On allocation error. The object is left unchanged.
811 */
812 void reserve(size_t cwcMin, bool fForce = false);
813
814 /**
815 * A C like version of the #reserve() method, i.e. return code instead of throw.
816 *
817 * @returns S_OK or E_OUTOFMEMORY.
818 * @param cwcMin The new minimum string length that the can be stored. This
819 * does not include the terminator.
820 * @param fForce Force this size.
821 */
822 HRESULT reserveNoThrow(size_t cwcMin, bool fForce = false) RT_NOEXCEPT;
823
824 /**
825 * Intended to assign copies of instances to |BSTR| out parameters from
826 * within the interface method. Transfers the ownership of the duplicated
827 * string to the caller.
828 *
829 * If the member string is empty, this allocates an empty BSTR in *pstr
830 * (i.e. makes it point to a new buffer with a null byte).
831 *
832 * @deprecated Use cloneToEx instead to avoid throwing exceptions.
833 */
834 void cloneTo(BSTR *pstr) const
835 {
836 if (pstr)
837 {
838 *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty
839#ifdef RT_EXCEPTIONS_ENABLED
840 if (!*pstr)
841 throw std::bad_alloc();
842#endif
843 }
844 }
845
846 /**
847 * A version of cloneTo that does not throw any out of memory exceptions, but
848 * returns E_OUTOFMEMORY intead.
849 * @returns S_OK or E_OUTOFMEMORY.
850 */
851 HRESULT cloneToEx(BSTR *pstr) const
852 {
853 if (!pstr)
854 return S_OK;
855 *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty
856 return pstr ? S_OK : E_OUTOFMEMORY;
857 }
858
859 /**
860 * Intended to assign instances to |BSTR| out parameters from within the
861 * interface method. Transfers the ownership of the original string to the
862 * caller and resets the instance to null.
863 *
864 * As opposed to cloneTo(), this method doesn't create a copy of the
865 * string.
866 *
867 * If the member string is empty, this allocates an empty BSTR in *pstr
868 * (i.e. makes it point to a new buffer with a null byte).
869 *
870 * @param pbstrDst The BSTR variable to detach the string to.
871 *
872 * @throws std::bad_alloc if we failed to allocate a new empty string.
873 */
874 void detachTo(BSTR *pbstrDst)
875 {
876 if (m_bstr)
877 {
878 *pbstrDst = m_bstr;
879 m_bstr = NULL;
880 }
881 else
882 {
883 // allocate null BSTR
884 *pbstrDst = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
885#ifdef RT_EXCEPTIONS_ENABLED
886 if (!*pbstrDst)
887 throw std::bad_alloc();
888#endif
889 }
890 }
891
892 /**
893 * A version of detachTo that does not throw exceptions on out-of-memory
894 * conditions, but instead returns E_OUTOFMEMORY.
895 *
896 * @param pbstrDst The BSTR variable to detach the string to.
897 * @returns S_OK or E_OUTOFMEMORY.
898 */
899 HRESULT detachToEx(BSTR *pbstrDst)
900 {
901 if (m_bstr)
902 {
903 *pbstrDst = m_bstr;
904 m_bstr = NULL;
905 }
906 else
907 {
908 // allocate null BSTR
909 *pbstrDst = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
910 if (!*pbstrDst)
911 return E_OUTOFMEMORY;
912 }
913 return S_OK;
914 }
915
916 /**
917 * Intended to pass instances as |BSTR| out parameters to methods.
918 * Takes the ownership of the returned data.
919 */
920 BSTR *asOutParam()
921 {
922 cleanup();
923 return &m_bstr;
924 }
925
926 /**
927 * Static immutable empty-string object. May be used for comparison purposes.
928 */
929 static const Bstr Empty;
930
931protected:
932
933 void cleanup();
934
935 /**
936 * Protected internal helper to copy a string. This ignores the previous object
937 * state, so either call this from a constructor or call cleanup() first.
938 *
939 * This variant copies from a zero-terminated UTF-16 string (which need not
940 * be a BSTR, i.e. need not have a length prefix).
941 *
942 * If the source is empty, this sets the member string to NULL.
943 *
944 * @param a_bstrSrc The source string. The caller guarantees
945 * that this is valid UTF-16.
946 *
947 * @throws std::bad_alloc - the object is representing an empty string.
948 */
949 void copyFrom(const OLECHAR *a_bstrSrc);
950
951 /** cleanup() + copyFrom() - for assignment operators. */
952 void cleanupAndCopyFrom(const OLECHAR *a_bstrSrc);
953
954 /**
955 * Protected internal helper to copy a string. This ignores the previous object
956 * state, so either call this from a constructor or call cleanup() first.
957 *
958 * This variant copies and converts from a zero-terminated UTF-8 string.
959 *
960 * If the source is empty, this sets the member string to NULL.
961 *
962 * @param a_pszSrc The source string. The caller guarantees
963 * that this is valid UTF-8.
964 *
965 * @throws std::bad_alloc - the object is representing an empty string.
966 */
967 void copyFrom(const char *a_pszSrc)
968 {
969 copyFromN(a_pszSrc, RTSTR_MAX);
970 }
971
972 /**
973 * Variant of copyFrom for sub-string constructors.
974 *
975 * @param a_pszSrc The source string. The caller guarantees
976 * that this is valid UTF-8.
977 * @param a_cchSrc The maximum number of chars (not codepoints) to
978 * copy. If you pass RTSTR_MAX it'll be exactly
979 * like copyFrom().
980 *
981 * @throws std::bad_alloc - the object is representing an empty string.
982 */
983 void copyFromN(const char *a_pszSrc, size_t a_cchSrc);
984
985 Bstr &appendWorkerUtf16(PCRTUTF16 pwszSrc, size_t cwcSrc);
986 Bstr &appendWorkerUtf8(const char *pszSrc, size_t cchSrc);
987 HRESULT appendWorkerUtf16NoThrow(PCRTUTF16 pwszSrc, size_t cwcSrc) RT_NOEXCEPT;
988 HRESULT appendWorkerUtf8NoThrow(const char *pszSrc, size_t cchSrc) RT_NOEXCEPT;
989
990 static DECLCALLBACK(size_t) printfOutputCallbackNoThrow(void *pvArg, const char *pachChars, size_t cbChars) RT_NOEXCEPT;
991
992 BSTR m_bstr;
993
994 friend class Utf8Str; /* to access our raw_copy() */
995};
996
997/* symmetric compare operators */
998inline bool operator==(CBSTR l, const Bstr &r) { return r.operator==(l); }
999inline bool operator!=(CBSTR l, const Bstr &r) { return r.operator!=(l); }
1000inline bool operator==(BSTR l, const Bstr &r) { return r.operator==(l); }
1001inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!=(l); }
1002
1003
1004
1005
1006/**
1007 * String class used universally in Main for UTF-8 strings.
1008 *
1009 * This is based on RTCString, to which some functionality has been
1010 * moved. Here we keep things that are specific to Main, such as conversions
1011 * with UTF-16 strings (Bstr).
1012 *
1013 * Like RTCString, Utf8Str does not differentiate between NULL strings
1014 * and empty strings. In other words, Utf8Str("") and Utf8Str(NULL) behave the
1015 * same. In both cases, RTCString allocates no memory, reports
1016 * a zero length and zero allocated bytes for both, and returns an empty
1017 * C string from c_str().
1018 *
1019 * @note All Utf8Str methods ASSUMES valid UTF-8 or UTF-16 input strings.
1020 * The VirtualBox policy in this regard is to validate strings coming
1021 * from external sources before passing them to Utf8Str or Bstr.
1022 */
1023class Utf8Str : public RTCString
1024{
1025public:
1026
1027 Utf8Str() {}
1028
1029 Utf8Str(const RTCString &that)
1030 : RTCString(that)
1031 {}
1032
1033 Utf8Str(const char *that)
1034 : RTCString(that)
1035 {}
1036
1037 Utf8Str(const Bstr &that)
1038 {
1039 copyFrom(that.raw());
1040 }
1041
1042 Utf8Str(CBSTR that, size_t a_cwcSize = RTSTR_MAX)
1043 {
1044 copyFrom(that, a_cwcSize);
1045 }
1046
1047 Utf8Str(const char *a_pszSrc, size_t a_cchSrc)
1048 : RTCString(a_pszSrc, a_cchSrc)
1049 {
1050 }
1051
1052 /**
1053 * Constructs a new string given the format string and the list of the
1054 * arguments for the format string.
1055 *
1056 * @param a_pszFormat Pointer to the format string (UTF-8),
1057 * @see pg_rt_str_format.
1058 * @param a_va Argument vector containing the arguments
1059 * specified by the format string.
1060 * @sa RTCString::printfV
1061 */
1062 Utf8Str(const char *a_pszFormat, va_list a_va) RT_IPRT_FORMAT_ATTR(1, 0)
1063 : RTCString(a_pszFormat, a_va)
1064 {
1065 }
1066
1067 Utf8Str& operator=(const RTCString &that)
1068 {
1069 RTCString::operator=(that);
1070 return *this;
1071 }
1072
1073 Utf8Str& operator=(const char *that)
1074 {
1075 RTCString::operator=(that);
1076 return *this;
1077 }
1078
1079 Utf8Str& operator=(const Bstr &that)
1080 {
1081 cleanup();
1082 copyFrom(that.raw());
1083 return *this;
1084 }
1085
1086 Utf8Str& operator=(CBSTR that)
1087 {
1088 cleanup();
1089 copyFrom(that);
1090 return *this;
1091 }
1092
1093 /**
1094 * Extended assignment method that returns a COM status code instead of an
1095 * exception on failure.
1096 *
1097 * @returns S_OK or E_OUTOFMEMORY.
1098 * @param a_rSrcStr The source string
1099 */
1100 HRESULT assignEx(Utf8Str const &a_rSrcStr)
1101 {
1102 return copyFromExNComRC(a_rSrcStr.m_psz, 0, a_rSrcStr.m_cch);
1103 }
1104
1105 /**
1106 * Extended assignment method that returns a COM status code instead of an
1107 * exception on failure.
1108 *
1109 * @returns S_OK, E_OUTOFMEMORY or E_INVALIDARG.
1110 * @param a_rSrcStr The source string
1111 * @param a_offSrc The character (byte) offset of the substring.
1112 * @param a_cchSrc The number of characters (bytes) to copy from the source
1113 * string.
1114 */
1115 HRESULT assignEx(Utf8Str const &a_rSrcStr, size_t a_offSrc, size_t a_cchSrc)
1116 {
1117 if ( a_offSrc + a_cchSrc > a_rSrcStr.m_cch
1118 || a_offSrc > a_rSrcStr.m_cch)
1119 return E_INVALIDARG;
1120 return copyFromExNComRC(a_rSrcStr.m_psz, a_offSrc, a_cchSrc);
1121 }
1122
1123 /**
1124 * Extended assignment method that returns a COM status code instead of an
1125 * exception on failure.
1126 *
1127 * @returns S_OK or E_OUTOFMEMORY.
1128 * @param a_pcszSrc The source string
1129 */
1130 HRESULT assignEx(const char *a_pcszSrc)
1131 {
1132 return copyFromExNComRC(a_pcszSrc, 0, a_pcszSrc ? strlen(a_pcszSrc) : 0);
1133 }
1134
1135 /**
1136 * Extended assignment method that returns a COM status code instead of an
1137 * exception on failure.
1138 *
1139 * @returns S_OK or E_OUTOFMEMORY.
1140 * @param a_pcszSrc The source string
1141 * @param a_cchSrc The number of characters (bytes) to copy from the source
1142 * string.
1143 */
1144 HRESULT assignEx(const char *a_pcszSrc, size_t a_cchSrc)
1145 {
1146 return copyFromExNComRC(a_pcszSrc, 0, a_cchSrc);
1147 }
1148
1149 RTMEMEF_NEW_AND_DELETE_OPERATORS();
1150
1151#if defined(VBOX_WITH_XPCOM)
1152 /**
1153 * Intended to assign instances to |char *| out parameters from within the
1154 * interface method. Transfers the ownership of the duplicated string to the
1155 * caller.
1156 *
1157 * This allocates a single 0 byte in the target if the member string is empty.
1158 *
1159 * This uses XPCOM memory allocation and thus only works on XPCOM. MSCOM doesn't
1160 * like char* strings anyway.
1161 */
1162 void cloneTo(char **pstr) const;
1163
1164 /**
1165 * A version of cloneTo that does not throw allocation errors but returns
1166 * E_OUTOFMEMORY instead.
1167 * @returns S_OK or E_OUTOFMEMORY (COM status codes).
1168 */
1169 HRESULT cloneToEx(char **pstr) const;
1170#endif
1171
1172 /**
1173 * Intended to assign instances to |BSTR| out parameters from within the
1174 * interface method. Transfers the ownership of the duplicated string to the
1175 * caller.
1176 */
1177 void cloneTo(BSTR *pstr) const
1178 {
1179 if (pstr)
1180 {
1181 Bstr bstr(*this);
1182 bstr.cloneTo(pstr);
1183 }
1184 }
1185
1186 /**
1187 * A version of cloneTo that does not throw allocation errors but returns
1188 * E_OUTOFMEMORY instead.
1189 *
1190 * @param pbstr Where to store a clone of the string.
1191 * @returns S_OK or E_OUTOFMEMORY (COM status codes).
1192 */
1193 HRESULT cloneToEx(BSTR *pbstr) const
1194 {
1195 if (!pbstr)
1196 return S_OK;
1197 Bstr bstr(*this);
1198 return bstr.detachToEx(pbstr);
1199 }
1200
1201 /**
1202 * Safe assignment from BSTR.
1203 *
1204 * @param pbstrSrc The source string.
1205 * @returns S_OK or E_OUTOFMEMORY (COM status codes).
1206 */
1207 HRESULT cloneEx(CBSTR pbstrSrc)
1208 {
1209 cleanup();
1210 return copyFromEx(pbstrSrc);
1211 }
1212
1213 /**
1214 * Removes a trailing slash from the member string, if present.
1215 * Calls RTPathStripTrailingSlash() without having to mess with mutableRaw().
1216 */
1217 Utf8Str& stripTrailingSlash();
1218
1219 /**
1220 * Removes a trailing filename from the member string, if present.
1221 * Calls RTPathStripFilename() without having to mess with mutableRaw().
1222 */
1223 Utf8Str& stripFilename();
1224
1225 /**
1226 * Removes the path component from the member string, if present.
1227 * Calls RTPathFilename() without having to mess with mutableRaw().
1228 */
1229 Utf8Str& stripPath();
1230
1231 /**
1232 * Removes a trailing file name suffix from the member string, if present.
1233 * Calls RTPathStripSuffix() without having to mess with mutableRaw().
1234 */
1235 Utf8Str& stripSuffix();
1236
1237 /**
1238 * Parses key=value pairs.
1239 *
1240 * @returns offset of the @a a_rPairSeparator following the returned value.
1241 * @retval npos is returned if there are no more key/value pairs.
1242 *
1243 * @param a_rKey Reference to variable that should receive
1244 * the key substring. This is set to null if
1245 * no key/value found. (It's also possible the
1246 * key is an empty string, so be careful.)
1247 * @param a_rValue Reference to variable that should receive
1248 * the value substring. This is set to null if
1249 * no key/value found. (It's also possible the
1250 * value is an empty string, so be careful.)
1251 * @param a_offStart The offset to start searching from. This is
1252 * typically 0 for the first call, and the
1253 * return value of the previous call for the
1254 * subsequent ones.
1255 * @param a_rPairSeparator The pair separator string. If this is an
1256 * empty string, the whole string will be
1257 * considered as a single key/value pair.
1258 * @param a_rKeyValueSeparator The key/value separator string.
1259 */
1260 size_t parseKeyValue(Utf8Str &a_rKey, Utf8Str &a_rValue, size_t a_offStart = 0,
1261 const Utf8Str &a_rPairSeparator = ",", const Utf8Str &a_rKeyValueSeparator = "=") const;
1262
1263 /**
1264 * Static immutable empty-string object. May be used for comparison purposes.
1265 */
1266 static const Utf8Str Empty;
1267protected:
1268
1269 void copyFrom(CBSTR a_pbstr, size_t a_cwcMax = RTSTR_MAX);
1270 HRESULT copyFromEx(CBSTR a_pbstr);
1271 HRESULT copyFromExNComRC(const char *a_pcszSrc, size_t a_offSrc, size_t a_cchSrc);
1272
1273 friend class Bstr; /* to access our raw_copy() */
1274};
1275
1276/**
1277 * Class with RTCString::printf as constructor for your convenience.
1278 *
1279 * Constructing a Utf8Str string object from a format string and a variable
1280 * number of arguments can easily be confused with the other Utf8Str
1281 * constructures, thus this child class.
1282 *
1283 * The usage of this class is like the following:
1284 * @code
1285 Utf8StrFmt strName("program name = %s", argv[0]);
1286 @endcode
1287 */
1288class Utf8StrFmt : public Utf8Str
1289{
1290public:
1291
1292 /**
1293 * Constructs a new string given the format string and the list of the
1294 * arguments for the format string.
1295 *
1296 * @param a_pszFormat Pointer to the format string (UTF-8),
1297 * @see pg_rt_str_format.
1298 * @param ... Ellipsis containing the arguments specified by
1299 * the format string.
1300 */
1301 explicit Utf8StrFmt(const char *a_pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2)
1302 {
1303 va_list va;
1304 va_start(va, a_pszFormat);
1305 printfV(a_pszFormat, va);
1306 va_end(va);
1307 }
1308
1309 RTMEMEF_NEW_AND_DELETE_OPERATORS();
1310
1311protected:
1312 Utf8StrFmt()
1313 { }
1314
1315private:
1316};
1317
1318/**
1319 * Class with Bstr::printf as constructor for your convenience.
1320 */
1321class BstrFmt : public Bstr
1322{
1323public:
1324
1325 /**
1326 * Constructs a new string given the format string and the list of the
1327 * arguments for the format string.
1328 *
1329 * @param a_pszFormat printf-like format string (in UTF-8 encoding), see
1330 * iprt/string.h for details.
1331 * @param ... List of the arguments for the format string.
1332 */
1333 explicit BstrFmt(const char *a_pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2)
1334 {
1335 va_list va;
1336 va_start(va, a_pszFormat);
1337 printfV(a_pszFormat, va);
1338 va_end(va);
1339 }
1340
1341 RTMEMEF_NEW_AND_DELETE_OPERATORS();
1342
1343protected:
1344 BstrFmt()
1345 { }
1346};
1347
1348/**
1349 * Class with Bstr::printfV as constructor for your convenience.
1350 */
1351class BstrFmtVA : public Bstr
1352{
1353public:
1354
1355 /**
1356 * Constructs a new string given the format string and the list of the
1357 * arguments for the format string.
1358 *
1359 * @param a_pszFormat printf-like format string (in UTF-8 encoding), see
1360 * iprt/string.h for details.
1361 * @param a_va List of arguments for the format string
1362 */
1363 BstrFmtVA(const char *a_pszFormat, va_list a_va) RT_IPRT_FORMAT_ATTR(1, 0)
1364 {
1365 printfV(a_pszFormat, a_va);
1366 }
1367
1368 RTMEMEF_NEW_AND_DELETE_OPERATORS();
1369
1370protected:
1371 BstrFmtVA()
1372 { }
1373};
1374
1375} /* namespace com */
1376
1377/** @} */
1378
1379#endif /* !VBOX_INCLUDED_com_string_h */
1380
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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