1/* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef StringConcatenate_h 27#define StringConcatenate_h 28 29#include <string.h> 30 31#ifndef AtomicString_h 32#include <wtf/text/AtomicString.h> 33#endif 34 35// This macro is helpful for testing how many intermediate Strings are created while evaluating an 36// expression containing operator+. 37#ifndef WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING 38#define WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING() ((void)0) 39#endif 40 41namespace WTF { 42 43template<typename StringType> 44class StringTypeAdapter { 45}; 46 47template<> 48class StringTypeAdapter<char> { 49public: 50 StringTypeAdapter<char>(char buffer) 51 : m_buffer(buffer) 52 { 53 } 54 55 unsigned length() { return 1; } 56 57 bool is8Bit() { return true; } 58 59 void writeTo(LChar* destination) 60 { 61 *destination = m_buffer; 62 } 63 64 void writeTo(UChar* destination) { *destination = m_buffer; } 65 66private: 67 unsigned char m_buffer; 68}; 69 70template<> 71class StringTypeAdapter<LChar> { 72public: 73 StringTypeAdapter<LChar>(LChar buffer) 74 : m_buffer(buffer) 75 { 76 } 77 78 unsigned length() { return 1; } 79 80 bool is8Bit() { return true; } 81 82 void writeTo(LChar* destination) 83 { 84 *destination = m_buffer; 85 } 86 87 void writeTo(UChar* destination) { *destination = m_buffer; } 88 89private: 90 LChar m_buffer; 91}; 92 93template<> 94class StringTypeAdapter<UChar> { 95public: 96 StringTypeAdapter<UChar>(UChar buffer) 97 : m_buffer(buffer) 98 { 99 } 100 101 unsigned length() { return 1; } 102 103 bool is8Bit() { return m_buffer <= 0xff; } 104 105 void writeTo(LChar* destination) 106 { 107 ASSERT(is8Bit()); 108 *destination = static_cast<LChar>(m_buffer); 109 } 110 111 void writeTo(UChar* destination) { *destination = m_buffer; } 112 113private: 114 UChar m_buffer; 115}; 116 117template<> 118class StringTypeAdapter<char*> { 119public: 120 StringTypeAdapter<char*>(char* buffer) 121 : m_buffer(buffer) 122 , m_length(strlen(buffer)) 123 { 124 } 125 126 unsigned length() { return m_length; } 127 128 bool is8Bit() { return true; } 129 130 void writeTo(LChar* destination) 131 { 132 for (unsigned i = 0; i < m_length; ++i) 133 destination[i] = static_cast<LChar>(m_buffer[i]); 134 } 135 136 void writeTo(UChar* destination) 137 { 138 for (unsigned i = 0; i < m_length; ++i) { 139 unsigned char c = m_buffer[i]; 140 destination[i] = c; 141 } 142 } 143 144private: 145 const char* m_buffer; 146 unsigned m_length; 147}; 148 149template<> 150class StringTypeAdapter<LChar*> { 151public: 152 StringTypeAdapter<LChar*>(LChar* buffer) 153 : m_buffer(buffer) 154 , m_length(strlen(reinterpret_cast<char*>(buffer))) 155 { 156 } 157 158 unsigned length() { return m_length; } 159 160 bool is8Bit() { return true; } 161 162 void writeTo(LChar* destination) 163 { 164 memcpy(destination, m_buffer, m_length * sizeof(LChar)); 165 } 166 167 void writeTo(UChar* destination) 168 { 169 StringImpl::copyChars(destination, m_buffer, m_length); 170 } 171 172private: 173 const LChar* m_buffer; 174 unsigned m_length; 175}; 176 177template<> 178class StringTypeAdapter<const UChar*> { 179public: 180 StringTypeAdapter<const UChar*>(const UChar* buffer) 181 : m_buffer(buffer) 182 { 183 size_t len = 0; 184 while (m_buffer[len] != UChar(0)) 185 ++len; 186 187 if (len > std::numeric_limits<unsigned>::max()) 188 CRASH(); 189 190 m_length = len; 191 } 192 193 unsigned length() { return m_length; } 194 195 bool is8Bit() { return false; } 196 197 NO_RETURN_DUE_TO_CRASH void writeTo(LChar*) 198 { 199 CRASH(); 200 } 201 202 void writeTo(UChar* destination) 203 { 204 memcpy(destination, m_buffer, m_length * sizeof(UChar)); 205 } 206 207private: 208 const UChar* m_buffer; 209 unsigned m_length; 210}; 211 212template<> 213class StringTypeAdapter<const char*> { 214public: 215 StringTypeAdapter<const char*>(const char* buffer) 216 : m_buffer(buffer) 217 , m_length(strlen(buffer)) 218 { 219 } 220 221 unsigned length() { return m_length; } 222 223 bool is8Bit() { return true; } 224 225 void writeTo(LChar* destination) 226 { 227 memcpy(destination, m_buffer, static_cast<size_t>(m_length) * sizeof(LChar)); 228 } 229 230 void writeTo(UChar* destination) 231 { 232 for (unsigned i = 0; i < m_length; ++i) { 233 unsigned char c = m_buffer[i]; 234 destination[i] = c; 235 } 236 } 237 238private: 239 const char* m_buffer; 240 unsigned m_length; 241}; 242 243template<> 244class StringTypeAdapter<const LChar*> { 245public: 246 StringTypeAdapter<const LChar*>(const LChar* buffer) 247 : m_buffer(buffer) 248 , m_length(strlen(reinterpret_cast<const char*>(buffer))) 249 { 250 } 251 252 unsigned length() { return m_length; } 253 254 bool is8Bit() { return true; } 255 256 void writeTo(LChar* destination) 257 { 258 memcpy(destination, m_buffer, static_cast<size_t>(m_length) * sizeof(LChar)); 259 } 260 261 void writeTo(UChar* destination) 262 { 263 StringImpl::copyChars(destination, m_buffer, m_length); 264 } 265 266private: 267 const LChar* m_buffer; 268 unsigned m_length; 269}; 270 271template<> 272class StringTypeAdapter<ASCIILiteral> { 273public: 274 StringTypeAdapter<ASCIILiteral>(ASCIILiteral buffer) 275 : m_buffer(reinterpret_cast<const LChar*>(static_cast<const char*>(buffer))) 276 , m_length(strlen(buffer)) 277 { 278 } 279 280 size_t length() { return m_length; } 281 282 bool is8Bit() { return true; } 283 284 void writeTo(LChar* destination) 285 { 286 memcpy(destination, m_buffer, static_cast<size_t>(m_length)); 287 } 288 289 void writeTo(UChar* destination) 290 { 291 StringImpl::copyChars(destination, m_buffer, m_length); 292 } 293 294private: 295 const LChar* m_buffer; 296 unsigned m_length; 297}; 298 299template<> 300class StringTypeAdapter<Vector<char>> { 301public: 302 StringTypeAdapter<Vector<char>>(const Vector<char>& buffer) 303 : m_buffer(buffer) 304 { 305 } 306 307 size_t length() { return m_buffer.size(); } 308 309 bool is8Bit() { return true; } 310 311 void writeTo(LChar* destination) 312 { 313 for (size_t i = 0; i < m_buffer.size(); ++i) 314 destination[i] = static_cast<unsigned char>(m_buffer[i]); 315 } 316 317 void writeTo(UChar* destination) 318 { 319 for (size_t i = 0; i < m_buffer.size(); ++i) 320 destination[i] = static_cast<unsigned char>(m_buffer[i]); 321 } 322 323private: 324 const Vector<char>& m_buffer; 325}; 326 327template<> 328class StringTypeAdapter<Vector<LChar>> { 329public: 330 StringTypeAdapter<Vector<LChar>>(const Vector<LChar>& buffer) 331 : m_buffer(buffer) 332 { 333 } 334 335 size_t length() { return m_buffer.size(); } 336 337 bool is8Bit() { return true; } 338 339 void writeTo(LChar* destination) 340 { 341 for (size_t i = 0; i < m_buffer.size(); ++i) 342 destination[i] = m_buffer[i]; 343 } 344 345 void writeTo(UChar* destination) 346 { 347 for (size_t i = 0; i < m_buffer.size(); ++i) 348 destination[i] = m_buffer[i]; 349 } 350 351private: 352 const Vector<LChar>& m_buffer; 353}; 354 355template<> 356class StringTypeAdapter<String> { 357public: 358 StringTypeAdapter<String>(const String& string) 359 : m_buffer(string) 360 { 361 } 362 363 unsigned length() { return m_buffer.length(); } 364 365 bool is8Bit() { return m_buffer.isNull() || m_buffer.is8Bit(); } 366 367 void writeTo(LChar* destination) 368 { 369 unsigned length = m_buffer.length(); 370 371 ASSERT(is8Bit()); 372 const LChar* data = m_buffer.characters8(); 373 for (unsigned i = 0; i < length; ++i) 374 destination[i] = data[i]; 375 376 WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING(); 377 } 378 379 void writeTo(UChar* destination) 380 { 381 unsigned length = m_buffer.length(); 382 383 if (is8Bit()) { 384 const LChar* data = m_buffer.characters8(); 385 for (unsigned i = 0; i < length; ++i) 386 destination[i] = data[i]; 387 } else { 388 const UChar* data = m_buffer.characters16(); 389 for (unsigned i = 0; i < length; ++i) 390 destination[i] = data[i]; 391 } 392 393 WTF_STRINGTYPEADAPTER_COPIED_WTF_STRING(); 394 } 395 396private: 397 const String& m_buffer; 398}; 399 400template<> 401class StringTypeAdapter<AtomicString> { 402public: 403 StringTypeAdapter<AtomicString>(const AtomicString& string) 404 : m_adapter(string.string()) 405 { 406 } 407 408 unsigned length() { return m_adapter.length(); } 409 410 bool is8Bit() { return m_adapter.is8Bit(); } 411 412 void writeTo(LChar* destination) { m_adapter.writeTo(destination); } 413 void writeTo(UChar* destination) { m_adapter.writeTo(destination); } 414 415private: 416 StringTypeAdapter<String> m_adapter; 417}; 418 419inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow) 420{ 421 unsigned oldTotal = total; 422 total = oldTotal + addend; 423 if (total < oldTotal) 424 overflow = true; 425} 426 427template<typename StringType1, typename StringType2> 428PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2) 429{ 430 StringTypeAdapter<StringType1> adapter1(string1); 431 StringTypeAdapter<StringType2> adapter2(string2); 432 433 bool overflow = false; 434 unsigned length = adapter1.length(); 435 sumWithOverflow(length, adapter2.length(), overflow); 436 if (overflow) 437 return 0; 438 439 if (adapter1.is8Bit() && adapter2.is8Bit()) { 440 LChar* buffer; 441 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 442 if (!resultImpl) 443 return 0; 444 445 LChar* result = buffer; 446 adapter1.writeTo(result); 447 result += adapter1.length(); 448 adapter2.writeTo(result); 449 450 return resultImpl.release(); 451 } 452 453 UChar* buffer; 454 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 455 if (!resultImpl) 456 return 0; 457 458 UChar* result = buffer; 459 adapter1.writeTo(result); 460 result += adapter1.length(); 461 adapter2.writeTo(result); 462 463 return resultImpl.release(); 464} 465 466template<typename StringType1, typename StringType2, typename StringType3> 467PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3) 468{ 469 StringTypeAdapter<StringType1> adapter1(string1); 470 StringTypeAdapter<StringType2> adapter2(string2); 471 StringTypeAdapter<StringType3> adapter3(string3); 472 473 bool overflow = false; 474 unsigned length = adapter1.length(); 475 sumWithOverflow(length, adapter2.length(), overflow); 476 sumWithOverflow(length, adapter3.length(), overflow); 477 if (overflow) 478 return 0; 479 480 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit()) { 481 LChar* buffer; 482 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 483 if (!resultImpl) 484 return 0; 485 486 LChar* result = buffer; 487 adapter1.writeTo(result); 488 result += adapter1.length(); 489 adapter2.writeTo(result); 490 result += adapter2.length(); 491 adapter3.writeTo(result); 492 493 return resultImpl.release(); 494 } 495 496 UChar* buffer = 0; 497 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 498 if (!resultImpl) 499 return 0; 500 501 UChar* result = buffer; 502 adapter1.writeTo(result); 503 result += adapter1.length(); 504 adapter2.writeTo(result); 505 result += adapter2.length(); 506 adapter3.writeTo(result); 507 508 return resultImpl.release(); 509} 510 511template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> 512PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) 513{ 514 StringTypeAdapter<StringType1> adapter1(string1); 515 StringTypeAdapter<StringType2> adapter2(string2); 516 StringTypeAdapter<StringType3> adapter3(string3); 517 StringTypeAdapter<StringType4> adapter4(string4); 518 519 bool overflow = false; 520 unsigned length = adapter1.length(); 521 sumWithOverflow(length, adapter2.length(), overflow); 522 sumWithOverflow(length, adapter3.length(), overflow); 523 sumWithOverflow(length, adapter4.length(), overflow); 524 if (overflow) 525 return 0; 526 527 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit()) { 528 LChar* buffer; 529 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 530 if (!resultImpl) 531 return 0; 532 533 LChar* result = buffer; 534 adapter1.writeTo(result); 535 result += adapter1.length(); 536 adapter2.writeTo(result); 537 result += adapter2.length(); 538 adapter3.writeTo(result); 539 result += adapter3.length(); 540 adapter4.writeTo(result); 541 542 return resultImpl.release(); 543 } 544 545 UChar* buffer; 546 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 547 if (!resultImpl) 548 return 0; 549 550 UChar* result = buffer; 551 adapter1.writeTo(result); 552 result += adapter1.length(); 553 adapter2.writeTo(result); 554 result += adapter2.length(); 555 adapter3.writeTo(result); 556 result += adapter3.length(); 557 adapter4.writeTo(result); 558 559 return resultImpl.release(); 560} 561 562template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> 563PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) 564{ 565 StringTypeAdapter<StringType1> adapter1(string1); 566 StringTypeAdapter<StringType2> adapter2(string2); 567 StringTypeAdapter<StringType3> adapter3(string3); 568 StringTypeAdapter<StringType4> adapter4(string4); 569 StringTypeAdapter<StringType5> adapter5(string5); 570 571 bool overflow = false; 572 unsigned length = adapter1.length(); 573 sumWithOverflow(length, adapter2.length(), overflow); 574 sumWithOverflow(length, adapter3.length(), overflow); 575 sumWithOverflow(length, adapter4.length(), overflow); 576 sumWithOverflow(length, adapter5.length(), overflow); 577 if (overflow) 578 return 0; 579 580 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit()) { 581 LChar* buffer; 582 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 583 if (!resultImpl) 584 return 0; 585 586 LChar* result = buffer; 587 adapter1.writeTo(result); 588 result += adapter1.length(); 589 adapter2.writeTo(result); 590 result += adapter2.length(); 591 adapter3.writeTo(result); 592 result += adapter3.length(); 593 adapter4.writeTo(result); 594 result += adapter4.length(); 595 adapter5.writeTo(result); 596 597 return resultImpl.release(); 598 } 599 600 UChar* buffer; 601 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 602 if (!resultImpl) 603 return 0; 604 605 UChar* result = buffer; 606 adapter1.writeTo(result); 607 result += adapter1.length(); 608 adapter2.writeTo(result); 609 result += adapter2.length(); 610 adapter3.writeTo(result); 611 result += adapter3.length(); 612 adapter4.writeTo(result); 613 result += adapter4.length(); 614 adapter5.writeTo(result); 615 616 return resultImpl.release(); 617} 618 619template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> 620PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) 621{ 622 StringTypeAdapter<StringType1> adapter1(string1); 623 StringTypeAdapter<StringType2> adapter2(string2); 624 StringTypeAdapter<StringType3> adapter3(string3); 625 StringTypeAdapter<StringType4> adapter4(string4); 626 StringTypeAdapter<StringType5> adapter5(string5); 627 StringTypeAdapter<StringType6> adapter6(string6); 628 629 bool overflow = false; 630 unsigned length = adapter1.length(); 631 sumWithOverflow(length, adapter2.length(), overflow); 632 sumWithOverflow(length, adapter3.length(), overflow); 633 sumWithOverflow(length, adapter4.length(), overflow); 634 sumWithOverflow(length, adapter5.length(), overflow); 635 sumWithOverflow(length, adapter6.length(), overflow); 636 if (overflow) 637 return 0; 638 639 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit()) { 640 LChar* buffer; 641 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 642 if (!resultImpl) 643 return 0; 644 645 LChar* result = buffer; 646 adapter1.writeTo(result); 647 result += adapter1.length(); 648 adapter2.writeTo(result); 649 result += adapter2.length(); 650 adapter3.writeTo(result); 651 result += adapter3.length(); 652 adapter4.writeTo(result); 653 result += adapter4.length(); 654 adapter5.writeTo(result); 655 result += adapter5.length(); 656 adapter6.writeTo(result); 657 658 return resultImpl.release(); 659 } 660 661 UChar* buffer; 662 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 663 if (!resultImpl) 664 return 0; 665 666 UChar* result = buffer; 667 adapter1.writeTo(result); 668 result += adapter1.length(); 669 adapter2.writeTo(result); 670 result += adapter2.length(); 671 adapter3.writeTo(result); 672 result += adapter3.length(); 673 adapter4.writeTo(result); 674 result += adapter4.length(); 675 adapter5.writeTo(result); 676 result += adapter5.length(); 677 adapter6.writeTo(result); 678 679 return resultImpl.release(); 680} 681 682template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> 683PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) 684{ 685 StringTypeAdapter<StringType1> adapter1(string1); 686 StringTypeAdapter<StringType2> adapter2(string2); 687 StringTypeAdapter<StringType3> adapter3(string3); 688 StringTypeAdapter<StringType4> adapter4(string4); 689 StringTypeAdapter<StringType5> adapter5(string5); 690 StringTypeAdapter<StringType6> adapter6(string6); 691 StringTypeAdapter<StringType7> adapter7(string7); 692 693 bool overflow = false; 694 unsigned length = adapter1.length(); 695 sumWithOverflow(length, adapter2.length(), overflow); 696 sumWithOverflow(length, adapter3.length(), overflow); 697 sumWithOverflow(length, adapter4.length(), overflow); 698 sumWithOverflow(length, adapter5.length(), overflow); 699 sumWithOverflow(length, adapter6.length(), overflow); 700 sumWithOverflow(length, adapter7.length(), overflow); 701 if (overflow) 702 return 0; 703 704 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit()) { 705 LChar* buffer; 706 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 707 if (!resultImpl) 708 return 0; 709 710 LChar* result = buffer; 711 adapter1.writeTo(result); 712 result += adapter1.length(); 713 adapter2.writeTo(result); 714 result += adapter2.length(); 715 adapter3.writeTo(result); 716 result += adapter3.length(); 717 adapter4.writeTo(result); 718 result += adapter4.length(); 719 adapter5.writeTo(result); 720 result += adapter5.length(); 721 adapter6.writeTo(result); 722 result += adapter6.length(); 723 adapter7.writeTo(result); 724 725 return resultImpl.release(); 726 } 727 728 UChar* buffer; 729 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 730 if (!resultImpl) 731 return 0; 732 733 UChar* result = buffer; 734 adapter1.writeTo(result); 735 result += adapter1.length(); 736 adapter2.writeTo(result); 737 result += adapter2.length(); 738 adapter3.writeTo(result); 739 result += adapter3.length(); 740 adapter4.writeTo(result); 741 result += adapter4.length(); 742 adapter5.writeTo(result); 743 result += adapter5.length(); 744 adapter6.writeTo(result); 745 result += adapter6.length(); 746 adapter7.writeTo(result); 747 748 return resultImpl.release(); 749} 750 751template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> 752PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) 753{ 754 StringTypeAdapter<StringType1> adapter1(string1); 755 StringTypeAdapter<StringType2> adapter2(string2); 756 StringTypeAdapter<StringType3> adapter3(string3); 757 StringTypeAdapter<StringType4> adapter4(string4); 758 StringTypeAdapter<StringType5> adapter5(string5); 759 StringTypeAdapter<StringType6> adapter6(string6); 760 StringTypeAdapter<StringType7> adapter7(string7); 761 StringTypeAdapter<StringType8> adapter8(string8); 762 763 bool overflow = false; 764 unsigned length = adapter1.length(); 765 sumWithOverflow(length, adapter2.length(), overflow); 766 sumWithOverflow(length, adapter3.length(), overflow); 767 sumWithOverflow(length, adapter4.length(), overflow); 768 sumWithOverflow(length, adapter5.length(), overflow); 769 sumWithOverflow(length, adapter6.length(), overflow); 770 sumWithOverflow(length, adapter7.length(), overflow); 771 sumWithOverflow(length, adapter8.length(), overflow); 772 if (overflow) 773 return 0; 774 775 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit() && adapter8.is8Bit()) { 776 LChar* buffer; 777 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 778 if (!resultImpl) 779 return 0; 780 781 LChar* result = buffer; 782 adapter1.writeTo(result); 783 result += adapter1.length(); 784 adapter2.writeTo(result); 785 result += adapter2.length(); 786 adapter3.writeTo(result); 787 result += adapter3.length(); 788 adapter4.writeTo(result); 789 result += adapter4.length(); 790 adapter5.writeTo(result); 791 result += adapter5.length(); 792 adapter6.writeTo(result); 793 result += adapter6.length(); 794 adapter7.writeTo(result); 795 result += adapter7.length(); 796 adapter8.writeTo(result); 797 798 return resultImpl.release(); 799 } 800 801 UChar* buffer; 802 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 803 if (!resultImpl) 804 return 0; 805 806 UChar* result = buffer; 807 adapter1.writeTo(result); 808 result += adapter1.length(); 809 adapter2.writeTo(result); 810 result += adapter2.length(); 811 adapter3.writeTo(result); 812 result += adapter3.length(); 813 adapter4.writeTo(result); 814 result += adapter4.length(); 815 adapter5.writeTo(result); 816 result += adapter5.length(); 817 adapter6.writeTo(result); 818 result += adapter6.length(); 819 adapter7.writeTo(result); 820 result += adapter7.length(); 821 adapter8.writeTo(result); 822 823 return resultImpl.release(); 824} 825 826template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8, typename StringType9> 827PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9) 828{ 829 StringTypeAdapter<StringType1> adapter1(string1); 830 StringTypeAdapter<StringType2> adapter2(string2); 831 StringTypeAdapter<StringType3> adapter3(string3); 832 StringTypeAdapter<StringType4> adapter4(string4); 833 StringTypeAdapter<StringType5> adapter5(string5); 834 StringTypeAdapter<StringType6> adapter6(string6); 835 StringTypeAdapter<StringType7> adapter7(string7); 836 StringTypeAdapter<StringType8> adapter8(string8); 837 StringTypeAdapter<StringType9> adapter9(string9); 838 839 bool overflow = false; 840 unsigned length = adapter1.length(); 841 sumWithOverflow(length, adapter2.length(), overflow); 842 sumWithOverflow(length, adapter3.length(), overflow); 843 sumWithOverflow(length, adapter4.length(), overflow); 844 sumWithOverflow(length, adapter5.length(), overflow); 845 sumWithOverflow(length, adapter6.length(), overflow); 846 sumWithOverflow(length, adapter7.length(), overflow); 847 sumWithOverflow(length, adapter8.length(), overflow); 848 sumWithOverflow(length, adapter9.length(), overflow); 849 if (overflow) 850 return 0; 851 852 if (adapter1.is8Bit() && adapter2.is8Bit() && adapter3.is8Bit() && adapter4.is8Bit() && adapter5.is8Bit() && adapter6.is8Bit() && adapter7.is8Bit() && adapter8.is8Bit() && adapter9.is8Bit()) { 853 LChar* buffer; 854 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 855 if (!resultImpl) 856 return 0; 857 858 LChar* result = buffer; 859 adapter1.writeTo(result); 860 result += adapter1.length(); 861 adapter2.writeTo(result); 862 result += adapter2.length(); 863 adapter3.writeTo(result); 864 result += adapter3.length(); 865 adapter4.writeTo(result); 866 result += adapter4.length(); 867 adapter5.writeTo(result); 868 result += adapter5.length(); 869 adapter6.writeTo(result); 870 result += adapter6.length(); 871 adapter7.writeTo(result); 872 result += adapter7.length(); 873 adapter8.writeTo(result); 874 result += adapter8.length(); 875 adapter9.writeTo(result); 876 877 return resultImpl.release(); 878 } 879 880 UChar* buffer; 881 RefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 882 if (!resultImpl) 883 return 0; 884 885 UChar* result = buffer; 886 adapter1.writeTo(result); 887 result += adapter1.length(); 888 adapter2.writeTo(result); 889 result += adapter2.length(); 890 adapter3.writeTo(result); 891 result += adapter3.length(); 892 adapter4.writeTo(result); 893 result += adapter4.length(); 894 adapter5.writeTo(result); 895 result += adapter5.length(); 896 adapter6.writeTo(result); 897 result += adapter6.length(); 898 adapter7.writeTo(result); 899 result += adapter7.length(); 900 adapter8.writeTo(result); 901 result += adapter8.length(); 902 adapter9.writeTo(result); 903 904 return resultImpl.release(); 905} 906 907 908// Convenience only. 909template<typename StringType1> 910String makeString(StringType1 string1) 911{ 912 return String(string1); 913} 914 915template<typename StringType1, typename StringType2> 916String makeString(StringType1 string1, StringType2 string2) 917{ 918 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2); 919 if (!resultImpl) 920 CRASH(); 921 return resultImpl.release(); 922} 923 924template<typename StringType1, typename StringType2, typename StringType3> 925String makeString(StringType1 string1, StringType2 string2, StringType3 string3) 926{ 927 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3); 928 if (!resultImpl) 929 CRASH(); 930 return resultImpl.release(); 931} 932 933template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> 934String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) 935{ 936 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4); 937 if (!resultImpl) 938 CRASH(); 939 return resultImpl.release(); 940} 941 942template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> 943String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) 944{ 945 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5); 946 if (!resultImpl) 947 CRASH(); 948 return resultImpl.release(); 949} 950 951template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> 952String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) 953{ 954 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6); 955 if (!resultImpl) 956 CRASH(); 957 return resultImpl.release(); 958} 959 960template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> 961String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) 962{ 963 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7); 964 if (!resultImpl) 965 CRASH(); 966 return resultImpl.release(); 967} 968 969template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> 970String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) 971{ 972 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8); 973 if (!resultImpl) 974 CRASH(); 975 return resultImpl.release(); 976} 977 978template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8, typename StringType9> 979String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8, StringType9 string9) 980{ 981 RefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8, string9); 982 if (!resultImpl) 983 CRASH(); 984 return resultImpl.release(); 985} 986 987} // namespace WTF 988 989using WTF::makeString; 990 991#include <wtf/text/StringOperators.h> 992#endif 993