VirtualBox

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

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

Automated rebranding to Oracle copyright/license strings via filemuncher

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.4 KB
Line 
1/* $Id: string.h 28800 2010-04-27 08:22:32Z vboxsync $ */
2
3/** @file
4 * MS COM / XPCOM Abstraction Layer:
5 * Smart string classes declaration
6 */
7
8/*
9 * Copyright (C) 2006-2009 Oracle Corporation
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
29#ifndef ___VBox_com_string_h
30#define ___VBox_com_string_h
31
32/* Make sure all the stdint.h macros are included - must come first! */
33#ifndef __STDC_LIMIT_MACROS
34# define __STDC_LIMIT_MACROS
35#endif
36#ifndef __STDC_CONSTANT_MACROS
37# define __STDC_CONSTANT_MACROS
38#endif
39
40#if defined (VBOX_WITH_XPCOM)
41# include <nsMemory.h>
42#endif
43
44#include "VBox/com/defs.h"
45#include "VBox/com/assert.h"
46
47#include <iprt/alloc.h>
48#include <iprt/cpp/ministring.h>
49
50namespace com
51{
52
53class Utf8Str;
54
55// global constant in glue/string.cpp that represents an empty BSTR
56extern const BSTR g_bstrEmpty;
57
58/**
59 * String class used universally in Main for COM-style Utf-16 strings.
60 * Unfortunately COM on Windows uses UTF-16 everywhere, requiring conversions
61 * back and forth since most of VirtualBox and our libraries use UTF-8.
62 *
63 * To make things more obscure, on Windows, a COM-style BSTR is not just a
64 * pointer to a null-terminated wide character array, but the four bytes
65 * (32 bits) BEFORE the memory that the pointer points to are a length
66 * DWORD. One must therefore avoid pointer arithmetic and always use
67 * SysAllocString and the like to deal with BSTR pointers, which manage
68 * that DWORD correctly.
69 *
70 * For platforms other than Windows, we provide our own versions of the
71 * Sys* functions in Main/xpcom/helpers.cpp which do NOT use length
72 * prefixes though to be compatible with how XPCOM allocates string
73 * parameters to public functions.
74 *
75 * The Bstr class hides all this handling behind a std::string-like interface
76 * and also provides automatic conversions to MiniString and Utf8Str instances.
77 *
78 * The one advantage of using the SysString* routines is that this makes it
79 * possible to use it as a type of member variables of COM/XPCOM components
80 * and pass their values to callers through component methods' output parameters
81 * using the #cloneTo() operation. Also, the class can adopt (take ownership of)
82 * string buffers returned in output parameters of COM methods using the
83 * #asOutParam() operation and correctly free them afterwards.
84 *
85 * Starting with VirtualBox 3.2, like Utf8Str, Bstr no longer differentiates
86 * between NULL strings and empty strings. In other words, Bstr("") and
87 * Bstr(NULL) behave the same. In both cases, Bstr allocates no memory,
88 * reports a zero length and zero allocated bytes for both, and returns an
89 * empty C wide string from raw().
90 */
91class Bstr
92{
93public:
94
95 Bstr()
96 : m_bstr(NULL)
97 { }
98
99 Bstr(const Bstr &that)
100 {
101 copyFrom((const OLECHAR *)that.m_bstr);
102 }
103
104 Bstr(CBSTR that)
105 {
106 copyFrom((const OLECHAR *)that);
107 }
108
109#if defined (VBOX_WITH_XPCOM)
110 Bstr(const wchar_t *that)
111 {
112 AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
113 copyFrom((const OLECHAR *)that);
114 }
115#endif
116
117 Bstr(const iprt::MiniString &that)
118 {
119 copyFrom(that.raw());
120 }
121
122 Bstr(const char *that)
123 {
124 copyFrom(that);
125 }
126
127 ~Bstr()
128 {
129 setNull();
130 }
131
132 Bstr& operator=(const Bstr &that)
133 {
134 cleanup();
135 copyFrom((const OLECHAR *)that.m_bstr);
136 return *this;
137 }
138
139 Bstr& operator=(CBSTR that)
140 {
141 cleanup();
142 copyFrom((const OLECHAR *)that);
143 return *this;
144 }
145
146#if defined (VBOX_WITH_XPCOM)
147 Bstr& operator=(const wchar_t *that)
148 {
149 cleanup();
150 copyFrom((const OLECHAR *)that);
151 return *this;
152 }
153#endif
154
155 Bstr& setNull()
156 {
157 cleanup();
158 return *this;
159 }
160
161 /** Case sensitivity selector. */
162 enum CaseSensitivity
163 {
164 CaseSensitive,
165 CaseInsensitive
166 };
167
168 /**
169 * Compares the member string to str.
170 * @param str
171 * @param cs Whether comparison should be case-sensitive.
172 * @return
173 */
174 int compare(CBSTR str, CaseSensitivity cs = CaseSensitive) const
175 {
176 if (cs == CaseSensitive)
177 return ::RTUtf16Cmp((PRTUTF16)m_bstr, (PRTUTF16)str);
178 return ::RTUtf16LocaleICmp((PRTUTF16)m_bstr, (PRTUTF16)str);
179 }
180
181 int compare(BSTR str) const
182 {
183 return compare((CBSTR)str);
184 }
185
186 bool operator==(const Bstr &that) const { return !compare(that.m_bstr); }
187 bool operator!=(const Bstr &that) const { return !!compare(that.m_bstr); }
188 bool operator==(CBSTR that) const { return !compare(that); }
189 bool operator==(BSTR that) const { return !compare(that); }
190
191 bool operator!=(CBSTR that) const { return !!compare(that); }
192 bool operator!=(BSTR that) const { return !!compare(that); }
193 bool operator<(const Bstr &that) const { return compare(that.m_bstr) < 0; }
194 bool operator<(CBSTR that) const { return compare(that) < 0; }
195 bool operator<(BSTR that) const { return compare(that) < 0; }
196
197 /**
198 * Returns true if the member string has no length.
199 * This is true for instances created from both NULL and "" input strings.
200 *
201 * @note Always use this method to check if an instance is empty. Do not
202 * use length() because that may need to run through the entire string
203 * (Bstr does not cache string lengths). Also do not use operator bool();
204 * for one, MSVC is really annoying with its thinking that that is ambiguous,
205 * and even though operator bool() is protected with Bstr, at least gcc uses
206 * operator CBSTR() when a construct like "if (string)" is encountered, which
207 * is always true now since it raw() never returns an empty string. Again,
208 * always use isEmpty() even though if (string) may compile!
209 */
210 bool isEmpty() const { return m_bstr == NULL || *m_bstr == 0; }
211
212 size_t length() const { return isEmpty() ? 0 : ::RTUtf16Len((PRTUTF16)m_bstr); }
213
214 /**
215 * Returns true if the member string is not empty. I'd like to make this
216 * private but since we require operator BSTR() it's futile anyway because
217 * the compiler will then (wrongly) use that one instead. Also if this is
218 * private the odd WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP macro below
219 * will fail on Windows.
220 */
221 operator bool() const
222 {
223 return m_bstr != NULL;
224 }
225
226 /**
227 * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
228 * returns a pointer to a global variable containing an empty BSTR with a proper zero
229 * length prefix so that Windows is happy.
230 */
231 CBSTR raw() const
232 {
233 if (m_bstr)
234 return m_bstr;
235
236 return g_bstrEmpty;
237 }
238
239 /**
240 * Convenience operator so that Bstr's can be passed to CBSTR input parameters
241 * of COM methods.
242 */
243 operator CBSTR() const { return raw(); }
244
245 /**
246 * Convenience operator so that Bstr's can be passed to CBSTR input parameters
247 * of COM methods. Unfortunately this is required for Windows since with
248 * MSCOM, input BSTR parameters of interface methods are not const.
249 */
250 operator BSTR() { return (BSTR)raw(); }
251
252 /**
253 * Returns a non-const raw pointer that allows to modify the string directly.
254 * As opposed to raw(), this DOES return NULL if the member string is empty
255 * because we cannot return a mutable pointer to the global variable with the
256 * empty string.
257 *
258 * @warning
259 * Be sure not to modify data beyond the allocated memory! The
260 * guaranteed size of the allocated memory is at least #length()
261 * bytes after creation and after every assignment operation.
262 */
263 BSTR mutableRaw() { return m_bstr; }
264
265 /**
266 * Intended to assign copies of instances to |BSTR| out parameters from
267 * within the interface method. Transfers the ownership of the duplicated
268 * string to the caller.
269 *
270 * If the member string is empty, this allocates an empty BSTR in *pstr
271 * (i.e. makes it point to a new buffer with a null byte).
272 */
273 void cloneTo(BSTR *pstr) const
274 {
275 if (pstr)
276 {
277 *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty
278#ifdef RT_EXCEPTIONS_ENABLED
279 if (!*pstr)
280 throw std::bad_alloc();
281#endif
282 }
283 }
284
285 /**
286 * Intended to assign instances to |BSTR| out parameters from within the
287 * interface method. Transfers the ownership of the original string to the
288 * caller and resets the instance to null.
289 *
290 * As opposed to cloneTo(), this method doesn't create a copy of the
291 * string.
292 *
293 * If the member string is empty, this allocates an empty BSTR in *pstr
294 * (i.e. makes it point to a new buffer with a null byte).
295 */
296 void detachTo(BSTR *pstr)
297 {
298 if (m_bstr)
299 *pstr = m_bstr;
300 else
301 {
302 // allocate null BSTR
303 *pstr = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
304#ifdef RT_EXCEPTIONS_ENABLED
305 if (!*pstr)
306 throw std::bad_alloc();
307#endif
308 }
309 m_bstr = NULL;
310 }
311
312 /**
313 * Intended to pass instances as |BSTR| out parameters to methods.
314 * Takes the ownership of the returned data.
315 */
316 BSTR* asOutParam()
317 {
318 cleanup();
319 return &m_bstr;
320 }
321
322 /**
323 * Static immutable null object. May be used for comparison purposes.
324 */
325 static const Bstr Null;
326
327protected:
328
329 void cleanup()
330 {
331 if (m_bstr)
332 {
333 ::SysFreeString(m_bstr);
334 m_bstr = NULL;
335 }
336 }
337
338 /**
339 * Protected internal helper to copy a string. This ignores the previous object
340 * state, so either call this from a constructor or call cleanup() first.
341 *
342 * This variant copies from a zero-terminated UTF-16 string (which need not
343 * be a BSTR, i.e. need not have a length prefix).
344 *
345 * If the source is empty, this sets the member string to NULL.
346 * @param rs
347 */
348 void copyFrom(const OLECHAR *rs)
349 {
350 if (rs && *rs)
351 {
352 m_bstr = ::SysAllocString(rs);
353#ifdef RT_EXCEPTIONS_ENABLED
354 if (!m_bstr)
355 throw std::bad_alloc();
356#endif
357 }
358 else
359 m_bstr = NULL;
360 }
361
362 /**
363 * Protected internal helper to copy a string. This ignores the previous object
364 * state, so either call this from a constructor or call cleanup() first.
365 *
366 * This variant copies and converts from a zero-terminated UTF-8 string.
367 *
368 * If the source is empty, this sets the member string to NULL.
369 * @param rs
370 */
371 void copyFrom(const char *rs)
372 {
373 if (rs && *rs)
374 {
375 PRTUTF16 s = NULL;
376 ::RTStrToUtf16(rs, &s);
377#ifdef RT_EXCEPTIONS_ENABLED
378 if (!s)
379 throw std::bad_alloc();
380#endif
381 copyFrom((const OLECHAR *)s); // allocates BSTR from zero-terminated input string
382 ::RTUtf16Free(s);
383 }
384 else
385 m_bstr = NULL;
386 }
387
388 BSTR m_bstr;
389
390 friend class Utf8Str; /* to access our raw_copy() */
391};
392
393/* symmetric compare operators */
394inline bool operator==(CBSTR l, const Bstr &r) { return r.operator==(l); }
395inline bool operator!=(CBSTR l, const Bstr &r) { return r.operator!=(l); }
396inline bool operator==(BSTR l, const Bstr &r) { return r.operator==(l); }
397inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!=(l); }
398
399// work around error C2593 of the stupid MSVC 7.x ambiguity resolver
400WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Bstr)
401
402////////////////////////////////////////////////////////////////////////////////
403
404/**
405 * String class used universally in Main for UTF-8 strings.
406 *
407 * This is based on iprt::MiniString, to which some functionality has been
408 * moved. Here we keep things that are specific to Main, such as conversions
409 * with UTF-16 strings (Bstr).
410 *
411 * Like iprt::MiniString, Utf8Str does not differentiate between NULL strings
412 * and empty strings. In other words, Utf8Str("") and Utf8Str(NULL)
413 * behave the same. In both cases, MiniString allocates no memory, reports
414 * a zero length and zero allocated bytes for both, and returns an empty
415 * C string from c_str().
416 */
417class Utf8Str : public iprt::MiniString
418{
419public:
420
421 Utf8Str() {}
422
423 Utf8Str(const MiniString &that)
424 : MiniString(that)
425 {}
426
427 Utf8Str(const char *that)
428 : MiniString(that)
429 {}
430
431 Utf8Str(const Bstr &that)
432 {
433 copyFrom(that);
434 }
435
436 Utf8Str(CBSTR that)
437 {
438 copyFrom(that);
439 }
440
441 Utf8Str& operator=(const MiniString &that)
442 {
443 MiniString::operator=(that);
444 return *this;
445 }
446
447 Utf8Str& operator=(const char *that)
448 {
449 MiniString::operator=(that);
450 return *this;
451 }
452
453 Utf8Str& operator=(const Bstr &that)
454 {
455 cleanup();
456 copyFrom(that);
457 return *this;
458 }
459
460 Utf8Str& operator=(CBSTR that)
461 {
462 cleanup();
463 copyFrom(that);
464 return *this;
465 }
466
467#if defined (VBOX_WITH_XPCOM)
468 /**
469 * Intended to assign instances to |char *| out parameters from within the
470 * interface method. Transfers the ownership of the duplicated string to the
471 * caller.
472 *
473 * This allocates a single 0 byte in the target if the member string is empty.
474 *
475 * This uses XPCOM memory allocation and thus only works on XPCOM. MSCOM doesn't
476 * like char* strings anyway.
477 */
478 void cloneTo(char **pstr) const;
479#endif
480
481 /**
482 * Intended to assign instances to |BSTR| out parameters from within the
483 * interface method. Transfers the ownership of the duplicated string to the
484 * caller.
485 */
486 void cloneTo(BSTR *pstr) const
487 {
488 if (pstr)
489 {
490 Bstr bstr(*this);
491 bstr.cloneTo(pstr);
492 }
493 }
494
495 /**
496 * Converts "this" to lower case by calling RTStrToLower().
497 * @return
498 */
499 Utf8Str& toLower();
500
501 /**
502 * Converts "this" to upper case by calling RTStrToUpper().
503 * @return
504 */
505 Utf8Str& toUpper();
506
507 /**
508 * Removes a trailing slash from the member string, if present.
509 * Calls RTPathStripTrailingSlash() without having to mess with mutableRaw().
510 */
511 void stripTrailingSlash();
512
513 /**
514 * Removes a trailing filename from the member string, if present.
515 * Calls RTPathStripFilename() without having to mess with mutableRaw().
516 */
517 void stripFilename();
518
519 /**
520 * Removes a trailing file name extension from the member string, if present.
521 * Calls RTPathStripExt() without having to mess with mutableRaw().
522 */
523 void stripExt();
524
525 /**
526 * Attempts to convert the member string into a 32-bit integer.
527 *
528 * @returns 32-bit unsigned number on success.
529 * @returns 0 on failure.
530 */
531 int toInt32() const
532 {
533 return RTStrToInt32(m_psz);
534 }
535
536 /**
537 * Attempts to convert the member string into an unsigned 32-bit integer.
538 *
539 * @returns 32-bit unsigned number on success.
540 * @returns 0 on failure.
541 */
542 int toUInt32() const
543 {
544 return RTStrToUInt32(m_psz);
545 }
546
547 /**
548 * Static immutable null object. May be used for comparison purposes.
549 */
550 static const Utf8Str Null;
551
552protected:
553
554 /**
555 * As with the ministring::copyFrom() variants, this unconditionally
556 * sets the members to a copy of the given other strings and makes
557 * no assumptions about previous contents. This can therefore be used
558 * both in copy constructors, when member variables have no defined
559 * value, and in assignments after having called cleanup().
560 *
561 * This variant converts from a UTF-16 string, most probably from
562 * a Bstr assignment.
563 *
564 * @param rs
565 */
566 void copyFrom(CBSTR s)
567 {
568 if (s && *s)
569 {
570 RTUtf16ToUtf8((PRTUTF16)s, &m_psz); /** @todo r=bird: This isn't throwing std::bad_alloc / handling return codes.
571 * Also, this technically requires using RTStrFree, ministring::cleanup() uses RTMemFree. */
572 m_cbLength = strlen(m_psz); /** @todo optimize by using a different RTUtf* function */
573 m_cbAllocated = m_cbLength + 1;
574 }
575 else
576 {
577 m_cbLength = 0;
578 m_cbAllocated = 0;
579 m_psz = NULL;
580 }
581 }
582
583 friend class Bstr; /* to access our raw_copy() */
584};
585
586/**
587 * This class is a printf-like formatter for Utf8Str strings. Its purpose is
588 * to construct Utf8Str objects from a format string and a list of arguments
589 * for the format string.
590 *
591 * The usage of this class is like the following:
592 * <code>
593 * Utf8StrFmt string ("program name = %s", argv[0]);
594 * </code>
595 */
596class Utf8StrFmt : public Utf8Str
597{
598public:
599
600 /**
601 * Constructs a new string given the format string and the list
602 * of the arguments for the format string.
603 *
604 * @param format printf-like format string (in UTF-8 encoding)
605 * @param ... list of the arguments for the format string
606 */
607 explicit Utf8StrFmt(const char *format, ...)
608 {
609 va_list args;
610 va_start(args, format);
611 init(format, args);
612 va_end(args);
613 }
614
615protected:
616
617 Utf8StrFmt() {}
618
619 void init(const char *format, va_list args);
620
621private:
622
623 static DECLCALLBACK(size_t) strOutput(void *pvArg, const char *pachChars,
624 size_t cbChars);
625};
626
627/**
628 * This class is a vprintf-like formatter for Utf8Str strings. It is
629 * identical to Utf8StrFmt except that its constructor takes a va_list
630 * argument instead of ellipsis.
631 *
632 * Note that a separate class is necessary because va_list is defined as
633 * |char *| on most platforms. For this reason, if we had two overloaded
634 * constructors in Utf8StrFmt (one taking ellipsis and another one taking
635 * va_list) then composing a constructor call using exactly two |char *|
636 * arguments would cause the compiler to use the va_list overload instead of
637 * the ellipsis one which is obviously wrong. The compiler would choose
638 * va_list because ellipsis has the lowest rank when it comes to resolving
639 * overloads, as opposed to va_list which is an exact match for |char *|.
640 */
641class Utf8StrFmtVA : public Utf8StrFmt
642{
643public:
644
645 /**
646 * Constructs a new string given the format string and the list
647 * of the arguments for the format string.
648 *
649 * @param format printf-like format string (in UTF-8 encoding)
650 * @param args list of arguments for the format string
651 */
652 Utf8StrFmtVA(const char *format, va_list args) { init(format, args); }
653};
654
655/**
656 * The BstrFmt class is a shortcut to <tt>Bstr(Utf8StrFmt(...))</tt>.
657 */
658class BstrFmt : public Bstr
659{
660public:
661
662 /**
663 * Constructs a new string given the format string and the list of the
664 * arguments for the format string.
665 *
666 * @param aFormat printf-like format string (in UTF-8 encoding).
667 * @param ... List of the arguments for the format string.
668 */
669 explicit BstrFmt(const char *aFormat, ...)
670 {
671 va_list args;
672 va_start(args, aFormat);
673 copyFrom(Utf8StrFmtVA(aFormat, args).c_str());
674 va_end(args);
675 }
676};
677
678/**
679 * The BstrFmtVA class is a shortcut to <tt>Bstr(Utf8StrFmtVA(...))</tt>.
680 */
681class BstrFmtVA : public Bstr
682{
683public:
684
685 /**
686 * Constructs a new string given the format string and the list of the
687 * arguments for the format string.
688 *
689 * @param aFormat printf-like format string (in UTF-8 encoding).
690 * @param aArgs List of arguments for the format string
691 */
692 BstrFmtVA(const char *aFormat, va_list aArgs)
693 {
694 copyFrom(Utf8StrFmtVA(aFormat, aArgs).c_str());
695 }
696};
697
698} /* namespace com */
699
700#endif /* !___VBox_com_string_h */
701
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