VirtualBox

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

Last change on this file since 93115 was 93115, checked in by vboxsync, 2 years ago

scm --update-copyright-year

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

© 2023 Oracle
ContactPrivacy policyTerms of Use