Changeset 65177 in webkit for trunk/JavaScriptCore/runtime/UString.h
- Timestamp:
- Aug 11, 2010, 12:52:41 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/UString.h
r65104 r65177 39 39 namespace JSC { 40 40 41 using WTF::PlacementNewAdoptType; 42 using WTF::PlacementNewAdopt; 43 44 class UString { 45 friend class JIT; 46 47 public: 48 UString() {} 49 UString(const char*); // Constructor for null-terminated string. 50 UString(const char*, unsigned length); 51 UString(const UChar*, unsigned length); 52 UString(const Vector<UChar>& buffer); 53 54 UString(const UString& s) 55 : m_impl(s.m_impl) 56 { 57 } 58 59 // Special constructor for cases where we overwrite an object in place. 60 UString(PlacementNewAdoptType) 61 : m_impl(PlacementNewAdopt) 62 { 63 } 64 65 template<size_t inlineCapacity> 66 static PassRefPtr<StringImpl> adopt(Vector<UChar, inlineCapacity>& vector) 67 { 68 return StringImpl::adopt(vector); 69 } 70 71 static UString from(int); 72 static UString from(long long); 73 static UString from(unsigned); 74 static UString from(long); 75 static UString from(double); 76 77 // NOTE: This method should only be used for *debugging* purposes as it 78 // is neither Unicode safe nor free from side effects nor thread-safe. 79 char* ascii() const; 80 81 /** 82 * Convert the string to UTF-8, assuming it is UTF-16 encoded. 83 * In non-strict mode, this function is tolerant of badly formed UTF-16, it 84 * can create UTF-8 strings that are invalid because they have characters in 85 * the range U+D800-U+DDFF, U+FFFE, or U+FFFF, but the UTF-8 string is 86 * guaranteed to be otherwise valid. 87 * In strict mode, error is returned as null CString. 88 */ 89 CString UTF8String(bool strict = false) const; 90 91 const UChar* data() const 92 { 93 if (!m_impl) 94 return 0; 95 return m_impl->characters(); 96 } 97 98 unsigned size() const 99 { 100 if (!m_impl) 101 return 0; 102 return m_impl->length(); 103 } 104 105 bool isNull() const { return !m_impl; } 106 bool isEmpty() const { return !m_impl || !m_impl->length(); } 107 108 bool is8Bit() const; 109 110 UChar operator[](unsigned pos) const; 111 112 double toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const; 113 double toDouble(bool tolerateTrailingJunk) const; 114 double toDouble() const; 115 116 uint32_t toUInt32(bool* ok = 0) const; 117 uint32_t toUInt32(bool* ok, bool tolerateEmptyString) const; 118 uint32_t toStrictUInt32(bool* ok = 0) const; 119 120 unsigned toArrayIndex(bool* ok = 0) const; 121 122 static const unsigned NotFound = 0xFFFFFFFFu; 123 unsigned find(const UString& f, unsigned pos = 0) const; 124 unsigned find(UChar, unsigned pos = 0) const; 125 unsigned rfind(const UString& f, unsigned pos) const; 126 unsigned rfind(UChar, unsigned pos) const; 127 128 UString substr(unsigned pos = 0, unsigned len = 0xFFFFFFFF) const; 129 130 StringImpl* impl() const { return m_impl.get(); } 131 132 UString(PassRefPtr<StringImpl> r) 133 : m_impl(r) 134 { 135 } 136 137 size_t cost() const 138 { 139 if (!m_impl) 140 return 0; 141 return m_impl->cost(); 142 } 143 144 ALWAYS_INLINE ~UString() { } 145 private: 146 RefPtr<StringImpl> m_impl; 147 148 friend bool operator==(const UString&, const UString&); 149 }; 150 151 ALWAYS_INLINE bool operator==(const UString& s1, const UString& s2) 152 { 153 StringImpl* rep1 = s1.impl(); 154 StringImpl* rep2 = s2.impl(); 155 unsigned size1 = 0; 156 unsigned size2 = 0; 157 158 if (rep1 == rep2) // If they're the same rep, they're equal. 159 return true; 41 using WTF::PlacementNewAdoptType; 42 using WTF::PlacementNewAdopt; 43 44 class UString { 45 public: 46 UString() {} 47 UString(const char*); // Constructor for null-terminated string. 48 UString(const char*, unsigned length); 49 UString(const UChar*, unsigned length); 50 UString(const Vector<UChar>& buffer); 51 52 UString(const UString& s) 53 : m_impl(s.m_impl) 54 { 55 } 56 57 // Special constructor for cases where we overwrite an object in place. 58 UString(PlacementNewAdoptType) 59 : m_impl(PlacementNewAdopt) 60 { 61 } 62 63 template<size_t inlineCapacity> 64 static PassRefPtr<StringImpl> adopt(Vector<UChar, inlineCapacity>& vector) 65 { 66 return StringImpl::adopt(vector); 67 } 68 69 static UString number(int); 70 static UString number(long long); 71 static UString number(unsigned); 72 static UString number(long); 73 static UString number(double); 74 75 // NOTE: This method should only be used for *debugging* purposes as it 76 // is neither Unicode safe nor free from side effects nor thread-safe. 77 char* ascii() const; 78 79 /** 80 * Convert the string to UTF-8, assuming it is UTF-16 encoded. 81 * In non-strict mode, this function is tolerant of badly formed UTF-16, it 82 * can create UTF-8 strings that are invalid because they have characters in 83 * the range U+D800-U+DDFF, U+FFFE, or U+FFFF, but the UTF-8 string is 84 * guaranteed to be otherwise valid. 85 * In strict mode, error is returned as null CString. 86 */ 87 CString UTF8String(bool strict = false) const; 88 89 ALWAYS_INLINE unsigned length() const 90 { 91 if (!m_impl) 92 return 0; 93 return m_impl->length(); 94 } 95 96 const UChar* characters() const 97 { 98 if (!m_impl) 99 return 0; 100 return m_impl->characters(); 101 } 102 103 UChar operator[](unsigned pos) const; 104 105 double toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const; 106 double toDouble(bool tolerateTrailingJunk) const; 107 double toDouble() const; 108 109 uint32_t toUInt32(bool* ok = 0) const; 110 uint32_t toUInt32(bool* ok, bool tolerateEmptyString) const; 111 uint32_t toStrictUInt32(bool* ok = 0) const; 112 113 unsigned toArrayIndex(bool* ok = 0) const; 114 115 static const unsigned NotFound = 0xFFFFFFFFu; 116 unsigned find(const UString& f, unsigned pos = 0) const; 117 unsigned find(UChar, unsigned pos = 0) const; 118 unsigned rfind(const UString& f, unsigned pos) const; 119 unsigned rfind(UChar, unsigned pos) const; 120 121 UString substr(unsigned pos = 0, unsigned len = 0xFFFFFFFF) const; 122 123 bool isNull() const { return !m_impl; } 124 ALWAYS_INLINE bool isEmpty() const { return !m_impl || !m_impl->length(); } 125 126 StringImpl* impl() const { return m_impl.get(); } 127 128 UString(PassRefPtr<StringImpl> r) 129 : m_impl(r) 130 { 131 } 132 133 size_t cost() const 134 { 135 if (!m_impl) 136 return 0; 137 return m_impl->cost(); 138 } 139 140 private: 141 RefPtr<StringImpl> m_impl; 142 }; 143 144 ALWAYS_INLINE bool operator==(const UString& s1, const UString& s2) 145 { 146 StringImpl* rep1 = s1.impl(); 147 StringImpl* rep2 = s2.impl(); 148 unsigned size1 = 0; 149 unsigned size2 = 0; 150 151 if (rep1 == rep2) // If they're the same rep, they're equal. 152 return true; 153 154 if (rep1) 155 size1 = rep1->length(); 160 156 161 if (rep1) 162 size1 = rep1->length(); 163 164 if (rep2) 165 size2 = rep2->length(); 166 167 if (size1 != size2) // If the lengths are not the same, we're done. 168 return false; 157 if (rep2) 158 size2 = rep2->length(); 169 159 170 if (!size1) 171 return true; 172 173 // At this point we know 174 // (a) that the strings are the same length and 175 // (b) that they are greater than zero length. 176 const UChar* d1 = rep1->characters(); 177 const UChar* d2 = rep2->characters(); 178 179 if (d1 == d2) // Check to see if the data pointers are the same. 180 return true; 181 182 // Do quick checks for sizes 1 and 2. 183 switch (size1) { 184 case 1: 185 return d1[0] == d2[0]; 186 case 2: 187 return (d1[0] == d2[0]) & (d1[1] == d2[1]); 188 default: 189 return memcmp(d1, d2, size1 * sizeof(UChar)) == 0; 190 } 191 } 192 193 194 inline bool operator!=(const UString& s1, const UString& s2) 195 { 196 return !JSC::operator==(s1, s2); 197 } 198 199 bool operator<(const UString& s1, const UString& s2); 200 bool operator>(const UString& s1, const UString& s2); 201 202 bool operator==(const UString& s1, const char* s2); 203 204 inline bool operator!=(const UString& s1, const char* s2) 205 { 206 return !JSC::operator==(s1, s2); 207 } 208 209 inline bool operator==(const char *s1, const UString& s2) 210 { 211 return operator==(s2, s1); 212 } 213 214 inline bool operator!=(const char *s1, const UString& s2) 215 { 216 return !JSC::operator==(s1, s2); 217 } 218 219 inline int codePointCompare(const UString& s1, const UString& s2) 220 { 221 return codePointCompare(s1.impl(), s2.impl()); 222 } 223 224 // Rule from ECMA 15.2 about what an array index is. 225 // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1. 226 inline unsigned UString::toArrayIndex(bool* ok) const 227 { 228 unsigned i = toStrictUInt32(ok); 229 if (ok && i >= 0xFFFFFFFFU) 230 *ok = false; 231 return i; 232 } 233 234 // We'd rather not do shared substring append for small strings, since 235 // this runs too much risk of a tiny initial string holding down a 236 // huge buffer. 237 static const unsigned minShareSize = Heap::minExtraCost / sizeof(UChar); 238 239 struct IdentifierRepHash : PtrHash<RefPtr<StringImpl> > { 240 static unsigned hash(const RefPtr<StringImpl>& key) { return key->existingHash(); } 241 static unsigned hash(StringImpl* key) { return key->existingHash(); } 242 }; 243 244 template<typename StringType> 245 class StringTypeAdapter { 246 }; 247 248 template<> 249 class StringTypeAdapter<char*> { 250 public: 251 StringTypeAdapter<char*>(char* buffer) 252 : m_buffer((unsigned char*)buffer) 253 , m_length(strlen(buffer)) 254 { 255 } 256 257 unsigned length() { return m_length; } 258 259 void writeTo(UChar* destination) 260 { 261 for (unsigned i = 0; i < m_length; ++i) 262 destination[i] = m_buffer[i]; 263 } 264 265 private: 266 const unsigned char* m_buffer; 267 unsigned m_length; 268 }; 269 270 template<> 271 class StringTypeAdapter<const char*> { 272 public: 273 StringTypeAdapter<const char*>(const char* buffer) 274 : m_buffer((unsigned char*)buffer) 275 , m_length(strlen(buffer)) 276 { 277 } 278 279 unsigned length() { return m_length; } 280 281 void writeTo(UChar* destination) 282 { 283 for (unsigned i = 0; i < m_length; ++i) 284 destination[i] = m_buffer[i]; 285 } 286 287 private: 288 const unsigned char* m_buffer; 289 unsigned m_length; 290 }; 291 292 template<> 293 class StringTypeAdapter<UString> { 294 public: 295 StringTypeAdapter<UString>(UString& string) 296 : m_data(string.data()) 297 , m_length(string.size()) 298 { 299 } 300 301 unsigned length() { return m_length; } 302 303 void writeTo(UChar* destination) 304 { 305 for (unsigned i = 0; i < m_length; ++i) 306 destination[i] = m_data[i]; 307 } 308 309 private: 310 const UChar* m_data; 311 unsigned m_length; 312 }; 313 314 inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow) 315 { 316 unsigned oldTotal = total; 317 total = oldTotal + addend; 318 if (total < oldTotal) 319 overflow = true; 320 } 321 322 template<typename StringType1, typename StringType2> 323 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2) 324 { 325 StringTypeAdapter<StringType1> adapter1(string1); 326 StringTypeAdapter<StringType2> adapter2(string2); 327 328 UChar* buffer; 329 bool overflow = false; 330 unsigned length = adapter1.length(); 331 sumWithOverflow(length, adapter2.length(), overflow); 332 if (overflow) 333 return 0; 334 PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 335 if (!resultImpl) 336 return 0; 337 338 UChar* result = buffer; 339 adapter1.writeTo(result); 340 result += adapter1.length(); 341 adapter2.writeTo(result); 342 343 return resultImpl; 344 } 345 346 template<typename StringType1, typename StringType2, typename StringType3> 347 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3) 348 { 349 StringTypeAdapter<StringType1> adapter1(string1); 350 StringTypeAdapter<StringType2> adapter2(string2); 351 StringTypeAdapter<StringType3> adapter3(string3); 352 353 UChar* buffer = 0; 354 bool overflow = false; 355 unsigned length = adapter1.length(); 356 sumWithOverflow(length, adapter2.length(), overflow); 357 sumWithOverflow(length, adapter3.length(), overflow); 358 if (overflow) 359 return 0; 360 PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 361 if (!resultImpl) 362 return 0; 363 364 UChar* result = buffer; 365 adapter1.writeTo(result); 366 result += adapter1.length(); 367 adapter2.writeTo(result); 368 result += adapter2.length(); 369 adapter3.writeTo(result); 370 371 return resultImpl; 372 } 373 374 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> 375 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) 376 { 377 StringTypeAdapter<StringType1> adapter1(string1); 378 StringTypeAdapter<StringType2> adapter2(string2); 379 StringTypeAdapter<StringType3> adapter3(string3); 380 StringTypeAdapter<StringType4> adapter4(string4); 381 382 UChar* buffer; 383 bool overflow = false; 384 unsigned length = adapter1.length(); 385 sumWithOverflow(length, adapter2.length(), overflow); 386 sumWithOverflow(length, adapter3.length(), overflow); 387 sumWithOverflow(length, adapter4.length(), overflow); 388 if (overflow) 389 return 0; 390 PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 391 if (!resultImpl) 392 return 0; 393 394 UChar* result = buffer; 395 adapter1.writeTo(result); 396 result += adapter1.length(); 397 adapter2.writeTo(result); 398 result += adapter2.length(); 399 adapter3.writeTo(result); 400 result += adapter3.length(); 401 adapter4.writeTo(result); 402 403 return resultImpl; 404 } 405 406 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> 407 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) 408 { 409 StringTypeAdapter<StringType1> adapter1(string1); 410 StringTypeAdapter<StringType2> adapter2(string2); 411 StringTypeAdapter<StringType3> adapter3(string3); 412 StringTypeAdapter<StringType4> adapter4(string4); 413 StringTypeAdapter<StringType5> adapter5(string5); 414 415 UChar* buffer; 416 bool overflow = false; 417 unsigned length = adapter1.length(); 418 sumWithOverflow(length, adapter2.length(), overflow); 419 sumWithOverflow(length, adapter3.length(), overflow); 420 sumWithOverflow(length, adapter4.length(), overflow); 421 sumWithOverflow(length, adapter5.length(), overflow); 422 if (overflow) 423 return 0; 424 PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 425 if (!resultImpl) 426 return 0; 427 428 UChar* result = buffer; 429 adapter1.writeTo(result); 430 result += adapter1.length(); 431 adapter2.writeTo(result); 432 result += adapter2.length(); 433 adapter3.writeTo(result); 434 result += adapter3.length(); 435 adapter4.writeTo(result); 436 result += adapter4.length(); 437 adapter5.writeTo(result); 438 439 return resultImpl; 440 } 441 442 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> 443 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) 444 { 445 StringTypeAdapter<StringType1> adapter1(string1); 446 StringTypeAdapter<StringType2> adapter2(string2); 447 StringTypeAdapter<StringType3> adapter3(string3); 448 StringTypeAdapter<StringType4> adapter4(string4); 449 StringTypeAdapter<StringType5> adapter5(string5); 450 StringTypeAdapter<StringType6> adapter6(string6); 451 452 UChar* buffer; 453 bool overflow = false; 454 unsigned length = adapter1.length(); 455 sumWithOverflow(length, adapter2.length(), overflow); 456 sumWithOverflow(length, adapter3.length(), overflow); 457 sumWithOverflow(length, adapter4.length(), overflow); 458 sumWithOverflow(length, adapter5.length(), overflow); 459 sumWithOverflow(length, adapter6.length(), overflow); 460 if (overflow) 461 return 0; 462 PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 463 if (!resultImpl) 464 return 0; 465 466 UChar* result = buffer; 467 adapter1.writeTo(result); 468 result += adapter1.length(); 469 adapter2.writeTo(result); 470 result += adapter2.length(); 471 adapter3.writeTo(result); 472 result += adapter3.length(); 473 adapter4.writeTo(result); 474 result += adapter4.length(); 475 adapter5.writeTo(result); 476 result += adapter5.length(); 477 adapter6.writeTo(result); 478 479 return resultImpl; 480 } 481 482 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> 483 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) 484 { 485 StringTypeAdapter<StringType1> adapter1(string1); 486 StringTypeAdapter<StringType2> adapter2(string2); 487 StringTypeAdapter<StringType3> adapter3(string3); 488 StringTypeAdapter<StringType4> adapter4(string4); 489 StringTypeAdapter<StringType5> adapter5(string5); 490 StringTypeAdapter<StringType6> adapter6(string6); 491 StringTypeAdapter<StringType7> adapter7(string7); 492 493 UChar* buffer; 494 bool overflow = false; 495 unsigned length = adapter1.length(); 496 sumWithOverflow(length, adapter2.length(), overflow); 497 sumWithOverflow(length, adapter3.length(), overflow); 498 sumWithOverflow(length, adapter4.length(), overflow); 499 sumWithOverflow(length, adapter5.length(), overflow); 500 sumWithOverflow(length, adapter6.length(), overflow); 501 sumWithOverflow(length, adapter7.length(), overflow); 502 if (overflow) 503 return 0; 504 PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 505 if (!resultImpl) 506 return 0; 507 508 UChar* result = buffer; 509 adapter1.writeTo(result); 510 result += adapter1.length(); 511 adapter2.writeTo(result); 512 result += adapter2.length(); 513 adapter3.writeTo(result); 514 result += adapter3.length(); 515 adapter4.writeTo(result); 516 result += adapter4.length(); 517 adapter5.writeTo(result); 518 result += adapter5.length(); 519 adapter6.writeTo(result); 520 result += adapter6.length(); 521 adapter7.writeTo(result); 522 523 return resultImpl; 524 } 525 526 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> 527 PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) 528 { 529 StringTypeAdapter<StringType1> adapter1(string1); 530 StringTypeAdapter<StringType2> adapter2(string2); 531 StringTypeAdapter<StringType3> adapter3(string3); 532 StringTypeAdapter<StringType4> adapter4(string4); 533 StringTypeAdapter<StringType5> adapter5(string5); 534 StringTypeAdapter<StringType6> adapter6(string6); 535 StringTypeAdapter<StringType7> adapter7(string7); 536 StringTypeAdapter<StringType8> adapter8(string8); 537 538 UChar* buffer; 539 bool overflow = false; 540 unsigned length = adapter1.length(); 541 sumWithOverflow(length, adapter2.length(), overflow); 542 sumWithOverflow(length, adapter3.length(), overflow); 543 sumWithOverflow(length, adapter4.length(), overflow); 544 sumWithOverflow(length, adapter5.length(), overflow); 545 sumWithOverflow(length, adapter6.length(), overflow); 546 sumWithOverflow(length, adapter7.length(), overflow); 547 sumWithOverflow(length, adapter8.length(), overflow); 548 if (overflow) 549 return 0; 550 PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); 551 if (!resultImpl) 552 return 0; 553 554 UChar* result = buffer; 555 adapter1.writeTo(result); 556 result += adapter1.length(); 557 adapter2.writeTo(result); 558 result += adapter2.length(); 559 adapter3.writeTo(result); 560 result += adapter3.length(); 561 adapter4.writeTo(result); 562 result += adapter4.length(); 563 adapter5.writeTo(result); 564 result += adapter5.length(); 565 adapter6.writeTo(result); 566 result += adapter6.length(); 567 adapter7.writeTo(result); 568 result += adapter7.length(); 569 adapter8.writeTo(result); 570 571 return resultImpl; 572 } 573 574 template<typename StringType1, typename StringType2> 575 UString makeString(StringType1 string1, StringType2 string2) 576 { 577 PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2); 578 if (!resultImpl) 579 CRASH(); 580 return resultImpl; 581 } 582 583 template<typename StringType1, typename StringType2, typename StringType3> 584 UString makeString(StringType1 string1, StringType2 string2, StringType3 string3) 585 { 586 PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3); 587 if (!resultImpl) 588 CRASH(); 589 return resultImpl; 590 } 591 592 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> 593 UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) 594 { 595 PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4); 596 if (!resultImpl) 597 CRASH(); 598 return resultImpl; 599 } 600 601 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> 602 UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) 603 { 604 PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5); 605 if (!resultImpl) 606 CRASH(); 607 return resultImpl; 608 } 609 610 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> 611 UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) 612 { 613 PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6); 614 if (!resultImpl) 615 CRASH(); 616 return resultImpl; 617 } 618 619 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> 620 UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) 621 { 622 PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7); 623 if (!resultImpl) 624 CRASH(); 625 return resultImpl; 626 } 627 628 template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> 629 UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) 630 { 631 PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8); 632 if (!resultImpl) 633 CRASH(); 634 return resultImpl; 635 } 160 if (size1 != size2) // If the lengths are not the same, we're done. 161 return false; 162 163 if (!size1) 164 return true; 165 166 // At this point we know 167 // (a) that the strings are the same length and 168 // (b) that they are greater than zero length. 169 const UChar* d1 = rep1->characters(); 170 const UChar* d2 = rep2->characters(); 171 172 if (d1 == d2) // Check to see if the data pointers are the same. 173 return true; 174 175 // Do quick checks for sizes 1 and 2. 176 switch (size1) { 177 case 1: 178 return d1[0] == d2[0]; 179 case 2: 180 return (d1[0] == d2[0]) & (d1[1] == d2[1]); 181 default: 182 return memcmp(d1, d2, size1 * sizeof(UChar)) == 0; 183 } 184 } 185 186 187 inline bool operator!=(const UString& s1, const UString& s2) 188 { 189 return !JSC::operator==(s1, s2); 190 } 191 192 bool operator<(const UString& s1, const UString& s2); 193 bool operator>(const UString& s1, const UString& s2); 194 195 bool operator==(const UString& s1, const char* s2); 196 197 inline bool operator!=(const UString& s1, const char* s2) 198 { 199 return !JSC::operator==(s1, s2); 200 } 201 202 inline bool operator==(const char *s1, const UString& s2) 203 { 204 return operator==(s2, s1); 205 } 206 207 inline bool operator!=(const char *s1, const UString& s2) 208 { 209 return !JSC::operator==(s1, s2); 210 } 211 212 inline int codePointCompare(const UString& s1, const UString& s2) 213 { 214 return codePointCompare(s1.impl(), s2.impl()); 215 } 216 217 // Rule from ECMA 15.2 about what an array index is. 218 // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1. 219 inline unsigned UString::toArrayIndex(bool* ok) const 220 { 221 unsigned i = toStrictUInt32(ok); 222 if (ok && i >= 0xFFFFFFFFU) 223 *ok = false; 224 return i; 225 } 226 227 // We'd rather not do shared substring append for small strings, since 228 // this runs too much risk of a tiny initial string holding down a 229 // huge buffer. 230 static const unsigned minShareSize = Heap::minExtraCost / sizeof(UChar); 231 232 struct IdentifierRepHash : PtrHash<RefPtr<StringImpl> > { 233 static unsigned hash(const RefPtr<StringImpl>& key) { return key->existingHash(); } 234 static unsigned hash(StringImpl* key) { return key->existingHash(); } 235 }; 636 236 637 237 } // namespace JSC … … 639 239 namespace WTF { 640 240 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 241 template<typename T> struct DefaultHash; 242 template<typename T> struct StrHash; 243 244 template<> struct StrHash<StringImpl*> { 245 static unsigned hash(const StringImpl* key) { return key->hash(); } 246 static bool equal(const StringImpl* a, const StringImpl* b) { return ::equal(a, b); } 247 static const bool safeToCompareToEmptyOrDeleted = false; 248 }; 249 250 template<> struct StrHash<RefPtr<StringImpl> > : public StrHash<StringImpl*> { 251 using StrHash<StringImpl*>::hash; 252 static unsigned hash(const RefPtr<StringImpl>& key) { return key->hash(); } 253 using StrHash<StringImpl*>::equal; 254 static bool equal(const RefPtr<StringImpl>& a, const RefPtr<StringImpl>& b) { return ::equal(a.get(), b.get()); } 255 static bool equal(const StringImpl* a, const RefPtr<StringImpl>& b) { return ::equal(a, b.get()); } 256 static bool equal(const RefPtr<StringImpl>& a, const StringImpl* b) { return ::equal(a.get(), b); } 257 258 static const bool safeToCompareToEmptyOrDeleted = false; 259 }; 260 261 template <> struct VectorTraits<JSC::UString> : SimpleClassVectorTraits 262 { 263 static const bool canInitializeWithMemset = true; 264 }; 665 265 666 266 } // namespace WTF
Note:
See TracChangeset
for help on using the changeset viewer.