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 |