Changeset 80835 in vbox
- Timestamp:
- Sep 16, 2019 8:30:40 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 133405
- Location:
- trunk
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/com/string.h
r80793 r80835 386 386 387 387 /** 388 * Returns a non-const raw pointer that allows to modify the string directly. 389 * As opposed to raw(), this DOES return NULL if the member string is empty 390 * because we cannot return a mutable pointer to the global variable with the 391 * empty string. 392 * 393 * @warning 394 * Be sure not to modify data beyond the allocated memory! The 395 * guaranteed size of the allocated memory is at least #length() 396 * bytes after creation and after every assignment operation. 388 * Returns a non-const raw pointer that allows modifying the string directly. 389 * 390 * @note As opposed to raw(), this DOES return NULL if the member string is 391 * empty because we cannot return a mutable pointer to the global variable 392 * with the empty string. 393 * 394 * @note If modifying the string size (only shrinking it is allows), #jolt() or 395 * #joltNoThrow() must be called! 396 * 397 * @note Do not modify memory beyond the #length() of the string! 398 * 399 * @sa joltNoThrow(), mutalbleRaw(), reserve(), reserveNoThrow() 397 400 */ 398 401 BSTR mutableRaw() { return m_bstr; } 402 403 /** 404 * Correct the embedded length after using mutableRaw(). 405 * 406 * This is needed on COM (Windows) to update the embedded string length. It is 407 * a stub on hosts using XPCOM. 408 * 409 * @param cwcNew The new string length, if handy, otherwise a negative 410 * number. 411 * @sa joltNoThrow(), mutalbleRaw(), reserve(), reserveNoThrow() 412 */ 413 #ifndef VBOX_WITH_XPCOM 414 void jolt(ssize_t cwcNew = -1); 415 #else 416 void jolt(ssize_t cwcNew = -1) 417 { 418 Assert(cwcNew < 0 || (cwcNew == 0 && !m_bstr) || m_bstr[cwcNew] == '\0'); RT_NOREF(cwcNew); 419 } 420 #endif 421 422 /** 423 * Correct the embedded length after using mutableRaw(). 424 * 425 * This is needed on COM (Windows) to update the embedded string length. It is 426 * a stub on hosts using XPCOM. 427 * 428 * @returns S_OK on success, E_OUTOFMEMORY if shrinking the string failed. 429 * @param cwcNew The new string length, if handy, otherwise a negative 430 * number. 431 * @sa jolt(), mutalbleRaw(), reserve(), reserveNoThrow() 432 */ 433 #ifndef VBOX_WITH_XPCOM 434 HRESULT joltNoThrow(ssize_t cwcNew = -1) RT_NOEXCEPT; 435 #else 436 HRESULT joltNoThrow(ssize_t cwcNew = -1) RT_NOEXCEPT 437 { 438 Assert(cwcNew < 0 || (cwcNew == 0 && !m_bstr) || m_bstr[cwcNew] == '\0'); RT_NOREF(cwcNew); 439 return S_OK; 440 } 441 #endif 442 443 /** 444 * Make sure at that least @a cwc of buffer space is reserved. 445 * 446 * Requests that the contained memory buffer have at least cb bytes allocated. 447 * This may expand or shrink the string's storage, but will never truncate the 448 * contained string. In other words, cb will be ignored if it's smaller than 449 * length() + 1. 450 * 451 * @param cwcMin The new minimum string length that the can be stored. This 452 * does not include the terminator. 453 * @param fForce Force this size. 454 * 455 * @throws std::bad_alloc On allocation error. The object is left unchanged. 456 */ 457 void reserve(size_t cwcMin, bool fForce = false); 458 459 /** 460 * A C like version of the #reserve() method, i.e. return code instead of throw. 461 * 462 * @returns S_OK or E_OUTOFMEMORY. 463 * @param cwcMin The new minimum string length that the can be stored. This 464 * does not include the terminator. 465 * @param fForce Force this size. 466 */ 467 HRESULT reserveNoThrow(size_t cwcMin, bool fForce = false) RT_NOEXCEPT; 399 468 400 469 /** -
trunk/src/VBox/Main/glue/string.cpp
r80793 r80835 112 112 if (cwcAlloc <= cwcBoth) 113 113 cwcAlloc = RT_ALIGN_Z(cwcBoth + 1, 512); 114 if (pArgs->cwcAlloc) 115 AssertMsgReturnStmt(::SysReAllocStringLen(&pThis->m_bstr, NULL, (unsigned)cwcAlloc), 116 ("cwcAlloc=%#zx\n", cwcAlloc), pArgs->hrc = E_OUTOFMEMORY, 0); 117 else 118 { 119 Assert(pThis->m_bstr == NULL); 120 pThis->m_bstr = ::SysAllocStringLen(NULL, (unsigned)cwcAlloc); 121 AssertMsgReturnStmt(pThis->m_bstr, ("cwcAlloc=%#zx\n", cwcAlloc), pArgs->hrc = E_OUTOFMEMORY, 0); 122 } 114 pArgs->hrc = pThis->reserveNoThrow(cwcAlloc, true /*fForce*/); 115 AssertMsgReturn(pArgs->hrc == S_OK, ("cwcAlloc=%#zx\n", cwcAlloc), 0); 123 116 pArgs->cwcAlloc = cwcAlloc; 124 117 } … … 134 127 rc = ::RTStrToUtf16Ex(pachChars, cbChars, &pwszDst, pArgs->cwcAlloc - pArgs->offDst, &cwcAppend); 135 128 AssertRCReturnStmt(rc, pArgs->hrc = E_UNEXPECTED, 0); 129 pArgs->offDst += cwcAppend; 136 130 } 137 131 return cbChars; … … 142 136 cleanup(); 143 137 BSTRNOTHROW Args = { this, 0, 0, S_OK }; 144 RTStrFormatV(printfOutputCallbackNoThrow, this, NULL, NULL, pszFormat, va);138 RTStrFormatV(printfOutputCallbackNoThrow, &Args, NULL, NULL, pszFormat, va); 145 139 if (Args.hrc == S_OK) 146 140 { 147 #ifdef RT_OS_WINDOWS 148 if (Args. offDst + 1 == Args.cwcAlloc)141 Args.hrc = joltNoThrow(Args.offDst); 142 if (Args.hrc == S_OK) 149 143 return S_OK; 150 151 /* Official way: Reallocate the string. We could of course just update the size-prefix if we dare... */152 if (SysReAllocStringLen(&m_bstr, NULL, (unsigned)(Args.offDst + 1)))153 return S_OK;154 AssertMsgFailed(("offDst=%#zx\n", Args.offDst));155 Args.hrc = E_OUTOFMEMORY;156 #else157 return S_OK;158 #endif159 144 } 160 145 cleanup(); … … 244 229 245 230 231 #ifndef VBOX_WITH_XPCOM 232 233 HRESULT Bstr::joltNoThrow(ssize_t cwcNew /* = -1*/) 234 { 235 if (m_bstr) 236 { 237 size_t const cwcAlloc = ::SysStringLen(m_bstr); 238 size_t const cwcActual = cwcNew < 0 ? ::RTUtf16Len(m_bstr) : (size_t)cwcNew; 239 Assert(cwcNew < 0 || cwcActual == ::RTUtf16Len(m_bstr)); 240 if (cwcActual != cwcAlloc) 241 { 242 Assert(cwcActual <= cwcAlloc); 243 Assert((unsigned int)cwcActual == cwcActual); 244 245 /* Official way: Reallocate the string. We could of course just update the size-prefix if we dared... */ 246 if (!::SysReAllocStringLen(&m_bstr, NULL, (unsigned int)cwcActual)) 247 { 248 AssertFailed(); 249 return E_OUTOFMEMORY; 250 } 251 } 252 } 253 else 254 Assert(cwcNew <= 0); 255 return S_OK; 256 } 257 258 259 void Bstr::jolt(ssize_t cwcNew /* = -1*/) 260 { 261 HRESULT hrc = joltNoThrow(cwcNew); 262 if (hrc != S_OK) 263 throw std::bad_alloc(); 264 } 265 266 #endif /* !VBOX_WITH_XPCOM */ 267 268 269 HRESULT Bstr::reserveNoThrow(size_t cwcMin, bool fForce /*= false*/) RT_NOEXCEPT 270 { 271 /* If not forcing the string to the cwcMin length, check cwcMin against the 272 current string length: */ 273 if (!fForce) 274 { 275 size_t cwcCur = m_bstr ? ::SysStringLen(m_bstr) : 0; 276 if (cwcCur >= cwcMin) 277 return S_OK; 278 } 279 280 /* The documentation for SysReAllocStringLen hints about it being allergic 281 to NULL in some way or another, so we call SysAllocStringLen directly 282 when appropriate: */ 283 if (m_bstr) 284 AssertReturn(::SysReAllocStringLen(&m_bstr, NULL, (unsigned int)cwcMin) != FALSE, E_OUTOFMEMORY); 285 else if (cwcMin > 0) 286 { 287 m_bstr = ::SysAllocStringLen(NULL, (unsigned int)cwcMin); 288 AssertReturn(m_bstr, E_OUTOFMEMORY); 289 } 290 291 return S_OK; 292 } 293 294 295 void Bstr::reserve(size_t cwcMin, bool fForce /*= false*/) 296 { 297 HRESULT hrc = reserveNoThrow(cwcMin, fForce); 298 if (hrc != S_OK) 299 throw std::bad_alloc(); 300 } 301 302 246 303 /* static */ 247 304 const Utf8Str Utf8Str::Empty; /* default ctor is OK */ -
trunk/src/VBox/Main/testcase/Makefile.kmk
r76553 r80835 36 36 $(if $(VBOX_WITH_GUEST_CONTROL),tstGuestCtrlContextID,) \ 37 37 tstMediumLock \ 38 tstBstr \ 38 39 tstGuid 39 40 PROGRAMS.linux += \ … … 254 255 255 256 # 257 # tstBstr 258 # 259 tstBstr_TEMPLATE = VBOXMAINCLIENTTSTEXE 260 tstBstr_SOURCES = tstBstr.cpp 261 262 263 # 256 264 # tstGuid 257 265 #
Note:
See TracChangeset
for help on using the changeset viewer.