| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights
reserved. | 3 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights
reserved. |
| 4 * Copyright (C) 2009 Google Inc. All rights reserved. | 4 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #define StringImpl_h | 24 #define StringImpl_h |
| 25 | 25 |
| 26 #include <limits.h> | 26 #include <limits.h> |
| 27 #include <wtf/ASCIICType.h> | 27 #include <wtf/ASCIICType.h> |
| 28 #include <wtf/Forward.h> | 28 #include <wtf/Forward.h> |
| 29 #include <wtf/StdLibExtras.h> | 29 #include <wtf/StdLibExtras.h> |
| 30 #include <wtf/StringHasher.h> | 30 #include <wtf/StringHasher.h> |
| 31 #include <wtf/Vector.h> | 31 #include <wtf/Vector.h> |
| 32 #include <wtf/unicode/Unicode.h> | 32 #include <wtf/unicode/Unicode.h> |
| 33 | 33 |
| 34 #if PLATFORM(QT) | |
| 35 #include <QString> | |
| 36 #endif | |
| 37 | |
| 38 #if USE(CF) | 34 #if USE(CF) |
| 39 typedef const struct __CFString * CFStringRef; | 35 typedef const struct __CFString * CFStringRef; |
| 40 #endif | 36 #endif |
| 41 | 37 |
| 42 #ifdef __OBJC__ | 38 #ifdef __OBJC__ |
| 43 @class NSString; | 39 @class NSString; |
| 44 #endif | 40 #endif |
| 45 | 41 |
| 46 #if PLATFORM(BLACKBERRY) | 42 #if PLATFORM(BLACKBERRY) |
| 47 #include <BlackBerryPlatformString.h> | 43 #include <BlackBerryPlatformString.h> |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 friend struct WTF::UCharBufferTranslator; | 142 friend struct WTF::UCharBufferTranslator; |
| 147 friend class AtomicStringImpl; | 143 friend class AtomicStringImpl; |
| 148 friend class JSC::LLInt::Data; | 144 friend class JSC::LLInt::Data; |
| 149 friend class JSC::LLIntOffsetsExtractor; | 145 friend class JSC::LLIntOffsetsExtractor; |
| 150 | 146 |
| 151 private: | 147 private: |
| 152 enum BufferOwnership { | 148 enum BufferOwnership { |
| 153 BufferInternal, | 149 BufferInternal, |
| 154 BufferOwned, | 150 BufferOwned, |
| 155 BufferSubstring, | 151 BufferSubstring, |
| 156 #if PLATFORM(QT) | |
| 157 BufferAdoptedQString | |
| 158 #endif | |
| 159 // NOTE: Adding more ownership types needs to extend m_hashAndFlags as w
e're at capacity | 152 // NOTE: Adding more ownership types needs to extend m_hashAndFlags as w
e're at capacity |
| 160 }; | 153 }; |
| 161 | 154 |
| 162 // Used to construct static strings, which have an special refCount that can
never hit zero. | 155 // Used to construct static strings, which have an special refCount that can
never hit zero. |
| 163 // This means that the static string will never be destroyed, which is impor
tant because | 156 // This means that the static string will never be destroyed, which is impor
tant because |
| 164 // static strings will be shared across threads & ref-counted in a non-threa
dsafe manner. | 157 // static strings will be shared across threads & ref-counted in a non-threa
dsafe manner. |
| 165 enum ConstructStaticStringTag { ConstructStaticString }; | 158 enum ConstructStaticStringTag { ConstructStaticString }; |
| 166 StringImpl(const UChar* characters, unsigned length, ConstructStaticStringTa
g) | 159 StringImpl(const UChar* characters, unsigned length, ConstructStaticStringTa
g) |
| 167 : m_refCount(s_refCountFlagIsStaticString) | 160 : m_refCount(s_refCountFlagIsStaticString) |
| 168 , m_length(length) | 161 , m_length(length) |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 // that's exactly the oposite of what we want!), and teh normal hash wou
ld | 308 // that's exactly the oposite of what we want!), and teh normal hash wou
ld |
| 316 // lead to lots of conflicts. | 309 // lead to lots of conflicts. |
| 317 unsigned hash = reinterpret_cast<uintptr_t>(this); | 310 unsigned hash = reinterpret_cast<uintptr_t>(this); |
| 318 hash <<= s_flagCount; | 311 hash <<= s_flagCount; |
| 319 if (!hash) | 312 if (!hash) |
| 320 hash = 1 << s_flagCount; | 313 hash = 1 << s_flagCount; |
| 321 m_hashAndFlags = hash | BufferInternal; | 314 m_hashAndFlags = hash | BufferInternal; |
| 322 | 315 |
| 323 STRING_STATS_ADD_16BIT_STRING(m_length); | 316 STRING_STATS_ADD_16BIT_STRING(m_length); |
| 324 } | 317 } |
| 325 | |
| 326 #if PLATFORM(QT) | |
| 327 // Used to create new strings that adopt an existing QString's data | |
| 328 enum ConstructAdoptedQStringTag { ConstructAdoptedQString }; | |
| 329 StringImpl(QStringData* qStringData, ConstructAdoptedQStringTag) | |
| 330 : m_refCount(s_refCountIncrement) | |
| 331 , m_length(qStringData->size) | |
| 332 , m_data16(0) | |
| 333 , m_qStringData(qStringData) | |
| 334 , m_hashAndFlags(BufferAdoptedQString) | |
| 335 { | |
| 336 ASSERT(m_length); | |
| 337 | |
| 338 // We ref the string-data to ensure it will be valid for the lifetime of | |
| 339 // this string. We then deref it in the destructor, so that the string | |
| 340 // data can eventually be freed. | |
| 341 m_qStringData->ref.ref(); | |
| 342 | |
| 343 // Now that we have a ref we can safely reference the string data | |
| 344 m_data16 = reinterpret_cast_ptr<const UChar*>(qStringData->data()); | |
| 345 ASSERT(m_data16); | |
| 346 | |
| 347 STRING_STATS_ADD_16BIT_STRING(m_length); | |
| 348 } | |
| 349 #endif | |
| 350 | |
| 351 public: | 318 public: |
| 352 WTF_EXPORT_STRING_API ~StringImpl(); | 319 WTF_EXPORT_STRING_API ~StringImpl(); |
| 353 | 320 |
| 354 WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> create(const UChar*, uns
igned length); | 321 WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> create(const UChar*, uns
igned length); |
| 355 WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> create(const LChar*, uns
igned length); | 322 WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> create(const LChar*, uns
igned length); |
| 356 WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> create8BitIfPossible(con
st UChar*, unsigned length); | 323 WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> create8BitIfPossible(con
st UChar*, unsigned length); |
| 357 template<size_t inlineCapacity> | 324 template<size_t inlineCapacity> |
| 358 static PassRefPtr<StringImpl> create8BitIfPossible(const Vector<UChar, inlin
eCapacity>& vector) | 325 static PassRefPtr<StringImpl> create8BitIfPossible(const Vector<UChar, inlin
eCapacity>& vector) |
| 359 { | 326 { |
| 360 return create8BitIfPossible(vector.data(), vector.size()); | 327 return create8BitIfPossible(vector.data(), vector.size()); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 if (size > std::numeric_limits<unsigned>::max()) | 419 if (size > std::numeric_limits<unsigned>::max()) |
| 453 CRASH(); | 420 CRASH(); |
| 454 return adoptRef(new StringImpl(vector.releaseBuffer(), size)); | 421 return adoptRef(new StringImpl(vector.releaseBuffer(), size)); |
| 455 } | 422 } |
| 456 return empty(); | 423 return empty(); |
| 457 } | 424 } |
| 458 | 425 |
| 459 WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> adopt(StringBuffer<UChar
>&); | 426 WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> adopt(StringBuffer<UChar
>&); |
| 460 WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> adopt(StringBuffer<LChar
>&); | 427 WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> adopt(StringBuffer<LChar
>&); |
| 461 | 428 |
| 462 #if PLATFORM(QT) | |
| 463 static PassRefPtr<StringImpl> adopt(QStringData*); | |
| 464 #endif | |
| 465 | |
| 466 unsigned length() const { return m_length; } | 429 unsigned length() const { return m_length; } |
| 467 bool is8Bit() const { return m_hashAndFlags & s_hashFlag8BitBuffer; } | 430 bool is8Bit() const { return m_hashAndFlags & s_hashFlag8BitBuffer; } |
| 468 bool hasInternalBuffer() const { return bufferOwnership() == BufferInternal;
} | 431 bool hasInternalBuffer() const { return bufferOwnership() == BufferInternal;
} |
| 469 bool hasOwnedBuffer() const { return bufferOwnership() == BufferOwned; } | 432 bool hasOwnedBuffer() const { return bufferOwnership() == BufferOwned; } |
| 470 StringImpl* baseString() const { return bufferOwnership() == BufferSubstring
? m_substringBuffer : 0; } | 433 StringImpl* baseString() const { return bufferOwnership() == BufferSubstring
? m_substringBuffer : 0; } |
| 471 | 434 |
| 472 // FIXME: Remove all unnecessary usages of characters() | 435 // FIXME: Remove all unnecessary usages of characters() |
| 473 ALWAYS_INLINE const LChar* characters8() const { ASSERT(is8Bit()); return m_
data8; } | 436 ALWAYS_INLINE const LChar* characters8() const { ASSERT(is8Bit()); return m_
data8; } |
| 474 ALWAYS_INLINE const UChar* characters16() const { ASSERT(!is8Bit()); return
m_data16; } | 437 ALWAYS_INLINE const UChar* characters16() const { ASSERT(!is8Bit()); return
m_data16; } |
| 475 ALWAYS_INLINE const UChar* characters() const | 438 ALWAYS_INLINE const UChar* characters() const |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 if (isAtomic) | 487 if (isAtomic) |
| 525 m_hashAndFlags |= s_hashFlagIsAtomic; | 488 m_hashAndFlags |= s_hashFlagIsAtomic; |
| 526 else | 489 else |
| 527 m_hashAndFlags &= ~s_hashFlagIsAtomic; | 490 m_hashAndFlags &= ~s_hashFlagIsAtomic; |
| 528 } | 491 } |
| 529 | 492 |
| 530 #ifdef STRING_STATS | 493 #ifdef STRING_STATS |
| 531 bool isSubString() const { return bufferOwnership() == BufferSubstring; } | 494 bool isSubString() const { return bufferOwnership() == BufferSubstring; } |
| 532 #endif | 495 #endif |
| 533 | 496 |
| 534 #if PLATFORM(QT) | |
| 535 QStringData* qStringData() { return bufferOwnership() == BufferAdoptedQStrin
g ? m_qStringData : 0; } | |
| 536 #endif | |
| 537 | |
| 538 private: | 497 private: |
| 539 // The high bits of 'hash' are always empty, but we prefer to store our flag
s | 498 // The high bits of 'hash' are always empty, but we prefer to store our flag
s |
| 540 // in the low bits because it makes them slightly more efficient to access. | 499 // in the low bits because it makes them slightly more efficient to access. |
| 541 // So, we shift left and right when setting and getting our hash code. | 500 // So, we shift left and right when setting and getting our hash code. |
| 542 void setHash(unsigned hash) const | 501 void setHash(unsigned hash) const |
| 543 { | 502 { |
| 544 ASSERT(!hasHash()); | 503 ASSERT(!hasHash()); |
| 545 // Multiple clients assume that StringHasher is the canonical string has
h function. | 504 // Multiple clients assume that StringHasher is the canonical string has
h function. |
| 546 ASSERT(hash == (is8Bit() ? StringHasher::computeHashAndMaskTop8Bits(m_da
ta8, m_length) : StringHasher::computeHashAndMaskTop8Bits(m_data16, m_length))); | 505 ASSERT(hash == (is8Bit() ? StringHasher::computeHashAndMaskTop8Bits(m_da
ta8, m_length) : StringHasher::computeHashAndMaskTop8Bits(m_data16, m_length))); |
| 547 ASSERT(!(hash & (s_flagMask << (8 * sizeof(hash) - s_flagCount)))); // V
erify that enough high bits are empty. | 506 ASSERT(!(hash & (s_flagMask << (8 * sizeof(hash) - s_flagCount)))); // V
erify that enough high bits are empty. |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 802 unsigned m_refCount; | 761 unsigned m_refCount; |
| 803 unsigned m_length; | 762 unsigned m_length; |
| 804 union { | 763 union { |
| 805 const LChar* m_data8; | 764 const LChar* m_data8; |
| 806 const UChar* m_data16; | 765 const UChar* m_data16; |
| 807 }; | 766 }; |
| 808 union { | 767 union { |
| 809 void* m_buffer; | 768 void* m_buffer; |
| 810 StringImpl* m_substringBuffer; | 769 StringImpl* m_substringBuffer; |
| 811 mutable UChar* m_copyData16; | 770 mutable UChar* m_copyData16; |
| 812 #if PLATFORM(QT) | |
| 813 QStringData* m_qStringData; | |
| 814 #endif | |
| 815 }; | 771 }; |
| 816 mutable unsigned m_hashAndFlags; | 772 mutable unsigned m_hashAndFlags; |
| 817 }; | 773 }; |
| 818 | 774 |
| 819 COMPILE_ASSERT(sizeof(StringImpl) == sizeof(StringImpl::StaticASCIILiteral), Str
ingImpl_should_match_its_StaticASCIILiteral); | 775 COMPILE_ASSERT(sizeof(StringImpl) == sizeof(StringImpl::StaticASCIILiteral), Str
ingImpl_should_match_its_StaticASCIILiteral); |
| 820 | 776 |
| 821 #if !ASSERT_DISABLED | 777 #if !ASSERT_DISABLED |
| 822 // StringImpls created from StaticASCIILiteral will ASSERT | 778 // StringImpls created from StaticASCIILiteral will ASSERT |
| 823 // in the generic ValueCheck<T>::checkConsistency | 779 // in the generic ValueCheck<T>::checkConsistency |
| 824 // as they are not allocated by fastMalloc. | 780 // as they are not allocated by fastMalloc. |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1338 } | 1294 } |
| 1339 | 1295 |
| 1340 using WTF::StringImpl; | 1296 using WTF::StringImpl; |
| 1341 using WTF::equal; | 1297 using WTF::equal; |
| 1342 using WTF::equalNonNull; | 1298 using WTF::equalNonNull; |
| 1343 using WTF::TextCaseSensitivity; | 1299 using WTF::TextCaseSensitivity; |
| 1344 using WTF::TextCaseSensitive; | 1300 using WTF::TextCaseSensitive; |
| 1345 using WTF::TextCaseInsensitive; | 1301 using WTF::TextCaseInsensitive; |
| 1346 | 1302 |
| 1347 #endif | 1303 #endif |
| OLD | NEW |