Changeset 26753 in vbox for trunk/include/VBox
- Timestamp:
- Feb 24, 2010 4:24:33 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 58004
- Location:
- trunk/include/VBox/com
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/com/Guid.h
r26603 r26753 96 96 Guid(const Bstr &that) 97 97 { 98 ::RTUuidClear 99 if (!that.is Null())98 ::RTUuidClear(&uuid); 99 if (!that.isEmpty()) 100 100 ::RTUuidFromUtf16(&uuid, that.raw()); 101 101 refresh(); 102 102 } 103 103 104 Guid &operator=(const Guid &that)104 Guid& operator=(const Guid &that) 105 105 { 106 106 ::memcpy(&uuid, &that.uuid, sizeof (RTUUID)); … … 108 108 return *this; 109 109 } 110 Guid &operator=(const GUID &guid)110 Guid& operator=(const GUID &guid) 111 111 { 112 112 ::memcpy(&uuid, &guid, sizeof (GUID)); … … 114 114 return *this; 115 115 } 116 Guid &operator=(const RTUUID &guid)116 Guid& operator=(const RTUUID &guid) 117 117 { 118 118 ::memcpy(&uuid, &guid, sizeof (RTUUID)); … … 120 120 return *this; 121 121 } 122 Guid &operator=(const char *str)122 Guid& operator=(const char *str) 123 123 { 124 124 ::RTUuidFromStr(&uuid, str); … … 145 145 } 146 146 147 Bstr toUtf16 147 Bstr toUtf16() const 148 148 { 149 149 if (isEmpty()) -
trunk/include/VBox/com/string.h
r26603 r26753 49 49 #include "VBox/com/assert.h" 50 50 51 #include <iprt/cpp/utils.h>52 51 #include <iprt/alloc.h> 53 52 #include <iprt/cpp/ministring.h> … … 58 57 class Utf8Str; 59 58 59 // global constant in glue/string.cpp that represents an empty BSTR 60 extern const BSTR g_bstrEmpty; 61 60 62 /** 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. 63 * String class used universally in Main for COM-style Utf-16 strings. 64 * Unfortunately COM on Windows uses UTF-16 everywhere, requiring conversions 65 * back and forth since most of VirtualBox and our libraries use UTF-8. 66 * 67 * To make things more obscure, on Windows, a COM-style BSTR is not just a 68 * pointer to a null-terminated wide character array, but the four bytes 69 * (32 bits) BEFORE the memory that the pointer points to are a length 70 * DWORD. One must therefore avoid pointer arithmetic and always use 71 * SysAllocString and the like to deal with BSTR pointers, which manage 72 * that DWORD correctly. 73 * 74 * For platforms other than Windows, we provide our own versions of the 75 * Sys* functions in Main/xpcom/helpers.cpp which do NOT use length 76 * prefixes though to be compatible with how XPCOM allocates string 77 * parameters to public functions. 78 * 79 * The Bstr class hides all this handling behind a std::string-like interface 80 * and also provides automatic conversions to MiniString and Utf8Str instances. 81 * 82 * The one advantage of using the SysString* routines is that this makes it 83 * possible to use it as a type of member variables of COM/XPCOM components 84 * and pass their values to callers through component methods' output parameters 85 * using the #cloneTo() operation. Also, the class can adopt (take ownership of) 86 * string buffers returned in output parameters of COM methods using the 87 * #asOutParam() operation and correctly free them afterwards. 88 * 89 * Starting with VirtualBox 3.2, like Utf8Str, Bstr no longer differentiates 90 * between NULL strings and empty strings. In other words, Bstr("") and 91 * Bstr(NULL) behave the same. In both cases, Bstr allocates no memory, 92 * reports a zero length and zero allocated bytes for both, and returns an 93 * empty C wide string from raw(). 72 94 */ 73 95 class Bstr … … 75 97 public: 76 98 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); } 99 Bstr() 100 : m_bstr(NULL) 101 { } 102 103 Bstr(const Bstr &that) 104 { 105 copyFrom((const OLECHAR *)that.m_bstr); 106 } 107 108 Bstr(CBSTR that) 109 { 110 copyFrom((const OLECHAR *)that); 111 } 84 112 85 113 #if defined (VBOX_WITH_XPCOM) 86 Bstr(const wchar_t *that) : bstr(NULL)114 Bstr(const wchar_t *that) 87 115 { 88 116 AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR)); 89 raw_copy(bstr, (CBSTR)that); 90 } 91 #endif 92 93 Bstr(const iprt::MiniString &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 } 117 copyFrom((const OLECHAR *)that); 118 } 119 #endif 120 121 Bstr(const iprt::MiniString &that) 122 { 123 copyFrom(that.raw()); 124 } 125 126 Bstr(const char *that) 127 { 128 copyFrom(that); 129 } 130 131 ~Bstr() 132 { 133 setNull(); 134 } 135 136 Bstr& operator=(const Bstr &that) 137 { 138 cleanup(); 139 copyFrom((const OLECHAR *)that.m_bstr); 114 140 return *this; 115 141 } 116 142 117 Bstr &setNullIfEmpty() 118 { 119 if (bstr && *bstr == 0) 120 { 121 ::SysFreeString(bstr); 122 bstr = NULL; 123 } 143 Bstr& operator=(CBSTR that) 144 { 145 cleanup(); 146 copyFrom((const OLECHAR *)that); 124 147 return *this; 125 148 } 126 149 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 } 150 #if defined (VBOX_WITH_XPCOM) 151 Bstr& operator=(const wchar_t *that) 152 { 153 cleanup(); 154 copyFrom((const OLECHAR *)that); 142 155 return *this; 143 156 } 144 145 int compare(CBSTR str) const 146 { 147 return ::RTUtf16Cmp((PRTUTF16) bstr, (PRTUTF16) str); 157 #endif 158 159 Bstr& setNull() 160 { 161 cleanup(); 162 return *this; 163 } 164 165 /** Case sensitivity selector. */ 166 enum CaseSensitivity 167 { 168 CaseSensitive, 169 CaseInsensitive 170 }; 171 172 /** 173 * Compares the member string to str. 174 * @param str 175 * @param cs Whether comparison should be case-sensitive. 176 * @return 177 */ 178 int compare(CBSTR str, CaseSensitivity cs = CaseSensitive) const 179 { 180 if (cs == CaseSensitive) 181 return ::RTUtf16Cmp((PRTUTF16)m_bstr, (PRTUTF16)str); 182 return ::RTUtf16LocaleICmp((PRTUTF16)m_bstr, (PRTUTF16)str); 148 183 } 149 184 150 185 int compare(BSTR str) const 151 186 { 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); }187 return compare((CBSTR)str); 188 } 189 190 bool operator==(const Bstr &that) const { return !compare(that.m_bstr); } 191 bool operator!=(const Bstr &that) const { return !!compare(that.m_bstr); } 157 192 bool operator==(CBSTR that) const { return !compare(that); } 158 193 bool operator==(BSTR that) const { return !compare(that); } 159 194 160 #if defined (VBOX_WITH_XPCOM)161 bool operator!=(const wchar_t *that) const162 {163 AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));164 return !!compare((CBSTR) that);165 }166 bool operator==(const wchar_t *that) const167 {168 AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));169 return !compare((CBSTR) that);170 }171 #endif172 173 195 bool operator!=(CBSTR that) const { return !!compare(that); } 174 196 bool operator!=(BSTR that) const { return !!compare(that); } 175 bool operator<(const Bstr &that) const { return compare(that. bstr) < 0; }197 bool operator<(const Bstr &that) const { return compare(that.m_bstr) < 0; } 176 198 bool operator<(CBSTR that) const { return compare(that) < 0; } 177 199 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; } 200 201 /** 202 * Returns true if the member string has no length. 203 * This is true for instances created from both NULL and "" input strings. 204 * 205 * @note Always use this method to check if an instance is empty. Do not 206 * use length() because that may need to run through the entire string 207 * (Bstr does not cache string lengths). Also do not use operator bool(); 208 * for one, MSVC is really annoying with its thinking that that is ambiguous, 209 * and even though operator bool() is protected with Bstr, at least gcc uses 210 * operator CBSTR() when a construct like "if (string)" is encountered, which 211 * is always true now since it raw() never returns an empty string. Again, 212 * always use isEmpty() even though if (string) may compile! 213 */ 214 bool isEmpty() const { return m_bstr == NULL || *m_bstr == 0; } 215 216 size_t length() const { return isEmpty() ? 0 : ::RTUtf16Len((PRTUTF16)m_bstr); } 217 218 /** 219 * Returns true if the member string is not empty. I'd like to make this 220 * private but since we require operator BSTR() it's futile anyway because 221 * the compiler will then (wrongly) use that one instead. Also if this is 222 * private the odd WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP macro below 223 * will fail on Windows. 224 */ 225 operator bool() const 226 { 227 return m_bstr != NULL; 228 } 229 230 /** 231 * Returns a pointer to the raw member UTF-16 string. If the member string is empty, 232 * returns a pointer to a global variable containing an empty BSTR with a proper zero 233 * length prefix so that Windows is happy. 234 */ 235 CBSTR raw() const 236 { 237 if (m_bstr) 238 return m_bstr; 239 240 return g_bstrEmpty; 241 } 242 243 /** 244 * Convenience operator so that Bstr's can be passed to CBSTR input parameters 245 * of COM methods. 246 */ 247 operator CBSTR() const { return raw(); } 248 249 /** 250 * Convenience operator so that Bstr's can be passed to CBSTR input parameters 251 * of COM methods. Unfortunately this is required for Windows since with 252 * MSCOM, input BSTR parameters of interface methods are not const. 253 */ 254 operator BSTR() { return (BSTR)raw(); } 213 255 214 256 /** 215 257 * Returns a non-const raw pointer that allows to modify the string directly. 258 * As opposed to raw(), this DOES return NULL if the member string is empty 259 * because we cannot return a mutable pointer to the global variable with the 260 * empty string. 261 * 216 262 * @warning 217 263 * Be sure not to modify data beyond the allocated memory! The … … 219 265 * bytes after creation and after every assignment operation. 220 266 */ 221 BSTR mutableRaw() { return bstr; }267 BSTR mutableRaw() { return m_bstr; } 222 268 223 269 /** … … 225 271 * within the interface method. Transfers the ownership of the duplicated 226 272 * string to the caller. 227 */ 228 const Bstr &cloneTo(BSTR *pstr) const 273 * 274 * If the member string is empty, this allocates an empty BSTR in *pstr 275 * (i.e. makes it point to a new buffer with a null byte). 276 */ 277 void cloneTo(BSTR *pstr) const 229 278 { 230 279 if (pstr) 231 280 { 232 *pstr = NULL; 233 raw_copy(*pstr, bstr); 281 *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty 282 #ifdef RT_EXCEPTIONS_ENABLED 283 if (!*pstr) 284 throw std::bad_alloc(); 285 #endif 234 286 } 235 return *this;236 287 } 237 288 … … 243 294 * As opposed to cloneTo(), this method doesn't create a copy of the 244 295 * 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; 296 * 297 * If the member string is empty, this allocates an empty BSTR in *pstr 298 * (i.e. makes it point to a new buffer with a null byte). 299 */ 300 void detachTo(BSTR *pstr) 301 { 302 if (m_bstr) 303 *pstr = m_bstr; 304 else 305 { 306 // allocate null BSTR 307 *pstr = ::SysAllocString((const OLECHAR *)g_bstrEmpty); 308 #ifdef RT_EXCEPTIONS_ENABLED 309 if (!*pstr) 310 throw std::bad_alloc(); 311 #endif 312 } 313 m_bstr = NULL; 314 } 259 315 260 316 /** … … 262 318 * Takes the ownership of the returned data. 263 319 */ 264 BSTR *asOutParam() { setNull(); return &bstr; } 320 BSTR* asOutParam() 321 { 322 cleanup(); 323 return &m_bstr; 324 } 265 325 266 326 /** … … 271 331 protected: 272 332 273 void safe_assign(CBSTR str)274 { 275 if ( bstr !=str)333 void cleanup() 334 { 335 if (m_bstr) 276 336 { 277 setNull();278 raw_copy(bstr, str);337 ::SysFreeString(m_bstr); 338 m_bstr = NULL; 279 339 } 280 340 } 281 341 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) 342 /** 343 * Protected internal helper to copy a string. This ignores the previous object 344 * state, so either call this from a constructor or call cleanup() first. 345 * 346 * This variant copies from a zero-terminated UTF-16 string (which need not 347 * be a BSTR, i.e. need not have a length prefix). 348 * 349 * If the source is empty, this sets the member string to NULL. 350 * @param rs 351 */ 352 void copyFrom(const OLECHAR *rs) 353 { 354 if (rs && *rs) 355 { 356 m_bstr = ::SysAllocString(rs); 357 #ifdef RT_EXCEPTIONS_ENABLED 358 if (!m_bstr) 359 throw std::bad_alloc(); 360 #endif 361 } 362 else 363 m_bstr = NULL; 364 } 365 366 /** 367 * Protected internal helper to copy a string. This ignores the previous object 368 * state, so either call this from a constructor or call cleanup() first. 369 * 370 * This variant copies and converts from a zero-terminated UTF-8 string. 371 * 372 * If the source is empty, this sets the member string to NULL. 373 * @param rs 374 */ 375 void copyFrom(const char *rs) 376 { 377 if (rs && *rs) 291 378 { 292 379 PRTUTF16 s = NULL; 293 380 ::RTStrToUtf16(rs, &s); 294 raw_copy(ls, (BSTR)s); 381 #ifdef RT_EXCEPTIONS_ENABLED 382 if (!s) 383 throw std::bad_alloc(); 384 #endif 385 copyFrom((const OLECHAR *)s); // allocates BSTR from zero-terminated input string 295 386 ::RTUtf16Free(s); 296 387 } 297 } 298 299 BSTR bstr; 388 else 389 m_bstr = NULL; 390 } 391 392 BSTR m_bstr; 300 393 301 394 friend class Utf8Str; /* to access our raw_copy() */ … … 308 401 inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!=(l); } 309 402 403 // work around error C2593 of the stupid MSVC 7.x ambiguity resolver 404 WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Bstr) 405 310 406 //////////////////////////////////////////////////////////////////////////////// 311 407 312 408 /** 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. 409 * String class used universally in Main for UTF-8 strings. 410 * 411 * This is based on iprt::MiniString, to which some functionality has been 412 * moved. Here we keep things that are specific to Main, such as conversions 413 * with UTF-16 strings (Bstr). 414 * 415 * Like iprt::MiniString, Utf8Str does not differentiate between NULL strings 416 * and empty strings. In other words, Utf8Str("") and Utf8Str(NULL) 417 * behave the same. In both cases, MiniString allocates no memory, reports 418 * a zero length and zero allocated bytes for both, and returns an empty 419 * C string from c_str(). 325 420 */ 326 421 class Utf8Str : public iprt::MiniString … … 374 469 } 375 470 471 #if defined (VBOX_WITH_XPCOM) 376 472 /** 377 473 * Intended to assign instances to |char *| out parameters from within the … … 379 475 * caller. 380 476 * 381 * @remarks The returned string must be freed by RTStrFree, not RTMemFree. 382 */ 383 const Utf8Str& cloneTo(char **pstr) const 384 { 385 if (pstr) /** @todo r=bird: This needs to if m_psz is NULL. Shouldn't it also throw std::bad_alloc? */ 386 *pstr = RTStrDup(m_psz); 387 return *this; 388 } 389 390 /** 391 * Intended to assign instances to |char *| out parameters from within the 392 * interface method. Transfers the ownership of the original string to the 393 * caller and resets the instance to null. 394 * 395 * As opposed to cloneTo(), this method doesn't create a copy of the 396 * string. 397 */ 398 Utf8Str& detachTo(char **pstr) 399 { 400 *pstr = m_psz; 401 m_psz = NULL; 402 m_cbAllocated = 0; 403 m_cbLength = 0; 404 return *this; 405 } 477 * This allocates a single 0 byte in the target if the member string is empty. 478 * 479 * This uses XPCOM memory allocation and thus only works on XPCOM. MSCOM doesn't 480 * like char* strings anyway. 481 */ 482 void cloneTo(char **pstr) const; 483 #endif 406 484 407 485 /** … … 410 488 * caller. 411 489 */ 412 const Utf8Str&cloneTo(BSTR *pstr) const490 void cloneTo(BSTR *pstr) const 413 491 { 414 492 if (pstr) 415 493 { 416 *pstr = NULL;417 Bstr::raw_copy(*pstr, m_psz);494 Bstr bstr(*this); 495 bstr.cloneTo(pstr); 418 496 } 419 return *this;420 497 } 421 498 … … 505 582 void copyFrom(CBSTR s) 506 583 { 507 if (s )584 if (s && *s) 508 585 { 509 586 RTUtf16ToUtf8((PRTUTF16)s, &m_psz); /** @todo r=bird: This isn't throwing std::bad_alloc / handling return codes. … … 523 600 }; 524 601 525 // work around error C2593 of the stupid MSVC 7.x ambiguity resolver526 WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Bstr)527 528 ////////////////////////////////////////////////////////////////////////////////529 530 // inlined Bstr members that depend on Utf8Str531 532 inline Bstr::Bstr(const iprt::MiniString &that)533 : bstr(NULL)534 {535 raw_copy(bstr, that.c_str());536 }537 538 inline Bstr::Bstr(const char *that)539 : bstr(NULL)540 {541 raw_copy(bstr, that);542 }543 544 inline Bstr &Bstr::operator=(const Utf8Str &that)545 {546 setNull();547 raw_copy(bstr, that.c_str());548 return *this;549 }550 inline Bstr &Bstr::operator=(const char *that)551 {552 setNull();553 raw_copy(bstr, that);554 return *this;555 }556 557 inline const Bstr& Bstr::cloneTo(char **pstr) const558 {559 if (pstr)560 {561 Utf8Str ustr(*this);562 ustr.detachTo(pstr);563 }564 return *this;565 }566 567 ////////////////////////////////////////////////////////////////////////////////568 569 602 /** 570 603 * This class is a printf-like formatter for Utf8Str strings. Its purpose is … … 654 687 va_list args; 655 688 va_start(args, aFormat); 656 raw_copy(bstr,Utf8StrFmtVA(aFormat, args).c_str());689 copyFrom(Utf8StrFmtVA(aFormat, args).c_str()); 657 690 va_end(args); 658 691 } … … 675 708 BstrFmtVA(const char *aFormat, va_list aArgs) 676 709 { 677 raw_copy(bstr,Utf8StrFmtVA(aFormat, aArgs).c_str());710 copyFrom(Utf8StrFmtVA(aFormat, aArgs).c_str()); 678 711 } 679 712 };
Note:
See TracChangeset
for help on using the changeset viewer.