VirtualBox

root/trunk/include/VBox/com/string.h

Revision 15051, 20.1 kB (checked in by vboxsync, 1 month ago)

Main: Cleaned up the long standing const BSTR = const (OLECHAR *) on WIn32 vs (const PRunichar) * on XPCOM clash. Cleaned up BSTR/GUID macros (IN_BSTR replaces INPTR BSTR, IN_GUID replaces INPTR GUIDPARAM, OUT_GUID replaces GUIDPARAMOUT).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /* $Id$ */
2
3 /** @file
4  * MS COM / XPCOM Abstraction Layer:
5  * Smart string classes declaration
6  */
7
8 /*
9  * Copyright (C) 2006-2007 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
55 namespace com
56 {
57
58 class 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  */
73 class Bstr
74 {
75 public:
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      *  plus the terminating zero character. If \a aSize is zero, or if a
130      *  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
271 protected:
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 */
305 inline bool operator== (CBSTR l, const Bstr &r) { return r.operator== (l); }
306 inline bool operator!= (CBSTR l, const Bstr &r) { return r.operator!= (l); }
307 inline bool operator== (BSTR l, const Bstr &r) { return r.operator== (l); }
308 inline 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  */
326 class Utf8Str
327 {
328 public:
329
330     typedef char *String;
331     typedef const char *ConstString;
332
333     Utf8Str () : str (NULL) {}
334
335     Utf8Str (const Utf8Str &that) : str (NULL) { raw_copy (str, that.str); }
336     Utf8Str (const char *that) : str (NULL) { raw_copy (str, that); }
337
338     Utf8Str (const Bstr &that) : str (NULL) { raw_copy (str, that); }
339     Utf8Str (CBSTR that) : str (NULL) { raw_copy (str, that); }
340
341     /** Shortcut that calls #alloc(aSize) right after object creation. */
342     Utf8Str (size_t aSize) : str (NULL) { alloc(aSize); }
343
344     virtual ~Utf8Str () { setNull(); }
345
346     Utf8Str &operator = (const Utf8Str &that) { safe_assign (that.str); return *this; }
347     Utf8Str &operator = (const char *that) { safe_assign (that); return *this; }
348
349     Utf8Str &operator = (const Bstr &that)
350     {
351         setNull();
352         raw_copy (str, that);
353         return *this;
354     }
355     Utf8Str &operator = (CBSTR that)
356     {
357         setNull();
358         raw_copy (str, that);
359         return *this;
360     }
361
362     Utf8Str &setNull()
363     {
364         if (str)
365         {
366 #if !defined (VBOX_WITH_XPCOM)
367             ::RTStrFree (str);
368 #else
369             nsMemory::Free (str);
370 #endif
371             str = NULL;
372         }
373         return *this;
374     }
375
376     Utf8Str &setNullIfEmpty()
377     {
378         if (str && *str == 0)
379         {
380 #if !defined (VBOX_WITH_XPCOM)
381             ::RTStrFree (str);
382 #else
383             nsMemory::Free (str);
384 #endif
385             str = NULL;
386         }
387         return *this;
388     }
389
390     /**
391      *  Allocates memory for a string capable to store \a aSize - 1 characters
392      *  plus the terminating zero character. If \a aSize is zero, or if a
393      *  memory allocation error occurs, this object will become null.
394      */
395     Utf8Str &alloc (size_t aSize)
396     {
397         setNull();
398         if (aSize)
399         {
400 #if !defined (VBOX_WITH_XPCOM)
401             str = (char *) ::RTMemTmpAlloc (aSize);
402 #else
403             str = (char *) nsMemory::Alloc (aSize);
404 #endif
405             if (str)
406                 str [0] = 0;
407         }
408         return *this;
409     }
410
411     int compare (const char *s) const
412     {
413         if (str == s)
414             return 0;
415         if (str == NULL)
416             return -1;
417         if (s == NULL)
418             return 1;
419
420         return ::strcmp (str, s);
421     }
422
423     bool operator == (const Utf8Str &that) const { return !compare (that.str); }
424     bool operator != (const Utf8Str &that) const { return !!compare (that.str); }
425     bool operator == (const char *that) const { return !compare (that); }
426     bool operator != (const char *that) const { return !!compare (that); }
427     bool operator < (const Utf8Str &that) const { return compare (that.str) < 0; }
428     bool operator < (const char *that) const { return compare (that) < 0; }
429
430     bool isNull() const { return str == NULL; }
431     operator bool() const { return !isNull(); }
432
433     bool isEmpty() const { return isNull() || *str == 0; }
434
435     size_t length() const { return isNull() ? 0 : ::strlen (str); }
436
437     /** Intended to to pass instances as input (|char *|) parameters to methods. */
438     operator const char *() const { return str; }
439
440     /** The same as operator const char *(), but for situations where the compiler
441         cannot typecast implicitly (for example, in printf() argument list). */
442     const char *raw() const { return str; }
443
444     /**
445      *  Returns a non-const raw pointer that allows to modify the string directly.
446      *  @warning
447      *      Be sure not to modify data beyond the allocated memory! The
448      *      guaranteed size of the allocated memory is at least #length()
449      *      bytes after creation and after every assignment operation.
450      */
451     char *mutableRaw() { return str; }
452
453     /**
454      *  Intended to assign instances to |char *| out parameters from within the
455      *  interface method. Transfers the ownership of the duplicated string to the
456      *  caller.
457      */
458     const Utf8Str &cloneTo (char **pstr) const
459     {
460         if (pstr)
461         {
462             *pstr = NULL;
463             raw_copy (*pstr, str);
464         }
465         return *this;
466     }
467
468     /**
469      *  Intended to assign instances to |char *| out parameters from within the
470      *  interface method. Transfers the ownership of the original string to the
471      *  caller and resets the instance to null.
472      *
473      *  As opposed to cloneTo(), this method doesn't create a copy of the
474      *  string.
475      */
476     Utf8Str &detachTo (char **pstr)
477     {
478         *pstr = str;
479         str = NULL;
480         return *this;
481     }
482
483     /**
484      *  Intended to assign instances to |BSTR| out parameters from within the
485      *  interface method. Transfers the ownership of the duplicated string to the
486      *  caller.
487      */
488     const Utf8Str &cloneTo (BSTR *pstr) const
489     {
490         if (pstr)
491         {
492             *pstr = NULL;
493             Bstr::raw_copy (*pstr, str);
494         }
495         return *this;
496     }
497
498     /**
499      *  Intended to pass instances as out (|char **|) parameters to methods.
500      *  Takes the ownership of the returned data.
501      */
502     char **asOutParam() { setNull(); return &str; }
503
504     /**
505      *  Static immutable null object. May be used for comparison purposes.
506      */
507     static const Utf8Str Null;
508
509 protected:
510
511     void safe_assign (const char *s)
512     {
513         if (str != s)
514         {
515             setNull();
516             raw_copy (str, s);
517         }
518     }
519
520     inline static void raw_copy (char *&ls, const char *rs)
521     {
522         if (rs)
523 #if !defined (VBOX_WITH_XPCOM)
524             ::RTStrDupEx (&ls, rs);
525 #else
526             ls = (char *) nsMemory::Clone (rs, strlen (rs) + 1);
527 #endif
528     }
529
530     inline static void raw_copy (char *&ls, CBSTR rs)
531     {
532         if (rs)
533         {
534 #if !defined (VBOX_WITH_XPCOM)
535             ::RTUtf16ToUtf8 ((PRTUTF16) rs, &ls);
536 #else
537             char *s = NULL;
538             ::RTUtf16ToUtf8 ((PRTUTF16) rs, &s);
539             raw_copy (ls, s);
540             ::RTStrFree (s);
541 #endif
542         }
543     }
544
545     char *str;
546
547     friend class Bstr; /* to access our raw_copy() */
548 };
549
550 // symmetric compare operators
551 inline bool operator== (const char *l, const Utf8Str &r) { return r.operator== (l); }
552 inline bool operator!= (const char *l, const Utf8Str &r) { return r.operator!= (l); }
553
554 // work around error C2593 of the stupid MSVC 7.x ambiguity resolver
555 WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP (Bstr)
556 WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP (Utf8Str)
557
558 ////////////////////////////////////////////////////////////////////////////////
559
560 // inlined Bstr members that depend on Utf8Str
561
562 inline Bstr::Bstr (const Utf8Str &that) : bstr (NULL) { raw_copy (bstr, that); }
563 inline Bstr::Bstr (const char *that) : bstr (NULL) { raw_copy (bstr, that); }
564
565 inline Bstr &Bstr::operator = (const Utf8Str &that)
566 {
567     setNull();
568     raw_copy (bstr, that);
569     return *this;
570 }
571 inline Bstr &Bstr::operator = (const char *that)
572 {
573     setNull();
574     raw_copy (bstr, that);
575     return *this;
576 }
577
578 inline const Bstr &Bstr::cloneTo (char **pstr) const
579 {
580     if (pstr) {
581         *pstr = NULL;
582         Utf8Str::raw_copy (*pstr, bstr);
583     }
584     return *this;
585 }
586
587 ////////////////////////////////////////////////////////////////////////////////
588
589 /**
590  *  This class is a printf-like formatter for Utf8Str strings. Its purpose is
591  *  to construct Utf8Str objects from a format string and a list of arguments
592  *  for the format string.
593  *
594  *  The usage of this class is like the following:
595  *  <code>
596  *      Utf8StrFmt string ("program name = %s", argv[0]);
597  *  </code>
598  */
599 class Utf8StrFmt : public Utf8Str
600 {
601 public:
602
603     /**
604      *  Constructs a new string given the format string and the list
605      *  of the arguments for the format string.
606      *
607      *  @param format   printf-like format string (in UTF-8 encoding)
608      *  @param ...      list of the arguments for the format string
609      */
610     explicit Utf8StrFmt (const char *format, ...)
611     {
612         va_list args;
613         va_start (args, format);
614         init (format, args);
615         va_end (args);
616     }
617
618 protected:
619
620     Utf8StrFmt() {}
621
622     void init (const char *format, va_list args);
623
624 private:
625
626     static DECLCALLBACK(size_t) strOutput (void *pvArg, const char *pachChars,
627                                            size_t cbChars);
628 };
629
630 /**
631  *  This class is a vprintf-like formatter for Utf8Str strings. It is
632  *  identical to Utf8StrFmt except that its constructor takes a va_list
633  *  argument instead of ellipsis.
634  *
635  *  Note that a separate class is necessary because va_list is defined as
636  *  |char *| on most platforms. For this reason, if we had two overloaded
637  *  constructors in Utf8StrFmt (one taking ellipsis and another one taking
638  *  va_list) then composing a constructor call using exactly two |char *|
639  *  arguments would cause the compiler to use the va_list overload instead of
640  *  the ellipsis one which is obviously wrong. The compiler would choose
641  *  va_list because ellipsis has the lowest rank when it comes to resolving
642  *  overloads, as opposed to va_list which is an exact match for |char *|.
643  */
644 class Utf8StrFmtVA : public Utf8StrFmt
645 {
646 public:
647
648     /**
649      *  Constructs a new string given the format string and the list
650      *  of the arguments for the format string.
651      *
652      *  @param format   printf-like format string (in UTF-8 encoding)
653      *  @param args     list of arguments for the format string
654      */
655     Utf8StrFmtVA (const char *format, va_list args) { init (format, args); }
656 };
657
658 /**
659  * The BstrFmt class is a shortcut to <tt>Bstr (Utf8StrFmt (...))</tt>.
660  */
661 class BstrFmt : public Bstr
662 {
663 public:
664
665     /**
666      * Constructs a new string given the format string and the list of the
667      * arguments for the format string.
668      *
669      * @param aFormat   printf-like format string (in UTF-8 encoding).
670      * @param ...       List of the arguments for the format string.
671      */
672     explicit BstrFmt (const char *aFormat, ...)
673     {
674         va_list args;
675         va_start (args, aFormat);
676         raw_copy (bstr, Utf8StrFmtVA (aFormat, args));
677         va_end (args);
678     }
679 };
680
681 /**
682  * The BstrFmtVA class is a shortcut to <tt>Bstr (Utf8StrFmtVA (...))</tt>.
683  */
684 class BstrFmtVA : public Bstr
685 {
686 public:
687
688     /**
689      * Constructs a new string given the format string and the list of the
690      * arguments for the format string.
691      *
692      * @param aFormat   printf-like format string (in UTF-8 encoding).
693      * @param aArgs     List of arguments for the format string
694      */
695     BstrFmtVA (const char *aFormat, va_list aArgs)
696     {
697         raw_copy (bstr, Utf8StrFmtVA (aFormat, aArgs));
698     }
699 };
700
701 } /* namespace com */
702
703 #endif /* ___VBox_com_string_h */
Note: See TracBrowser for help on using the browser.

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy