Changeset 73907 in vbox for trunk/src/VBox/Runtime/common/string
- Timestamp:
- Aug 27, 2018 9:54:04 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/string/ministring.cpp
r69111 r73907 66 66 } 67 67 68 int RTCString::assignNoThrow(const RTCString &a_rSrc) RT_NOEXCEPT 69 { 70 AssertReturn(&a_rSrc != this, VINF_SUCCESS); 71 size_t const cchSrc = a_rSrc.length(); 72 if (cchSrc > 0) 73 { 74 int rc = reserveNoThrow(cchSrc + 1); 75 if (RT_SUCCESS(rc)) 76 { 77 memcpy(m_psz, a_rSrc.c_str(), cchSrc); 78 m_psz[cchSrc] = '\0'; 79 m_cch = cchSrc; 80 return VINF_SUCCESS; 81 } 82 return rc; 83 } 84 setNull(); 85 return VINF_SUCCESS; 86 87 } 88 68 89 RTCString &RTCString::assign(const char *a_pszSrc) 69 90 { … … 82 103 setNull(); 83 104 return *this; 105 } 106 107 int RTCString::assignNoThrow(const char *a_pszSrc) RT_NOEXCEPT 108 { 109 if (a_pszSrc) 110 { 111 size_t cchSrc = strlen(a_pszSrc); 112 if (cchSrc) 113 { 114 int rc = reserveNoThrow(cchSrc + 1); 115 if (RT_SUCCESS(rc)) 116 { 117 memcpy(m_psz, a_pszSrc, cchSrc); 118 m_psz[cchSrc] = '\0'; 119 m_cch = cchSrc; 120 return VINF_SUCCESS; 121 } 122 return rc; 123 } 124 } 125 setNull(); 126 return VINF_SUCCESS; 84 127 } 85 128 … … 102 145 } 103 146 147 int RTCString::assignNoThrow(const RTCString &a_rSrc, size_t a_offSrc, size_t a_cchSrc /*= npos*/) RT_NOEXCEPT 148 { 149 AssertReturn(&a_rSrc != this, VINF_SUCCESS); 150 if (a_offSrc < a_rSrc.length()) 151 { 152 size_t cchMax = a_rSrc.length() - a_offSrc; 153 if (a_cchSrc > cchMax) 154 a_cchSrc = cchMax; 155 int rc = reserveNoThrow(a_cchSrc + 1); 156 if (RT_SUCCESS(rc)) 157 { 158 memcpy(m_psz, a_rSrc.c_str() + a_offSrc, a_cchSrc); 159 m_psz[a_cchSrc] = '\0'; 160 m_cch = a_cchSrc; 161 return VINF_SUCCESS; 162 } 163 return rc; 164 } 165 setNull(); 166 return VINF_SUCCESS; 167 } 168 104 169 RTCString &RTCString::assign(const char *a_pszSrc, size_t a_cchSrc) 105 170 { … … 117 182 } 118 183 184 int RTCString::assignNoThrow(const char *a_pszSrc, size_t a_cchSrc) RT_NOEXCEPT 185 { 186 if (a_cchSrc) 187 { 188 a_cchSrc = RTStrNLen(a_pszSrc, a_cchSrc); 189 int rc = reserveNoThrow(a_cchSrc + 1); 190 if (RT_SUCCESS(rc)) 191 { 192 memcpy(m_psz, a_pszSrc, a_cchSrc); 193 m_psz[a_cchSrc] = '\0'; 194 m_cch = a_cchSrc; 195 return VINF_SUCCESS; 196 } 197 return rc; 198 } 199 setNull(); 200 return VINF_SUCCESS; 201 } 202 119 203 RTCString &RTCString::assign(size_t a_cTimes, char a_ch) 120 204 { … … 122 206 memset(m_psz, a_ch, a_cTimes); 123 207 return *this; 208 } 209 210 211 int RTCString::assignNoThrow(size_t a_cTimes, char a_ch) RT_NOEXCEPT 212 { 213 int rc = reserveNoThrow(a_cTimes + 1); 214 if (RT_SUCCESS(rc)) 215 { 216 memset(m_psz, a_ch, a_cTimes); 217 return VINF_SUCCESS; 218 } 219 return rc; 124 220 } 125 221 … … 132 228 va_end(va); 133 229 return *this; 230 } 231 232 int RTCString::printfNoThrow(const char *pszFormat, ...) RT_NOEXCEPT 233 { 234 va_list va; 235 va_start(va, pszFormat); 236 int rc = printfVNoThrow(pszFormat, va); 237 va_end(va); 238 return rc; 134 239 } 135 240 … … 149 254 if (cbChars) 150 255 { 151 size_t c chBoth = pThis->m_cch + cbChars;256 size_t const cchBoth = pThis->m_cch + cbChars; 152 257 if (cchBoth >= pThis->m_cbAllocated) 153 258 { … … 178 283 } 179 284 285 struct RTCSTRINGOTHROW 286 { 287 RTCString *pThis; 288 int rc; 289 }; 290 291 /** 292 * Callback used with RTStrFormatV by RTCString::printfVNoThrow. 293 * 294 * @returns The number of bytes added (not used). 295 * 296 * @param pvArg Pointer to a RTCSTRINGOTHROW structure. 297 * @param pachChars The characters to append. 298 * @param cbChars The number of characters. 0 on the final callback. 299 */ 300 /*static*/ DECLCALLBACK(size_t) 301 RTCString::printfOutputCallbackNoThrow(void *pvArg, const char *pachChars, size_t cbChars) RT_NOEXCEPT 302 { 303 RTCString *pThis = ((RTCSTRINGOTHROW *)pvArg)->pThis; 304 if (cbChars) 305 { 306 size_t const cchBoth = pThis->m_cch + cbChars; 307 if (cchBoth >= pThis->m_cbAllocated) 308 { 309 /* Double the buffer size, if it's less that _4M. Align sizes like 310 for append. */ 311 size_t cbAlloc = RT_ALIGN_Z(pThis->m_cbAllocated, IPRT_MINISTRING_APPEND_ALIGNMENT); 312 cbAlloc += RT_MIN(cbAlloc, _4M); 313 if (cbAlloc <= cchBoth) 314 cbAlloc = RT_ALIGN_Z(cchBoth + 1, IPRT_MINISTRING_APPEND_ALIGNMENT); 315 int rc = pThis->reserveNoThrow(cbAlloc); 316 if (RT_SUCCESS(rc)) 317 { /* likely */ } 318 else 319 { 320 ((RTCSTRINGOTHROW *)pvArg)->rc = rc; 321 return cbChars; 322 } 323 } 324 325 memcpy(&pThis->m_psz[pThis->m_cch], pachChars, cbChars); 326 pThis->m_cch = cchBoth; 327 pThis->m_psz[cchBoth] = '\0'; 328 } 329 return cbChars; 330 } 331 332 int RTCString::printfVNoThrow(const char *pszFormat, va_list va) RT_NOEXCEPT 333 { 334 cleanup(); 335 RTCSTRINGOTHROW Args = { this, VINF_SUCCESS }; 336 RTStrFormatV(printfOutputCallback, &Args, NULL, NULL, pszFormat, va); 337 return Args.rc; 338 } 339 180 340 RTCString &RTCString::append(const RTCString &that) 181 341 { … … 184 344 } 185 345 346 int RTCString::appendNoThrow(const RTCString &that) RT_NOEXCEPT 347 { 348 Assert(&that != this); 349 return appendWorkerNoThrow(that.c_str(), that.length()); 350 } 351 186 352 RTCString &RTCString::append(const char *pszThat) 187 353 { 188 354 return appendWorker(pszThat, strlen(pszThat)); 355 } 356 357 int RTCString::appendNoThrow(const char *pszThat) RT_NOEXCEPT 358 { 359 return appendWorkerNoThrow(pszThat, strlen(pszThat)); 189 360 } 190 361 … … 199 370 } 200 371 372 int RTCString::appendNoThrow(const RTCString &rThat, size_t offStart, size_t cchMax /*= RTSTR_MAX*/) RT_NOEXCEPT 373 { 374 if (offStart < rThat.length()) 375 { 376 size_t cchLeft = rThat.length() - offStart; 377 return appendWorkerNoThrow(rThat.c_str() + offStart, RT_MIN(cchLeft, cchMax)); 378 } 379 return VINF_SUCCESS; 380 } 381 201 382 RTCString &RTCString::append(const char *pszThat, size_t cchMax) 202 383 { 203 384 return appendWorker(pszThat, RTStrNLen(pszThat, cchMax)); 385 } 386 387 int RTCString::appendNoThrow(const char *pszThat, size_t cchMax) RT_NOEXCEPT 388 { 389 return appendWorkerNoThrow(pszThat, RTStrNLen(pszThat, cchMax)); 204 390 } 205 391 … … 227 413 } 228 414 415 int RTCString::appendWorkerNoThrow(const char *pszSrc, size_t cchSrc) RT_NOEXCEPT 416 { 417 if (cchSrc) 418 { 419 size_t cchThis = length(); 420 size_t cchBoth = cchThis + cchSrc; 421 422 if (cchBoth >= m_cbAllocated) 423 { 424 int rc = reserveNoThrow(RT_ALIGN_Z(cchBoth + 1, IPRT_MINISTRING_APPEND_ALIGNMENT)); 425 if (RT_SUCCESS(rc)) 426 { /* likely */ } 427 else 428 return rc; 429 } 430 431 memcpy(&m_psz[cchThis], pszSrc, cchSrc); 432 m_psz[cchBoth] = '\0'; 433 m_cch = cchBoth; 434 } 435 return VINF_SUCCESS; 436 } 437 229 438 RTCString &RTCString::append(char ch) 230 439 { … … 248 457 } 249 458 459 int RTCString::appendNoThrow(char ch) RT_NOEXCEPT 460 { 461 Assert((unsigned char)ch < 0x80); /* Don't create invalid UTF-8. */ 462 if (ch) 463 { 464 // allocate in chunks of 20 in case this gets called several times 465 if (m_cch + 1 >= m_cbAllocated) 466 { 467 int rc = reserveNoThrow(RT_ALIGN_Z(m_cch + 2, IPRT_MINISTRING_APPEND_ALIGNMENT)); 468 if (RT_SUCCESS(rc)) 469 { /* likely */ } 470 else 471 return rc; 472 } 473 474 m_psz[m_cch] = ch; 475 m_psz[++m_cch] = '\0'; 476 } 477 return VINF_SUCCESS; 478 } 479 250 480 RTCString &RTCString::appendCodePoint(RTUNICP uc) 251 481 { … … 278 508 } 279 509 510 int RTCString::appendCodePointNoThrow(RTUNICP uc) RT_NOEXCEPT 511 { 512 /* 513 * Single byte encoding. 514 */ 515 if (uc < 0x80) 516 return RTCString::appendNoThrow((char)uc); 517 518 /* 519 * Multibyte encoding. 520 * Assume max encoding length when resizing the string, that's simpler. 521 */ 522 AssertReturn(uc <= UINT32_C(0x7fffffff), VERR_INVALID_UTF8_ENCODING); 523 524 if (m_cch + 6 >= m_cbAllocated) 525 { 526 int rc = reserveNoThrow(RT_ALIGN_Z(m_cch + 6 + 1, IPRT_MINISTRING_APPEND_ALIGNMENT)); 527 if (RT_SUCCESS(rc)) 528 { /* likely */ } 529 else 530 return rc; 531 } 532 533 char *pszNext = RTStrPutCp(&m_psz[m_cch], uc); 534 m_cch = pszNext - m_psz; 535 *pszNext = '\0'; 536 537 return VINF_SUCCESS; 538 } 539 540 280 541 RTCString &RTCString::erase(size_t offStart /*= 0*/, size_t cchLength /*= npos*/) 281 542 { … … 306 567 } 307 568 569 int RTCString::replaceNoThrow(size_t offStart, size_t cchLength, const RTCString &rStrReplacement) RT_NOEXCEPT 570 { 571 return replaceWorkerNoThrow(offStart, cchLength, rStrReplacement.c_str(), rStrReplacement.length()); 572 } 573 308 574 RTCString &RTCString::replace(size_t offStart, size_t cchLength, const RTCString &rStrReplacement, 309 575 size_t offReplacement, size_t cchReplacement) … … 325 591 } 326 592 593 int RTCString::replaceNoThrow(size_t offStart, size_t cchLength, const RTCString &rStrReplacement, 594 size_t offReplacement, size_t cchReplacement) 595 { 596 Assert(this != &rStrReplacement); 597 if (cchReplacement > 0) 598 { 599 if (offReplacement < rStrReplacement.length()) 600 { 601 size_t cchMaxReplacement = rStrReplacement.length() - offReplacement; 602 return replaceWorkerNoThrow(offStart, cchLength, rStrReplacement.c_str() + offReplacement, 603 RT_MIN(cchReplacement, cchMaxReplacement)); 604 } 605 return VERR_OUT_OF_RANGE; 606 } 607 return replaceWorkerNoThrow(offStart, cchLength, "", 0); 608 } 609 327 610 RTCString &RTCString::replace(size_t offStart, size_t cchLength, const char *pszReplacement) 328 611 { … … 330 613 } 331 614 615 int RTCString::replaceNoThrow(size_t offStart, size_t cchLength, const char *pszReplacement) RT_NOEXCEPT 616 { 617 return replaceWorkerNoThrow(offStart, cchLength, pszReplacement, strlen(pszReplacement)); 618 } 619 332 620 RTCString &RTCString::replace(size_t offStart, size_t cchLength, const char *pszReplacement, size_t cchReplacement) 333 621 { 334 622 return replaceWorker(offStart, cchLength, pszReplacement, RTStrNLen(pszReplacement, cchReplacement)); 623 } 624 625 int RTCString::replaceNoThrow(size_t offStart, size_t cchLength, const char *pszReplacement, size_t cchReplacement) RT_NOEXCEPT 626 { 627 return replaceWorkerNoThrow(offStart, cchLength, pszReplacement, RTStrNLen(pszReplacement, cchReplacement)); 335 628 } 336 629 … … 375 668 376 669 return *this; 670 } 671 672 int RTCString::replaceWorkerNoThrow(size_t offStart, size_t cchLength, const char *pszSrc, size_t cchSrc) RT_NOEXCEPT 673 { 674 /* 675 * Our non-standard handling of out_of_range situations. 676 */ 677 size_t const cchOldLength = length(); 678 AssertMsgReturn(offStart < cchOldLength, ("offStart=%zu (cchLength=%zu); length()=%zu\n", offStart, cchLength, cchOldLength), 679 VERR_OUT_OF_RANGE); 680 681 /* 682 * Correct the length parameter. 683 */ 684 size_t cchMaxLength = cchOldLength - offStart; 685 if (cchMaxLength < cchLength) 686 cchLength = cchMaxLength; 687 688 /* 689 * Adjust string allocation if necessary. 690 */ 691 size_t cchNew = cchOldLength - cchLength + cchSrc; 692 if (cchNew >= m_cbAllocated) 693 { 694 int rc = reserveNoThrow(RT_ALIGN_Z(cchNew + 1, IPRT_MINISTRING_APPEND_ALIGNMENT)); 695 if (RT_SUCCESS(rc)) 696 { /* likely */ } 697 else 698 return rc; 699 } 700 701 /* 702 * Make the change. 703 */ 704 size_t cchAfter = cchOldLength - offStart - cchLength; 705 if (cchAfter > 0) 706 memmove(&m_psz[offStart + cchSrc], &m_psz[offStart + cchLength], cchAfter); 707 memcpy(&m_psz[offStart], pszSrc, cchSrc); 708 m_psz[cchNew] = '\0'; 709 m_cch = cchNew; 710 711 return VINF_SUCCESS; 377 712 } 378 713
Note:
See TracChangeset
for help on using the changeset viewer.