VirtualBox

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

Last change on this file since 21079 was 21079, checked in by vboxsync, 15 years ago

Main: move libxml2 to IPRT unconditionally (remove VBOX_WITH_LIBXML2_IN_VBOXRT); move xml classes to IPRT; introduce IPRT ministring class as base for both Utf8Str and xml.cpp, with better performance; introduce some Utf8Str helpers to avoid string buffer hacks in Main code; remove std::auto_ptr<> from some headers

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.7 KB
Line 
1/* $Id: string.h 21079 2009-06-30 15:59:22Z 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/cpputils.h>
52#include <iprt/alloc.h>
53#include <iprt/ministring_cpp.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 : public ministring
327{
328public:
329
330 Utf8Str() {}
331
332 Utf8Str(const Utf8Str &that)
333 : ministring(that)
334 {}
335
336 Utf8Str(const char *that)
337 : ministring(that)
338 {}
339
340 Utf8Str(const Bstr &that)
341 {
342 copyFrom(that);
343 }
344
345 Utf8Str(CBSTR that)
346 {
347 copyFrom(that);
348 }
349
350 Utf8Str& operator=(const Utf8Str &that)
351 {
352 ministring::operator=(that);
353 return *this;
354 }
355
356 Utf8Str& operator=(const char *that)
357 {
358 ministring::operator=(that);
359 return *this;
360 }
361
362 Utf8Str& operator=(const Bstr &that)
363 {
364 cleanup();
365 copyFrom(that);
366 return *this;
367 }
368
369 Utf8Str& operator=(CBSTR that)
370 {
371 cleanup();
372 copyFrom(that);
373 return *this;
374 }
375
376 /**
377 * Intended to assign instances to |char *| out parameters from within the
378 * interface method. Transfers the ownership of the duplicated string to the
379 * caller.
380 */
381 const Utf8Str& cloneTo(char **pstr) const
382 {
383 if (pstr)
384 *pstr = RTStrDup(m_psz);
385 return *this;
386 }
387
388 /**
389 * Intended to assign instances to |char *| out parameters from within the
390 * interface method. Transfers the ownership of the original string to the
391 * caller and resets the instance to null.
392 *
393 * As opposed to cloneTo(), this method doesn't create a copy of the
394 * string.
395 */
396 Utf8Str& detachTo(char **pstr)
397 {
398 *pstr = m_psz;
399 m_psz = NULL;
400 m_cbAllocated = 0;
401 m_cbLength = 0;
402 return *this;
403 }
404
405 /**
406 * Intended to assign instances to |BSTR| out parameters from within the
407 * interface method. Transfers the ownership of the duplicated string to the
408 * caller.
409 */
410 const Utf8Str& cloneTo(BSTR *pstr) const
411 {
412 if (pstr)
413 {
414 *pstr = NULL;
415 Bstr::raw_copy(*pstr, m_psz);
416 }
417 return *this;
418 }
419
420 static const size_t npos;
421
422 /**
423 * Looks for pcszFind in "this" starting at "pos" and returns its position,
424 * counting from the beginning of "this" at 0. Returns npos if not found.
425 */
426 size_t find(const char *pcszFind, size_t pos = 0) const;
427
428 /**
429 * Returns a substring of "this" as a new Utf8Str. Works exactly like
430 * its equivalent in std::string except that this interprets pos and n
431 * as UTF-8 codepoints instead of bytes. With the default parameters "0"
432 * and "npos", this always copies the entire string.
433 * @param pos Index of first codepoint to copy from "this", counting from 0.
434 * @param n Number of codepoints to copy, starting with the one at "pos".
435 */
436 Utf8Str substr(size_t pos = 0, size_t n = npos) const;
437
438 /**
439 * Returns true if "this" ends with "that".
440 * @param that
441 * @param cs
442 * @return
443 */
444 bool endsWith(const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const;
445
446 /**
447 * Returns true if "this" begins with "that".
448 * @return
449 */
450 bool startsWith(const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const;
451
452 /**
453 * Returns true if "this" contains "that" (strstr).
454 * @param that
455 * @param cs
456 * @return
457 */
458 bool contains(const Utf8Str &that, CaseSensitivity cs = CaseSensitive) const;
459
460 /**
461 * Converts "this" to lower case by calling RTStrToLower().
462 * @return
463 */
464 Utf8Str& toLower();
465
466 /**
467 * Converts "this" to upper case by calling RTStrToUpper().
468 * @return
469 */
470 Utf8Str& toUpper();
471
472 /**
473 * Removes a trailing slash from the member string, if present.
474 * Calls RTPathStripTrailingSlash() without having to mess with mutableRaw().
475 */
476 void stripTrailingSlash();
477
478 /**
479 * Removes a trailing filename from the member string, if present.
480 * Calls RTPathStripFilename() without having to mess with mutableRaw().
481 */
482 void stripFilename();
483
484 /**
485 * Removes a trailing file name extension from the member string, if present.
486 * Calls RTPathStripExt() without having to mess with mutableRaw().
487 */
488 void stripExt();
489
490 /**
491 * Attempts to convert the member string into a 32-bit integer.
492 *
493 * @returns 32-bit unsigned number on success.
494 * @returns 0 on failure.
495 */
496 int toInt32() const
497 {
498 return RTStrToInt32(m_psz);
499 }
500
501 /**
502 * Attempts to convert the member string into an unsigned 32-bit integer.
503 *
504 * @returns 32-bit unsigned number on success.
505 * @returns 0 on failure.
506 */
507 int toUInt32() const
508 {
509 return RTStrToUInt32(m_psz);
510 }
511
512 /**
513 * Attempts to convert the member string into an 64-bit integer.
514 *
515 * @returns 64-bit unsigned number on success.
516 * @returns 0 on failure.
517 */
518 int64_t toInt64() const
519 {
520 return RTStrToInt64(m_psz);
521 }
522
523 /**
524 * Attempts to convert the member string into an unsigned 64-bit integer.
525 *
526 * @returns 64-bit unsigned number on success.
527 * @returns 0 on failure.
528 */
529 uint64_t toUInt64() const
530 {
531 return RTStrToUInt64(m_psz);
532 }
533
534 /**
535 * Attempts to convert the member string into an unsigned 64-bit integer.
536 * @return IPRT error code.
537 * @param i Output buffer.
538 */
539 int toInt(uint64_t &i) const;
540
541 /**
542 * Attempts to convert the member string into an unsigned 32-bit integer.
543 * @return IPRT error code.
544 * @param i Output buffer.
545 */
546 int toInt(uint32_t &i) const;
547
548 /**
549 * Intended to pass instances as out (|char **|) parameters to methods.
550 * Takes the ownership of the returned data.
551 */
552 char **asOutParam()
553 {
554 cleanup();
555 return &m_psz;
556 }
557
558 /**
559 * Static immutable null object. May be used for comparison purposes.
560 */
561 static const Utf8Str Null;
562
563protected:
564
565 /**
566 * As with the ministring::copyFrom() variants, this unconditionally
567 * sets the members to a copy of the given other strings and makes
568 * no assumptions about previous contents. This can therefore be used
569 * both in copy constructors, when member variables have no defined
570 * value, and in assignments after having called cleanup().
571 *
572 * This variant converts from a UTF-16 string, most probably from
573 * a Bstr assignment.
574 *
575 * @param rs
576 */
577 void copyFrom(CBSTR s)
578 {
579 if (s)
580 {
581 RTUtf16ToUtf8((PRTUTF16)s, &m_psz);
582 m_cbLength = strlen(m_psz); // TODO optimize by using a different RTUtf* function
583 m_cbAllocated = m_cbLength + 1;
584 }
585 else
586 {
587 m_cbLength = 0;
588 m_cbAllocated = 0;
589 m_psz = NULL;
590 }
591 }
592
593 friend class Bstr; /* to access our raw_copy() */
594};
595
596// work around error C2593 of the stupid MSVC 7.x ambiguity resolver
597WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP (Bstr)
598WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP (Utf8Str)
599
600////////////////////////////////////////////////////////////////////////////////
601
602// inlined Bstr members that depend on Utf8Str
603
604inline Bstr::Bstr (const Utf8Str &that) : bstr (NULL) { raw_copy (bstr, that); }
605inline Bstr::Bstr (const char *that) : bstr (NULL) { raw_copy (bstr, that); }
606
607inline Bstr &Bstr::operator = (const Utf8Str &that)
608{
609 setNull();
610 raw_copy (bstr, that);
611 return *this;
612}
613inline Bstr &Bstr::operator = (const char *that)
614{
615 setNull();
616 raw_copy (bstr, that);
617 return *this;
618}
619
620inline const Bstr& Bstr::cloneTo(char **pstr) const
621{
622 if (pstr)
623 {
624 Utf8Str ustr(*this);
625 ustr.detachTo(pstr);
626 }
627 return *this;
628}
629
630////////////////////////////////////////////////////////////////////////////////
631
632/**
633 * This class is a printf-like formatter for Utf8Str strings. Its purpose is
634 * to construct Utf8Str objects from a format string and a list of arguments
635 * for the format string.
636 *
637 * The usage of this class is like the following:
638 * <code>
639 * Utf8StrFmt string ("program name = %s", argv[0]);
640 * </code>
641 */
642class Utf8StrFmt : public Utf8Str
643{
644public:
645
646 /**
647 * Constructs a new string given the format string and the list
648 * of the arguments for the format string.
649 *
650 * @param format printf-like format string (in UTF-8 encoding)
651 * @param ... list of the arguments for the format string
652 */
653 explicit Utf8StrFmt (const char *format, ...)
654 {
655 va_list args;
656 va_start (args, format);
657 init (format, args);
658 va_end (args);
659 }
660
661protected:
662
663 Utf8StrFmt() {}
664
665 void init (const char *format, va_list args);
666
667private:
668
669 static DECLCALLBACK(size_t) strOutput (void *pvArg, const char *pachChars,
670 size_t cbChars);
671};
672
673/**
674 * This class is a vprintf-like formatter for Utf8Str strings. It is
675 * identical to Utf8StrFmt except that its constructor takes a va_list
676 * argument instead of ellipsis.
677 *
678 * Note that a separate class is necessary because va_list is defined as
679 * |char *| on most platforms. For this reason, if we had two overloaded
680 * constructors in Utf8StrFmt (one taking ellipsis and another one taking
681 * va_list) then composing a constructor call using exactly two |char *|
682 * arguments would cause the compiler to use the va_list overload instead of
683 * the ellipsis one which is obviously wrong. The compiler would choose
684 * va_list because ellipsis has the lowest rank when it comes to resolving
685 * overloads, as opposed to va_list which is an exact match for |char *|.
686 */
687class Utf8StrFmtVA : public Utf8StrFmt
688{
689public:
690
691 /**
692 * Constructs a new string given the format string and the list
693 * of the arguments for the format string.
694 *
695 * @param format printf-like format string (in UTF-8 encoding)
696 * @param args list of arguments for the format string
697 */
698 Utf8StrFmtVA (const char *format, va_list args) { init (format, args); }
699};
700
701/**
702 * The BstrFmt class is a shortcut to <tt>Bstr (Utf8StrFmt (...))</tt>.
703 */
704class BstrFmt : public Bstr
705{
706public:
707
708 /**
709 * Constructs a new string given the format string and the list of the
710 * arguments for the format string.
711 *
712 * @param aFormat printf-like format string (in UTF-8 encoding).
713 * @param ... List of the arguments for the format string.
714 */
715 explicit BstrFmt (const char *aFormat, ...)
716 {
717 va_list args;
718 va_start (args, aFormat);
719 raw_copy (bstr, Utf8StrFmtVA (aFormat, args));
720 va_end (args);
721 }
722};
723
724/**
725 * The BstrFmtVA class is a shortcut to <tt>Bstr (Utf8StrFmtVA (...))</tt>.
726 */
727class BstrFmtVA : public Bstr
728{
729public:
730
731 /**
732 * Constructs a new string given the format string and the list of the
733 * arguments for the format string.
734 *
735 * @param aFormat printf-like format string (in UTF-8 encoding).
736 * @param aArgs List of arguments for the format string
737 */
738 BstrFmtVA (const char *aFormat, va_list aArgs)
739 {
740 raw_copy (bstr, Utf8StrFmtVA (aFormat, aArgs));
741 }
742};
743
744} /* namespace com */
745
746#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