VirtualBox

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

Last change on this file since 18529 was 18529, checked in by vboxsync, 16 years ago

Main: added toLower, toUpper & contains

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.4 KB
Line 
1/* $Id: string.h 18529 2009-03-30 11:54:06Z vboxsync $ */
2
3/** @file
4 * MS COM / XPCOM Abstraction Layer:
5 * Smart string classes declaration
6 */
7
8/*
9 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * The contents of this file may alternatively be used under the terms
20 * of the Common Development and Distribution License Version 1.0
21 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
22 * VirtualBox OSE distribution, in which case the provisions of the
23 * CDDL are applicable instead of those of the GPL.
24 *
25 * You may elect to license modified versions of this file under the
26 * terms and conditions of either the GPL or the CDDL or both.
27 *
28 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
29 * Clara, CA 95054 USA or visit http://www.sun.com if you need
30 * additional information or have any questions.
31 */
32
33#ifndef ___VBox_com_string_h
34#define ___VBox_com_string_h
35
36/* Make sure all the stdint.h macros are included - must come first! */
37#ifndef __STDC_LIMIT_MACROS
38# define __STDC_LIMIT_MACROS
39#endif
40#ifndef __STDC_CONSTANT_MACROS
41# define __STDC_CONSTANT_MACROS
42#endif
43
44#if defined (VBOX_WITH_XPCOM)
45# include <nsMemory.h>
46#endif
47
48#include "VBox/com/defs.h"
49#include "VBox/com/assert.h"
50
51#include <iprt/string.h>
52#include <iprt/cpputils.h>
53#include <iprt/alloc.h>
54
55namespace com
56{
57
58class Utf8Str;
59
60/**
61 * Helper class that represents the |BSTR| type and hides platform-specific
62 * implementation details.
63 *
64 * This class uses COM/XPCOM-provided memory management routines to allocate
65 * and free string buffers. This makes it possible to:
66 * - use it as a type of member variables of COM/XPCOM components and pass
67 * their values to callers through component methods' output parameters
68 * using the #cloneTo() operation;
69 * - adopt (take ownership of) string buffers returned in output parameters
70 * of COM methods using the #asOutParam() operation and correctly free them
71 * afterwards.
72 */
73class Bstr
74{
75public:
76
77 typedef BSTR String;
78 typedef CBSTR ConstString;
79
80 Bstr () : bstr (NULL) {}
81
82 Bstr (const Bstr &that) : bstr (NULL) { raw_copy (bstr, that.bstr); }
83 Bstr (CBSTR that) : bstr (NULL) { raw_copy (bstr, that); }
84
85#if defined (VBOX_WITH_XPCOM)
86 Bstr (const wchar_t *that) : bstr (NULL)
87 {
88 AssertCompile (sizeof (wchar_t) == sizeof (OLECHAR));
89 raw_copy (bstr, (CBSTR) that);
90 }
91#endif
92
93 Bstr (const Utf8Str &that);
94 Bstr (const char *that);
95
96 /** Shortcut that calls #alloc(aSize) right after object creation. */
97 Bstr (size_t aSize) : bstr (NULL) { alloc (aSize); }
98
99 ~Bstr () { setNull(); }
100
101 Bstr &operator = (const Bstr &that) { safe_assign (that.bstr); return *this; }
102 Bstr &operator = (CBSTR that) { safe_assign (that); return *this; }
103
104 Bstr &operator = (const Utf8Str &that);
105 Bstr &operator = (const char *that);
106
107 Bstr &setNull()
108 {
109 if (bstr)
110 {
111 ::SysFreeString (bstr);
112 bstr = NULL;
113 }
114 return *this;
115 }
116
117 Bstr &setNullIfEmpty()
118 {
119 if (bstr && *bstr == 0)
120 {
121 ::SysFreeString (bstr);
122 bstr = NULL;
123 }
124 return *this;
125 }
126
127 /**
128 * Allocates memory for a string capable to store \a aSize - 1 characters;
129 * in other words, aSize includes the terminating zero character. If \a aSize
130 * is zero, or if a memory allocation error occurs, this object will become null.
131 */
132 Bstr &alloc (size_t aSize)
133 {
134 setNull();
135 if (aSize)
136 {
137 unsigned int size = (unsigned int) aSize; Assert (size == aSize);
138 bstr = ::SysAllocStringLen (NULL, size - 1);
139 if (bstr)
140 bstr [0] = 0;
141 }
142 return *this;
143 }
144
145 int compare (CBSTR str) const
146 {
147 return ::RTUtf16Cmp ((PRTUTF16) bstr, (PRTUTF16) str);
148 }
149
150 int compare (BSTR str) const
151 {
152 return ::RTUtf16Cmp ((PRTUTF16) bstr, (PRTUTF16) str);
153 }
154
155 bool operator == (const Bstr &that) const { return !compare (that.bstr); }
156 bool operator != (const Bstr &that) const { return !!compare (that.bstr); }
157 bool operator == (CBSTR that) const { return !compare (that); }
158 bool operator == (BSTR that) const { return !compare (that); }
159
160#if defined (VBOX_WITH_XPCOM)
161 bool operator != (const wchar_t *that) const
162 {
163 AssertCompile (sizeof (wchar_t) == sizeof (OLECHAR));
164 return !!compare ((CBSTR) that);
165 }
166 bool operator == (const wchar_t *that) const
167 {
168 AssertCompile (sizeof (wchar_t) == sizeof (OLECHAR));
169 return !compare ((CBSTR) that);
170 }
171#endif
172
173 bool operator != (CBSTR that) const { return !!compare (that); }
174 bool operator != (BSTR that) const { return !!compare (that); }
175 bool operator < (const Bstr &that) const { return compare (that.bstr) < 0; }
176 bool operator < (CBSTR that) const { return compare (that) < 0; }
177 bool operator < (BSTR that) const { return compare (that) < 0; }
178#if defined (VBOX_WITH_XPCOM)
179 bool operator < (const wchar_t *that) const
180 {
181 AssertCompile (sizeof (wchar_t) == sizeof (OLECHAR));
182 return compare ((CBSTR) that) < 0;
183 }
184#endif
185
186 int compareIgnoreCase (CBSTR str) const
187 {
188 return ::RTUtf16LocaleICmp (bstr, str);
189 }
190
191 bool isNull() const { return bstr == NULL; }
192 operator bool() const { return !isNull(); }
193
194 bool isEmpty() const { return isNull() || *bstr == 0; }
195
196 size_t length() const { return isNull() ? 0 : ::RTUtf16Len ((PRTUTF16) bstr); }
197
198 /** Intended to to pass instances as |CBSTR| input parameters to methods. */
199 operator CBSTR () const { return bstr; }
200
201 /**
202 * Intended to to pass instances as |BSTR| input parameters to methods.
203 * Note that we have to provide this mutable BSTR operator since in MS COM
204 * input BSTR parameters of interface methods are not const.
205 */
206 operator BSTR () { return bstr; }
207
208 /**
209 * The same as operator CBSTR(), but for situations where the compiler
210 * cannot typecast implicitly (for example, in printf() argument list).
211 */
212 CBSTR raw() const { return bstr; }
213
214 /**
215 * Returns a non-const raw pointer that allows to modify the string directly.
216 * @warning
217 * Be sure not to modify data beyond the allocated memory! The
218 * guaranteed size of the allocated memory is at least #length()
219 * bytes after creation and after every assignment operation.
220 */
221 BSTR mutableRaw() { return bstr; }
222
223 /**
224 * Intended to assign copies of instances to |BSTR| out parameters from
225 * within the interface method. Transfers the ownership of the duplicated
226 * string to the caller.
227 */
228 const Bstr &cloneTo (BSTR *pstr) const
229 {
230 if (pstr)
231 {
232 *pstr = NULL;
233 raw_copy (*pstr, bstr);
234 }
235 return *this;
236 }
237
238 /**
239 * Intended to assign instances to |BSTR| out parameters from within the
240 * interface method. Transfers the ownership of the original string to the
241 * caller and resets the instance to null.
242 *
243 * As opposed to cloneTo(), this method doesn't create a copy of the
244 * string.
245 */
246 Bstr &detachTo (BSTR *pstr)
247 {
248 *pstr = bstr;
249 bstr = NULL;
250 return *this;
251 }
252
253 /**
254 * Intended to assign copies of instances to |char *| out parameters from
255 * within the interface method. Transfers the ownership of the duplicated
256 * string to the caller.
257 */
258 const Bstr &cloneTo (char **pstr) const;
259
260 /**
261 * Intended to pass instances as |BSTR| out parameters to methods.
262 * Takes the ownership of the returned data.
263 */
264 BSTR *asOutParam() { setNull(); return &bstr; }
265
266 /**
267 * Static immutable null object. May be used for comparison purposes.
268 */
269 static const Bstr Null;
270
271protected:
272
273 void safe_assign (CBSTR str)
274 {
275 if (bstr != str)
276 {
277 setNull();
278 raw_copy (bstr, str);
279 }
280 }
281
282 inline static void raw_copy (BSTR &ls, CBSTR rs)
283 {
284 if (rs)
285 ls = ::SysAllocString ((const OLECHAR *) rs);
286 }
287
288 inline static void raw_copy (BSTR &ls, const char *rs)
289 {
290 if (rs)
291 {
292 PRTUTF16 s = NULL;
293 ::RTStrToUtf16 (rs, &s);
294 raw_copy (ls, (BSTR) s);
295 ::RTUtf16Free (s);
296 }
297 }
298
299 BSTR bstr;
300
301 friend class Utf8Str; /* to access our raw_copy() */
302};
303
304/* symmetric compare operators */
305inline bool operator== (CBSTR l, const Bstr &r) { return r.operator== (l); }
306inline bool operator!= (CBSTR l, const Bstr &r) { return r.operator!= (l); }
307inline bool operator== (BSTR l, const Bstr &r) { return r.operator== (l); }
308inline bool operator!= (BSTR l, const Bstr &r) { return r.operator!= (l); }
309
310////////////////////////////////////////////////////////////////////////////////
311
312/**
313 * Helper class that represents UTF8 (|char *|) strings. Useful in
314 * conjunction with Bstr to simplify conversions between UTF16 (|BSTR|)
315 * and UTF8.
316 *
317 * This class uses COM/XPCOM-provided memory management routines to allocate
318 * and free string buffers. This makes it possible to:
319 * - use it as a type of member variables of COM/XPCOM components and pass
320 * their values to callers through component methods' output parameters
321 * using the #cloneTo() operation;
322 * - adopt (take ownership of) string buffers returned in output parameters
323 * of COM methods using the #asOutParam() operation and correctly free them
324 * afterwards.
325 */
326class Utf8Str
327{
328public:
329
330 enum CaseSensitivity
331 {
332 CaseSensitive,
333 CaseInsensitive
334 };
335
336 typedef char *String;
337 typedef const char *ConstString;
338
339 Utf8Str () : str (NULL) {}
340
341 Utf8Str (const Utf8Str &that) : str (NULL) { raw_copy (str, that.str); }
342 Utf8Str (const char *that) : str (NULL) { raw_copy (str, that); }
343
344 Utf8Str (const Bstr &that) : str (NULL) { raw_copy (str, that); }
345 Utf8Str (CBSTR that) : str (NULL) { raw_copy (str, that); }
346
347 /** Shortcut that calls #alloc(aSize) right after object creation. */
348 Utf8Str (size_t aSize) : str (NULL) { alloc(aSize); }
349
350 virtual ~Utf8Str () { setNull(); }
351
352 Utf8Str &operator = (const Utf8Str &that) { safe_assign (that.str); return *this; }
353 Utf8Str &operator = (const char *that) { safe_assign (that); return *this; }
354
355 Utf8Str &operator = (const Bstr &that)
356 {
357 setNull();
358 raw_copy (str, that);
359 return *this;
360 }
361 Utf8Str &operator = (CBSTR that)
362 {
363 setNull();
364 raw_copy (str, that);
365 return *this;
366 }
367
368 Utf8Str &setNull()
369 {
370 if (str)
371 {
372#if !defined (VBOX_WITH_XPCOM)
373 ::RTStrFree (str);
374#else
375 nsMemory::Free (str);
376#endif
377 str = NULL;
378 }
379 return *this;
380 }
381
382 Utf8Str &setNullIfEmpty()
383 {
384 if (str && *str == 0)
385 {
386#if !defined (VBOX_WITH_XPCOM)
387 ::RTStrFree (str);
388#else
389 nsMemory::Free (str);
390#endif
391 str = NULL;
392 }
393 return *this;
394 }
395
396 /**
397 * Allocates memory for a string capable to store \a aSize - 1 bytes (not characters!);
398 * in other words, aSize includes the terminating zero character. If \a aSize
399 * is zero, or if a memory allocation error occurs, this object will become null.
400 */
401 Utf8Str &alloc (size_t aSize)
402 {
403 setNull();
404 if (aSize)
405 {
406#if !defined (VBOX_WITH_XPCOM)
407 str = (char *) ::RTMemTmpAlloc (aSize);
408#else
409 str = (char *) nsMemory::Alloc (aSize);
410#endif
411 if (str)
412 str [0] = 0;
413 }
414 return *this;
415 }
416
417 void append(const Utf8Str &that)
418 {
419 size_t cbThis = length();
420 size_t cbThat = that.length();
421
422 if (cbThat)
423 {
424 size_t cbBoth = cbThis + cbThat + 1;
425
426 // @todo optimize with realloc() once the memory management is fixed
427 char *pszTemp;
428#if !defined (VBOX_WITH_XPCOM)
429 pszTemp = (char*)::RTMemTmpAlloc(cbBoth);
430#else
431 pszTemp = (char*)nsMemory::Alloc(cbBoth);
432#endif
433 if (str)
434 {
435 memcpy(pszTemp, str, cbThis);
436 setNull();
437 }
438 if (that.str)
439 memcpy(pszTemp + cbThis, that.str, cbThat);
440 pszTemp[cbThis + cbThat] = '\0';
441
442 str = pszTemp;
443 }
444 }
445
446 int compare (const char *pcsz, CaseSensitivity cs = CaseSensitive) const
447 {
448 if (str == pcsz)
449 return 0;
450 if (str == NULL)
451 return -1;
452 if (pcsz == NULL)
453 return 1;
454
455 if (cs == CaseSensitive)
456 return ::RTStrCmp(str, pcsz);
457 else
458 return ::RTStrICmp(str, pcsz);
459 }
460
461 int compare (const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const
462 {
463 return compare (that.str, cs);
464 }
465
466 bool operator == (const Utf8Str &that) const { return !compare (that); }
467 bool operator != (const Utf8Str &that) const { return !!compare (that); }
468 bool operator == (const char *that) const { return !compare (that); }
469 bool operator != (const char *that) const { return !!compare (that); }
470 bool operator < (const Utf8Str &that) const { return compare (that) < 0; }
471 bool operator < (const char *that) const { return compare (that) < 0; }
472
473 bool endsWith (const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const
474 {
475 if (isNull() || that.isNull())
476 return false;
477
478 size_t l1 = length();
479 size_t l2 = that.length();
480 if (l1 < l2)
481 return false;
482
483 size_t l = l1 - l2;
484 if (cs == CaseSensitive)
485 return ::RTStrCmp(&str[l], that.str) == 0;
486 else
487 return ::RTStrICmp(&str[l], that.str) == 0;
488 }
489
490 bool startsWith (const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const
491 {
492 if (isNull() || that.isNull())
493 return false;
494
495 size_t l1 = length();
496 size_t l2 = that.length();
497 if (l1 < l2)
498 return false;
499
500 if (cs == CaseSensitive)
501 return ::RTStrNCmp(str, that.str, l2) == 0;
502 else
503 return ::RTStrNICmp(str, that.str, l2) == 0;
504 }
505
506 bool contains (const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const
507 {
508 if (isNull() || that.isNull())
509 return false;
510
511 char *pszString = ::RTStrDup(str);
512 char *pszTmp;
513
514 /* Create the generic pattern */
515 ::RTStrAPrintf(&pszTmp, "*%s*", that.str);
516 /* We have to duplicate the strings as long as there is no case
517 * insensitive version of RTStrSimplePatternMatch. */
518 if (cs == CaseInsensitive)
519 {
520 pszTmp = ::RTStrToLower(pszTmp);
521 pszString = ::RTStrToLower(pszString);
522 }
523 bool fResult = ::RTStrSimplePatternMatch(pszTmp, pszString);
524 RTStrFree(pszTmp);
525 RTStrFree(pszString);
526
527 return fResult;
528 }
529
530 Utf8Str& toLower()
531 {
532 if (isEmpty())
533 return *this;
534
535 ::RTStrToLower(str);
536
537 return *this;
538 }
539
540 Utf8Str& toUpper()
541 {
542 if (isEmpty())
543 return *this;
544
545 ::RTStrToUpper(str);
546
547 return *this;
548 }
549
550 bool isNull() const { return str == NULL; }
551 operator bool() const { return !isNull(); }
552
553 bool isEmpty() const { return isNull() || *str == 0; }
554
555 size_t length() const { return isNull() ? 0 : ::strlen (str); }
556
557 /** Intended to to pass instances as input (|char *|) parameters to methods. */
558 operator const char *() const { return str; }
559
560 /** The same as operator const char *(), but for situations where the compiler
561 cannot typecast implicitly (for example, in printf() argument list). */
562 const char *raw() const { return str; }
563
564 /** The same as operator const char *(), but for situations where the compiler
565 cannot typecast implicitly (for example, in printf() argument list). */
566 const char *c_str() const { return str; }
567
568 /**
569 * Returns a non-const raw pointer that allows to modify the string directly.
570 * @warning
571 * Be sure not to modify data beyond the allocated memory! The
572 * guaranteed size of the allocated memory is at least #length()
573 * bytes after creation and after every assignment operation.
574 */
575 char *mutableRaw() { return str; }
576
577 /**
578 * Intended to assign instances to |char *| out parameters from within the
579 * interface method. Transfers the ownership of the duplicated string to the
580 * caller.
581 */
582 const Utf8Str &cloneTo (char **pstr) const
583 {
584 if (pstr)
585 {
586 *pstr = NULL;
587 raw_copy (*pstr, str);
588 }
589 return *this;
590 }
591
592 /**
593 * Intended to assign instances to |char *| out parameters from within the
594 * interface method. Transfers the ownership of the original string to the
595 * caller and resets the instance to null.
596 *
597 * As opposed to cloneTo(), this method doesn't create a copy of the
598 * string.
599 */
600 Utf8Str &detachTo (char **pstr)
601 {
602 *pstr = str;
603 str = NULL;
604 return *this;
605 }
606
607 /**
608 * Intended to assign instances to |BSTR| out parameters from within the
609 * interface method. Transfers the ownership of the duplicated string to the
610 * caller.
611 */
612 const Utf8Str &cloneTo (BSTR *pstr) const
613 {
614 if (pstr)
615 {
616 *pstr = NULL;
617 Bstr::raw_copy (*pstr, str);
618 }
619 return *this;
620 }
621
622 static const size_t npos;
623
624 /**
625 * Looks for pcszFind in "this" starting at "pos" and returns its position,
626 * counting from the beginning of "this" at 0. Returns npos if not found.
627 */
628 size_t find(const char *pcszFind, size_t pos = 0) const;
629
630 /**
631 * Returns a substring of "this" as a new Utf8Str. Works exactly like
632 * its equivalent in std::string except that this interprets pos and n
633 * as UTF-8 codepoints instead of bytes. With the default parameters "0"
634 * and "npos", this always copies the entire string.
635 * @param pos Index of first codepoint to copy from "this", counting from 0.
636 * @param n Number of codepoints to copy, starting with the one at "pos".
637 */
638 Utf8Str substr(size_t pos = 0, size_t n = npos) const;
639
640 /**
641 * Attempts to convert the member string into an 32-bit integer.
642 *
643 * @returns 32-bit unsigned number on success.
644 * @returns 0 on failure.
645 */
646 int toInt32() const
647 {
648 return RTStrToInt32(str);
649 }
650
651 /**
652 * Attempts to convert the member string into an unsigned 32-bit integer.
653 *
654 * @returns 32-bit unsigned number on success.
655 * @returns 0 on failure.
656 */
657 int toUInt32() const
658 {
659 return RTStrToUInt32(str);
660 }
661
662 /**
663 * Attempts to convert the member string into an 64-bit integer.
664 *
665 * @returns 64-bit unsigned number on success.
666 * @returns 0 on failure.
667 */
668 int64_t toInt64() const
669 {
670 return RTStrToInt64(str);
671 }
672
673 /**
674 * Attempts to convert the member string into an unsigned 64-bit integer.
675 *
676 * @returns 64-bit unsigned number on success.
677 * @returns 0 on failure.
678 */
679 uint64_t toUInt64() const
680 {
681 return RTStrToUInt64(str);
682 }
683
684 /**
685 * Attempts to convert the member string into an unsigned 64-bit integer.
686 * @return IPRT error code.
687 * @param i Output buffer.
688 */
689 int toInt(uint64_t &i) const;
690
691 /**
692 * Attempts to convert the member string into an unsigned 32-bit integer.
693 * @return IPRT error code.
694 * @param i Output buffer.
695 */
696 int toInt(uint32_t &i) const;
697
698 /**
699 * Intended to pass instances as out (|char **|) parameters to methods.
700 * Takes the ownership of the returned data.
701 */
702 char **asOutParam() { setNull(); return &str; }
703
704 /**
705 * Static immutable null object. May be used for comparison purposes.
706 */
707 static const Utf8Str Null;
708
709protected:
710
711 void safe_assign (const char *s)
712 {
713 if (str != s)
714 {
715 setNull();
716 raw_copy (str, s);
717 }
718 }
719
720 inline static void raw_copy (char *&ls, const char *rs)
721 {
722 if (rs)
723#if !defined (VBOX_WITH_XPCOM)
724 ::RTStrDupEx (&ls, rs);
725#else
726 ls = (char *) nsMemory::Clone (rs, strlen (rs) + 1);
727#endif
728 }
729
730 inline static void raw_copy (char *&ls, CBSTR rs)
731 {
732 if (rs)
733 {
734#if !defined (VBOX_WITH_XPCOM)
735 ::RTUtf16ToUtf8 ((PRTUTF16) rs, &ls);
736#else
737 char *s = NULL;
738 ::RTUtf16ToUtf8 ((PRTUTF16) rs, &s);
739 raw_copy (ls, s);
740 ::RTStrFree (s);
741#endif
742 }
743 }
744
745 char *str;
746
747 friend class Bstr; /* to access our raw_copy() */
748};
749
750// symmetric compare operators
751inline bool operator== (const char *l, const Utf8Str &r) { return r.operator== (l); }
752inline bool operator!= (const char *l, const Utf8Str &r) { return r.operator!= (l); }
753
754// work around error C2593 of the stupid MSVC 7.x ambiguity resolver
755WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP (Bstr)
756WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP (Utf8Str)
757
758////////////////////////////////////////////////////////////////////////////////
759
760// inlined Bstr members that depend on Utf8Str
761
762inline Bstr::Bstr (const Utf8Str &that) : bstr (NULL) { raw_copy (bstr, that); }
763inline Bstr::Bstr (const char *that) : bstr (NULL) { raw_copy (bstr, that); }
764
765inline Bstr &Bstr::operator = (const Utf8Str &that)
766{
767 setNull();
768 raw_copy (bstr, that);
769 return *this;
770}
771inline Bstr &Bstr::operator = (const char *that)
772{
773 setNull();
774 raw_copy (bstr, that);
775 return *this;
776}
777
778inline const Bstr &Bstr::cloneTo (char **pstr) const
779{
780 if (pstr) {
781 *pstr = NULL;
782 Utf8Str::raw_copy (*pstr, bstr);
783 }
784 return *this;
785}
786
787////////////////////////////////////////////////////////////////////////////////
788
789/**
790 * This class is a printf-like formatter for Utf8Str strings. Its purpose is
791 * to construct Utf8Str objects from a format string and a list of arguments
792 * for the format string.
793 *
794 * The usage of this class is like the following:
795 * <code>
796 * Utf8StrFmt string ("program name = %s", argv[0]);
797 * </code>
798 */
799class Utf8StrFmt : public Utf8Str
800{
801public:
802
803 /**
804 * Constructs a new string given the format string and the list
805 * of the arguments for the format string.
806 *
807 * @param format printf-like format string (in UTF-8 encoding)
808 * @param ... list of the arguments for the format string
809 */
810 explicit Utf8StrFmt (const char *format, ...)
811 {
812 va_list args;
813 va_start (args, format);
814 init (format, args);
815 va_end (args);
816 }
817
818protected:
819
820 Utf8StrFmt() {}
821
822 void init (const char *format, va_list args);
823
824private:
825
826 static DECLCALLBACK(size_t) strOutput (void *pvArg, const char *pachChars,
827 size_t cbChars);
828};
829
830/**
831 * This class is a vprintf-like formatter for Utf8Str strings. It is
832 * identical to Utf8StrFmt except that its constructor takes a va_list
833 * argument instead of ellipsis.
834 *
835 * Note that a separate class is necessary because va_list is defined as
836 * |char *| on most platforms. For this reason, if we had two overloaded
837 * constructors in Utf8StrFmt (one taking ellipsis and another one taking
838 * va_list) then composing a constructor call using exactly two |char *|
839 * arguments would cause the compiler to use the va_list overload instead of
840 * the ellipsis one which is obviously wrong. The compiler would choose
841 * va_list because ellipsis has the lowest rank when it comes to resolving
842 * overloads, as opposed to va_list which is an exact match for |char *|.
843 */
844class Utf8StrFmtVA : public Utf8StrFmt
845{
846public:
847
848 /**
849 * Constructs a new string given the format string and the list
850 * of the arguments for the format string.
851 *
852 * @param format printf-like format string (in UTF-8 encoding)
853 * @param args list of arguments for the format string
854 */
855 Utf8StrFmtVA (const char *format, va_list args) { init (format, args); }
856};
857
858/**
859 * The BstrFmt class is a shortcut to <tt>Bstr (Utf8StrFmt (...))</tt>.
860 */
861class BstrFmt : public Bstr
862{
863public:
864
865 /**
866 * Constructs a new string given the format string and the list of the
867 * arguments for the format string.
868 *
869 * @param aFormat printf-like format string (in UTF-8 encoding).
870 * @param ... List of the arguments for the format string.
871 */
872 explicit BstrFmt (const char *aFormat, ...)
873 {
874 va_list args;
875 va_start (args, aFormat);
876 raw_copy (bstr, Utf8StrFmtVA (aFormat, args));
877 va_end (args);
878 }
879};
880
881/**
882 * The BstrFmtVA class is a shortcut to <tt>Bstr (Utf8StrFmtVA (...))</tt>.
883 */
884class BstrFmtVA : public Bstr
885{
886public:
887
888 /**
889 * Constructs a new string given the format string and the list of the
890 * arguments for the format string.
891 *
892 * @param aFormat printf-like format string (in UTF-8 encoding).
893 * @param aArgs List of arguments for the format string
894 */
895 BstrFmtVA (const char *aFormat, va_list aArgs)
896 {
897 raw_copy (bstr, Utf8StrFmtVA (aFormat, aArgs));
898 }
899};
900
901} /* namespace com */
902
903#endif /* ___VBox_com_string_h */
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