VirtualBox

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

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

Bstr: Added printf, printfNoThrow, printfV and printfVNoThrow methods (untested).

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

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