ee9386708aba447b6a724174c1f12da660b552bf
[WebKit-https.git] / Source / WTF / wtf / text / StringImpl.h
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2005-2010, 2013-2016 Apple Inc. All rights reserved.
4  * Copyright (C) 2009 Google Inc. All rights reserved.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #ifndef StringImpl_h
24 #define StringImpl_h
25
26 #include <limits.h>
27 #include <unicode/uchar.h>
28 #include <unicode/ustring.h>
29 #include <wtf/ASCIICType.h>
30 #include <wtf/CheckedArithmetic.h>
31 #include <wtf/Forward.h>
32 #include <wtf/Hasher.h>
33 #include <wtf/MathExtras.h>
34 #include <wtf/StdLibExtras.h>
35 #include <wtf/Vector.h>
36 #include <wtf/text/ConversionMode.h>
37 #include <wtf/text/StringCommon.h>
38
39 #if USE(CF)
40 typedef const struct __CFString * CFStringRef;
41 #endif
42
43 #ifdef __OBJC__
44 @class NSString;
45 #endif
46
47 namespace JSC {
48 namespace LLInt { class Data; }
49 class LLIntOffsetsExtractor;
50 }
51
52 namespace WTF {
53
54 class SymbolImpl;
55 class SymbolRegistry;
56
57 struct CStringTranslator;
58 struct CharBufferFromLiteralDataTranslator;
59 struct HashAndUTF8CharactersTranslator;
60 struct LCharBufferTranslator;
61 struct StringHash;
62 struct SubstringTranslator;
63 struct UCharBufferTranslator;
64
65 template<typename> class RetainPtr;
66
67 template<typename> struct HashAndCharactersTranslator;
68
69 enum TextCaseSensitivity {
70     TextCaseSensitive,
71     TextCaseInsensitive
72 };
73
74 typedef bool (*CharacterMatchFunctionPtr)(UChar);
75 typedef bool (*IsWhiteSpaceFunctionPtr)(UChar);
76
77 // Define STRING_STATS to 1 turn on run time statistics of string sizes and memory usage
78 #define STRING_STATS 0
79
80 #if STRING_STATS
81 struct StringStats {
82     inline void add8BitString(unsigned length, bool isSubString = false)
83     {
84         ++m_totalNumberStrings;
85         ++m_number8BitStrings;
86         if (!isSubString)
87             m_total8BitData += length;
88     }
89
90     inline void add16BitString(unsigned length, bool isSubString = false)
91     {
92         ++m_totalNumberStrings;
93         ++m_number16BitStrings;
94         if (!isSubString)
95             m_total16BitData += length;
96     }
97
98     void removeString(StringImpl&);
99     void printStats();
100
101     static const unsigned s_printStringStatsFrequency = 5000;
102     static std::atomic<unsigned> s_stringRemovesTillPrintStats;
103
104     std::atomic<unsigned> m_refCalls;
105     std::atomic<unsigned> m_derefCalls;
106
107     std::atomic<unsigned> m_totalNumberStrings;
108     std::atomic<unsigned> m_number8BitStrings;
109     std::atomic<unsigned> m_number16BitStrings;
110     std::atomic<unsigned long long> m_total8BitData;
111     std::atomic<unsigned long long> m_total16BitData;
112 };
113
114 #define STRING_STATS_ADD_8BIT_STRING(length) StringImpl::stringStats().add8BitString(length)
115 #define STRING_STATS_ADD_8BIT_STRING2(length, isSubString) StringImpl::stringStats().add8BitString(length, isSubString)
116 #define STRING_STATS_ADD_16BIT_STRING(length) StringImpl::stringStats().add16BitString(length)
117 #define STRING_STATS_ADD_16BIT_STRING2(length, isSubString) StringImpl::stringStats().add16BitString(length, isSubString)
118 #define STRING_STATS_REMOVE_STRING(string) StringImpl::stringStats().removeString(string)
119 #define STRING_STATS_REF_STRING(string) ++StringImpl::stringStats().m_refCalls;
120 #define STRING_STATS_DEREF_STRING(string) ++StringImpl::stringStats().m_derefCalls;
121 #else
122 #define STRING_STATS_ADD_8BIT_STRING(length) ((void)0)
123 #define STRING_STATS_ADD_8BIT_STRING2(length, isSubString) ((void)0)
124 #define STRING_STATS_ADD_16BIT_STRING(length) ((void)0)
125 #define STRING_STATS_ADD_16BIT_STRING2(length, isSubString) ((void)0)
126 #define STRING_STATS_ADD_UPCONVERTED_STRING(length) ((void)0)
127 #define STRING_STATS_REMOVE_STRING(string) ((void)0)
128 #define STRING_STATS_REF_STRING(string) ((void)0)
129 #define STRING_STATS_DEREF_STRING(string) ((void)0)
130 #endif
131
132 class StringImpl {
133     WTF_MAKE_NONCOPYABLE(StringImpl); WTF_MAKE_FAST_ALLOCATED;
134     friend struct WTF::CStringTranslator;
135     template<typename CharacterType> friend struct WTF::HashAndCharactersTranslator;
136     friend struct WTF::HashAndUTF8CharactersTranslator;
137     friend struct WTF::CharBufferFromLiteralDataTranslator;
138     friend struct WTF::LCharBufferTranslator;
139     friend struct WTF::SubstringTranslator;
140     friend struct WTF::UCharBufferTranslator;
141     friend class JSC::LLInt::Data;
142     friend class JSC::LLIntOffsetsExtractor;
143     friend class SymbolImpl;
144     
145 private:
146     enum BufferOwnership {
147         BufferInternal,
148         BufferOwned,
149         BufferSubstring,
150     };
151
152     // The bottom 6 bits in the hash are flags.
153 public:
154     static constexpr const unsigned s_flagCount = 6;
155 private:
156     static constexpr const unsigned s_flagMask = (1u << s_flagCount) - 1;
157     static_assert(s_flagCount <= StringHasher::flagCount, "StringHasher reserves enough bits for StringImpl flags");
158     static constexpr const unsigned s_flagStringKindCount = 4;
159
160     static constexpr const unsigned s_hashFlagStringKindIsAtomic = 1u << (s_flagStringKindCount);
161     static constexpr const unsigned s_hashFlagStringKindIsSymbol = 1u << (s_flagStringKindCount + 1);
162     static constexpr const unsigned s_hashMaskStringKind = s_hashFlagStringKindIsAtomic | s_hashFlagStringKindIsSymbol;
163     static constexpr const unsigned s_hashFlag8BitBuffer = 1u << 3;
164     static constexpr const unsigned s_hashFlagDidReportCost = 1u << 2;
165     static constexpr const unsigned s_hashMaskBufferOwnership = (1u << 0) | (1u << 1);
166
167     enum StringKind {
168         StringNormal = 0u, // non-symbol, non-atomic
169         StringAtomic = s_hashFlagStringKindIsAtomic, // non-symbol, atomic
170         StringSymbol = s_hashFlagStringKindIsSymbol, // symbol, non-atomic
171     };
172
173     // FIXME: there has to be a less hacky way to do this.
174     enum Force8Bit { Force8BitConstructor };
175     // Create a normal 8-bit string with internal storage (BufferInternal)
176     StringImpl(unsigned length, Force8Bit)
177         : m_refCount(s_refCountIncrement)
178         , m_length(length)
179         , m_data8(tailPointer<LChar>())
180         , m_hashAndFlags(s_hashFlag8BitBuffer | StringNormal | BufferInternal)
181     {
182         ASSERT(m_data8);
183         ASSERT(m_length);
184
185         STRING_STATS_ADD_8BIT_STRING(m_length);
186     }
187
188     // Create a normal 16-bit string with internal storage (BufferInternal)
189     StringImpl(unsigned length)
190         : m_refCount(s_refCountIncrement)
191         , m_length(length)
192         , m_data16(tailPointer<UChar>())
193         , m_hashAndFlags(StringNormal | BufferInternal)
194     {
195         ASSERT(m_data16);
196         ASSERT(m_length);
197
198         STRING_STATS_ADD_16BIT_STRING(m_length);
199     }
200
201     // Create a StringImpl adopting ownership of the provided buffer (BufferOwned)
202     StringImpl(MallocPtr<LChar> characters, unsigned length)
203         : m_refCount(s_refCountIncrement)
204         , m_length(length)
205         , m_data8(characters.leakPtr())
206         , m_hashAndFlags(s_hashFlag8BitBuffer | StringNormal | BufferOwned)
207     {
208         ASSERT(m_data8);
209         ASSERT(m_length);
210
211         STRING_STATS_ADD_8BIT_STRING(m_length);
212     }
213
214     enum ConstructWithoutCopyingTag { ConstructWithoutCopying };
215     StringImpl(const UChar* characters, unsigned length, ConstructWithoutCopyingTag)
216         : m_refCount(s_refCountIncrement)
217         , m_length(length)
218         , m_data16(characters)
219         , m_hashAndFlags(StringNormal | BufferInternal)
220     {
221         ASSERT(m_data16);
222         ASSERT(m_length);
223
224         STRING_STATS_ADD_16BIT_STRING(m_length);
225     }
226
227     StringImpl(const LChar* characters, unsigned length, ConstructWithoutCopyingTag)
228         : m_refCount(s_refCountIncrement)
229         , m_length(length)
230         , m_data8(characters)
231         , m_hashAndFlags(s_hashFlag8BitBuffer | StringNormal | BufferInternal)
232     {
233         ASSERT(m_data8);
234         ASSERT(m_length);
235
236         STRING_STATS_ADD_8BIT_STRING(m_length);
237     }
238
239     // Create a StringImpl adopting ownership of the provided buffer (BufferOwned)
240     StringImpl(MallocPtr<UChar> characters, unsigned length)
241         : m_refCount(s_refCountIncrement)
242         , m_length(length)
243         , m_data16(characters.leakPtr())
244         , m_hashAndFlags(StringNormal | BufferOwned)
245     {
246         ASSERT(m_data16);
247         ASSERT(m_length);
248
249         STRING_STATS_ADD_16BIT_STRING(m_length);
250     }
251
252     // Used to create new strings that are a substring of an existing 8-bit StringImpl (BufferSubstring)
253     StringImpl(const LChar* characters, unsigned length, Ref<StringImpl>&& base)
254         : m_refCount(s_refCountIncrement)
255         , m_length(length)
256         , m_data8(characters)
257         , m_hashAndFlags(s_hashFlag8BitBuffer | StringNormal | BufferSubstring)
258     {
259         ASSERT(is8Bit());
260         ASSERT(m_data8);
261         ASSERT(m_length);
262         ASSERT(base->bufferOwnership() != BufferSubstring);
263
264         substringBuffer() = &base.leakRef();
265
266         STRING_STATS_ADD_8BIT_STRING2(m_length, true);
267     }
268
269     // Used to create new strings that are a substring of an existing 16-bit StringImpl (BufferSubstring)
270     StringImpl(const UChar* characters, unsigned length, Ref<StringImpl>&& base)
271         : m_refCount(s_refCountIncrement)
272         , m_length(length)
273         , m_data16(characters)
274         , m_hashAndFlags(StringNormal | BufferSubstring)
275     {
276         ASSERT(!is8Bit());
277         ASSERT(m_data16);
278         ASSERT(m_length);
279         ASSERT(base->bufferOwnership() != BufferSubstring);
280
281         substringBuffer() = &base.leakRef();
282
283         STRING_STATS_ADD_16BIT_STRING2(m_length, true);
284     }
285
286 public:
287     WTF_EXPORT_STRING_API static void destroy(StringImpl*);
288
289     WTF_EXPORT_STRING_API static Ref<StringImpl> create(const UChar*, unsigned length);
290     WTF_EXPORT_STRING_API static Ref<StringImpl> create(const LChar*, unsigned length);
291     WTF_EXPORT_STRING_API static Ref<StringImpl> create8BitIfPossible(const UChar*, unsigned length);
292     template<size_t inlineCapacity>
293     static Ref<StringImpl> create8BitIfPossible(const Vector<UChar, inlineCapacity>& vector)
294     {
295         return create8BitIfPossible(vector.data(), vector.size());
296     }
297     WTF_EXPORT_STRING_API static Ref<StringImpl> create8BitIfPossible(const UChar*);
298
299     ALWAYS_INLINE static Ref<StringImpl> create(const char* s, unsigned length) { return create(reinterpret_cast<const LChar*>(s), length); }
300     WTF_EXPORT_STRING_API static Ref<StringImpl> create(const LChar*);
301     ALWAYS_INLINE static Ref<StringImpl> create(const char* s) { return create(reinterpret_cast<const LChar*>(s)); }
302
303     static ALWAYS_INLINE Ref<StringImpl> createSubstringSharingImpl(StringImpl& rep, unsigned offset, unsigned length)
304     {
305         ASSERT(length <= rep.length());
306
307         if (!length)
308             return *empty();
309
310         auto* ownerRep = ((rep.bufferOwnership() == BufferSubstring) ? rep.substringBuffer() : &rep);
311
312         // We allocate a buffer that contains both the StringImpl struct as well as the pointer to the owner string.
313         auto* stringImpl = static_cast<StringImpl*>(fastMalloc(allocationSize<StringImpl*>(1)));
314         if (rep.is8Bit())
315             return adoptRef(*new (NotNull, stringImpl) StringImpl(rep.m_data8 + offset, length, *ownerRep));
316         return adoptRef(*new (NotNull, stringImpl) StringImpl(rep.m_data16 + offset, length, *ownerRep));
317     }
318
319     template<unsigned charactersCount>
320     ALWAYS_INLINE static Ref<StringImpl> createFromLiteral(const char (&characters)[charactersCount])
321     {
322         COMPILE_ASSERT(charactersCount > 1, StringImplFromLiteralNotEmpty);
323         COMPILE_ASSERT((charactersCount - 1 <= ((unsigned(~0) - sizeof(StringImpl)) / sizeof(LChar))), StringImplFromLiteralCannotOverflow);
324
325         return createWithoutCopying(reinterpret_cast<const LChar*>(characters), charactersCount - 1);
326     }
327
328     // FIXME: Transition off of these functions to createWithoutCopying instead.
329     WTF_EXPORT_STRING_API static Ref<StringImpl> createFromLiteral(const char* characters, unsigned length);
330     WTF_EXPORT_STRING_API static Ref<StringImpl> createFromLiteral(const char* characters);
331
332     WTF_EXPORT_STRING_API static Ref<StringImpl> createWithoutCopying(const UChar* characters, unsigned length);
333     WTF_EXPORT_STRING_API static Ref<StringImpl> createWithoutCopying(const LChar* characters, unsigned length);
334
335     WTF_EXPORT_STRING_API static Ref<StringImpl> createUninitialized(unsigned length, LChar*& data);
336     WTF_EXPORT_STRING_API static Ref<StringImpl> createUninitialized(unsigned length, UChar*& data);
337     template <typename T> static ALWAYS_INLINE RefPtr<StringImpl> tryCreateUninitialized(unsigned length, T*& output)
338     {
339         if (!length) {
340             output = nullptr;
341             return empty();
342         }
343
344         if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(T))) {
345             output = nullptr;
346             return nullptr;
347         }
348         StringImpl* resultImpl;
349         if (!tryFastMalloc(allocationSize<T>(length)).getValue(resultImpl)) {
350             output = nullptr;
351             return nullptr;
352         }
353         output = resultImpl->tailPointer<T>();
354
355         return constructInternal<T>(resultImpl, length);
356     }
357
358     // Reallocate the StringImpl. The originalString must be only owned by the Ref,
359     // and the buffer ownership must be BufferInternal. Just like the input pointer of realloc(),
360     // the originalString can't be used after this function.
361     static Ref<StringImpl> reallocate(Ref<StringImpl>&& originalString, unsigned length, LChar*& data);
362     static Ref<StringImpl> reallocate(Ref<StringImpl>&& originalString, unsigned length, UChar*& data);
363
364     static unsigned flagsOffset() { return OBJECT_OFFSETOF(StringImpl, m_hashAndFlags); }
365     static unsigned flagIs8Bit() { return s_hashFlag8BitBuffer; }
366     static unsigned flagIsAtomic() { return s_hashFlagStringKindIsAtomic; }
367     static unsigned flagIsSymbol() { return s_hashFlagStringKindIsSymbol; }
368     static unsigned maskStringKind() { return s_hashMaskStringKind; }
369     static unsigned dataOffset() { return OBJECT_OFFSETOF(StringImpl, m_data8); }
370
371     template<typename CharType, size_t inlineCapacity, typename OverflowHandler>
372     static Ref<StringImpl> adopt(Vector<CharType, inlineCapacity, OverflowHandler>&& vector)
373     {
374         if (size_t size = vector.size()) {
375             ASSERT(vector.data());
376             if (size > std::numeric_limits<unsigned>::max())
377                 CRASH();
378             return adoptRef(*new StringImpl(vector.releaseBuffer(), size));
379         }
380         return *empty();
381     }
382
383     WTF_EXPORT_STRING_API static Ref<StringImpl> adopt(StringBuffer<UChar>&&);
384     WTF_EXPORT_STRING_API static Ref<StringImpl> adopt(StringBuffer<LChar>&&);
385
386     unsigned length() const { return m_length; }
387     static ptrdiff_t lengthMemoryOffset() { return OBJECT_OFFSETOF(StringImpl, m_length); }
388     bool is8Bit() const { return m_hashAndFlags & s_hashFlag8BitBuffer; }
389
390     ALWAYS_INLINE const LChar* characters8() const { ASSERT(is8Bit()); return m_data8; }
391     ALWAYS_INLINE const UChar* characters16() const { ASSERT(!is8Bit()); return m_data16; }
392
393     template <typename CharType>
394     ALWAYS_INLINE const CharType *characters() const;
395
396     size_t cost() const
397     {
398         // For substrings, return the cost of the base string.
399         if (bufferOwnership() == BufferSubstring)
400             return substringBuffer()->cost();
401
402         if (m_hashAndFlags & s_hashFlagDidReportCost)
403             return 0;
404
405         m_hashAndFlags |= s_hashFlagDidReportCost;
406         size_t result = m_length;
407         if (!is8Bit())
408             result <<= 1;
409         return result;
410     }
411     
412     size_t costDuringGC()
413     {
414         if (isStatic())
415             return 0;
416         
417         if (bufferOwnership() == BufferSubstring)
418             return divideRoundedUp(substringBuffer()->costDuringGC(), refCount());
419         
420         size_t result = m_length;
421         if (!is8Bit())
422             result <<= 1;
423         return divideRoundedUp(result, refCount());
424     }
425
426     WTF_EXPORT_STRING_API size_t sizeInBytes() const;
427
428     StringKind stringKind() const { return static_cast<StringKind>(m_hashAndFlags & s_hashMaskStringKind); }
429     bool isSymbol() const { return m_hashAndFlags & s_hashFlagStringKindIsSymbol; }
430     bool isAtomic() const { return m_hashAndFlags & s_hashFlagStringKindIsAtomic; }
431
432     void setIsAtomic(bool isAtomic)
433     {
434         ASSERT(!isStatic());
435         ASSERT(!isSymbol());
436         if (isAtomic) {
437             m_hashAndFlags |= s_hashFlagStringKindIsAtomic;
438             ASSERT(stringKind() == StringAtomic);
439         } else {
440             m_hashAndFlags &= ~s_hashFlagStringKindIsAtomic;
441             ASSERT(stringKind() == StringNormal);
442         }
443     }
444
445 #if STRING_STATS
446     bool isSubString() const { return bufferOwnership() == BufferSubstring; }
447 #endif
448
449     static WTF_EXPORT_STRING_API CString utf8ForCharacters(const LChar* characters, unsigned length);
450     static WTF_EXPORT_STRING_API CString utf8ForCharacters(const UChar* characters, unsigned length, ConversionMode = LenientConversion);
451     WTF_EXPORT_STRING_API CString utf8ForRange(unsigned offset, unsigned length, ConversionMode = LenientConversion) const;
452     WTF_EXPORT_STRING_API CString utf8(ConversionMode = LenientConversion) const;
453
454 private:
455     static WTF_EXPORT_STRING_API bool utf8Impl(const UChar* characters, unsigned length, char*& buffer, size_t bufferSize, ConversionMode);
456     
457     // The high bits of 'hash' are always empty, but we prefer to store our flags
458     // in the low bits because it makes them slightly more efficient to access.
459     // So, we shift left and right when setting and getting our hash code.
460     void setHash(unsigned hash) const
461     {
462         ASSERT(!hasHash());
463         // Multiple clients assume that StringHasher is the canonical string hash function.
464         ASSERT(hash == (is8Bit() ? StringHasher::computeHashAndMaskTop8Bits(m_data8, m_length) : StringHasher::computeHashAndMaskTop8Bits(m_data16, m_length)));
465         ASSERT(!(hash & (s_flagMask << (8 * sizeof(hash) - s_flagCount)))); // Verify that enough high bits are empty.
466         
467         hash <<= s_flagCount;
468         ASSERT(!(hash & m_hashAndFlags)); // Verify that enough low bits are empty after shift.
469         ASSERT(hash); // Verify that 0 is a valid sentinel hash value.
470
471         m_hashAndFlags |= hash; // Store hash with flags in low bits.
472     }
473
474     unsigned rawHash() const
475     {
476         return m_hashAndFlags >> s_flagCount;
477     }
478
479 public:
480     bool hasHash() const
481     {
482         return rawHash() != 0;
483     }
484
485     unsigned existingHash() const
486     {
487         ASSERT(hasHash());
488         return rawHash();
489     }
490
491     unsigned hash() const
492     {
493         if (hasHash())
494             return existingHash();
495         return hashSlowCase();
496     }
497
498     WTF_EXPORT_PRIVATE unsigned concurrentHash() const;
499
500     unsigned symbolAwareHash() const;
501     unsigned existingSymbolAwareHash() const;
502
503     bool isStatic() const { return m_refCount & s_refCountFlagIsStaticString; }
504
505     inline size_t refCount() const
506     {
507         return m_refCount / s_refCountIncrement;
508     }
509     
510     inline bool hasOneRef() const
511     {
512         return m_refCount == s_refCountIncrement;
513     }
514     
515     // This method is useful for assertions.
516     inline bool hasAtLeastOneRef() const
517     {
518         return !!m_refCount;
519     }
520
521     inline void ref()
522     {
523         STRING_STATS_REF_STRING(*this);
524
525         m_refCount += s_refCountIncrement;
526     }
527
528     inline void deref()
529     {
530         STRING_STATS_DEREF_STRING(*this);
531
532         unsigned tempRefCount = m_refCount - s_refCountIncrement;
533         if (!tempRefCount) {
534             StringImpl::destroy(this);
535             return;
536         }
537         m_refCount = tempRefCount;
538     }
539
540     class StaticStringImpl {
541         WTF_MAKE_NONCOPYABLE(StaticStringImpl);
542     public:
543         // Used to construct static strings, which have an special refCount that can never hit zero.
544         // This means that the static string will never be destroyed, which is important because
545         // static strings will be shared across threads & ref-counted in a non-threadsafe manner.
546         template<unsigned charactersCount>
547         constexpr StaticStringImpl(const char (&characters)[charactersCount], StringKind stringKind = StringNormal)
548             : m_refCount(s_refCountFlagIsStaticString)
549             , m_length(charactersCount - 1)
550             , m_data8(characters)
551             , m_hashAndFlags(s_hashFlag8BitBuffer | stringKind | BufferInternal | (StringHasher::computeLiteralHashAndMaskTop8Bits(characters) << s_flagCount))
552         {
553         }
554
555         template<unsigned charactersCount>
556         constexpr StaticStringImpl(const char16_t (&characters)[charactersCount], StringKind stringKind = StringNormal)
557             : m_refCount(s_refCountFlagIsStaticString)
558             , m_length(charactersCount - 1)
559             , m_data16(characters)
560             , m_hashAndFlags(stringKind | BufferInternal | (StringHasher::computeLiteralHashAndMaskTop8Bits(characters) << s_flagCount))
561         {
562         }
563
564         operator StringImpl&()
565         {
566             return *reinterpret_cast<StringImpl*>(this);
567         }
568
569         // These member variables must match the layout of StringImpl.
570         unsigned m_refCount;
571         unsigned m_length;
572         union {
573             const char* m_data8;
574             const char16_t* m_data16;
575         };
576         unsigned m_hashAndFlags;
577     };
578
579     WTF_EXPORTDATA static StaticStringImpl s_atomicEmptyString;
580     ALWAYS_INLINE static StringImpl* empty() { return reinterpret_cast<StringImpl*>(&s_atomicEmptyString); }
581
582     // FIXME: Does this really belong in StringImpl?
583     template <typename T> static void copyChars(T* destination, const T* source, unsigned numCharacters)
584     {
585         if (numCharacters == 1) {
586             *destination = *source;
587             return;
588         }
589
590         if (numCharacters <= s_copyCharsInlineCutOff) {
591             unsigned i = 0;
592 #if (CPU(X86) || CPU(X86_64))
593             const unsigned charsPerInt = sizeof(uint32_t) / sizeof(T);
594
595             if (numCharacters > charsPerInt) {
596                 unsigned stopCount = numCharacters & ~(charsPerInt - 1);
597
598                 const uint32_t* srcCharacters = reinterpret_cast<const uint32_t*>(source);
599                 uint32_t* destCharacters = reinterpret_cast<uint32_t*>(destination);
600                 for (unsigned j = 0; i < stopCount; i += charsPerInt, ++j)
601                     destCharacters[j] = srcCharacters[j];
602             }
603 #endif
604             for (; i < numCharacters; ++i)
605                 destination[i] = source[i];
606         } else
607             memcpy(destination, source, numCharacters * sizeof(T));
608     }
609
610     ALWAYS_INLINE static void copyChars(UChar* destination, const LChar* source, unsigned numCharacters)
611     {
612         for (unsigned i = 0; i < numCharacters; ++i)
613             destination[i] = source[i];
614     }
615
616     // Some string features, like refcounting and the atomicity flag, are not
617     // thread-safe. We achieve thread safety by isolation, giving each thread
618     // its own copy of the string.
619     Ref<StringImpl> isolatedCopy() const;
620
621     WTF_EXPORT_STRING_API Ref<StringImpl> substring(unsigned pos, unsigned len = UINT_MAX);
622
623     UChar at(unsigned i) const
624     {
625         ASSERT_WITH_SECURITY_IMPLICATION(i < m_length);
626         if (is8Bit())
627             return m_data8[i];
628         return m_data16[i];
629     }
630     UChar operator[](unsigned i) const { return at(i); }
631     WTF_EXPORT_STRING_API UChar32 characterStartingAt(unsigned);
632
633     WTF_EXPORT_STRING_API bool containsOnlyWhitespace();
634
635     int toIntStrict(bool* ok = 0, int base = 10);
636     unsigned toUIntStrict(bool* ok = 0, int base = 10);
637     int64_t toInt64Strict(bool* ok = 0, int base = 10);
638     uint64_t toUInt64Strict(bool* ok = 0, int base = 10);
639     intptr_t toIntPtrStrict(bool* ok = 0, int base = 10);
640
641     WTF_EXPORT_STRING_API int toInt(bool* ok = 0); // ignores trailing garbage
642     unsigned toUInt(bool* ok = 0); // ignores trailing garbage
643     int64_t toInt64(bool* ok = 0); // ignores trailing garbage
644     uint64_t toUInt64(bool* ok = 0); // ignores trailing garbage
645     intptr_t toIntPtr(bool* ok = 0); // ignores trailing garbage
646
647     // FIXME: Like the strict functions above, these give false for "ok" when there is trailing garbage.
648     // Like the non-strict functions above, these return the value when there is trailing garbage.
649     // It would be better if these were more consistent with the above functions instead.
650     double toDouble(bool* ok = 0);
651     float toFloat(bool* ok = 0);
652
653     WTF_EXPORT_STRING_API Ref<StringImpl> convertToASCIILowercase();
654     WTF_EXPORT_STRING_API Ref<StringImpl> convertToASCIIUppercase();
655     WTF_EXPORT_STRING_API Ref<StringImpl> convertToLowercaseWithoutLocale();
656     WTF_EXPORT_STRING_API Ref<StringImpl> convertToLowercaseWithoutLocaleStartingAtFailingIndex8Bit(unsigned);
657     WTF_EXPORT_STRING_API Ref<StringImpl> convertToUppercaseWithoutLocale();
658     WTF_EXPORT_STRING_API Ref<StringImpl> convertToLowercaseWithLocale(const AtomicString& localeIdentifier);
659     WTF_EXPORT_STRING_API Ref<StringImpl> convertToUppercaseWithLocale(const AtomicString& localeIdentifier);
660
661     Ref<StringImpl> foldCase();
662
663     Ref<StringImpl> stripWhiteSpace();
664     Ref<StringImpl> stripWhiteSpace(IsWhiteSpaceFunctionPtr);
665     WTF_EXPORT_STRING_API Ref<StringImpl> simplifyWhiteSpace();
666     Ref<StringImpl> simplifyWhiteSpace(IsWhiteSpaceFunctionPtr);
667
668     Ref<StringImpl> removeCharacters(CharacterMatchFunctionPtr);
669     template <typename CharType>
670     ALWAYS_INLINE Ref<StringImpl> removeCharacters(const CharType* characters, CharacterMatchFunctionPtr);
671
672     size_t find(LChar character, unsigned start = 0);
673     size_t find(char character, unsigned start = 0);
674     size_t find(UChar character, unsigned start = 0);
675     WTF_EXPORT_STRING_API size_t find(CharacterMatchFunctionPtr, unsigned index = 0);
676     size_t find(const LChar*, unsigned index = 0);
677     ALWAYS_INLINE size_t find(const char* s, unsigned index = 0) { return find(reinterpret_cast<const LChar*>(s), index); }
678     WTF_EXPORT_STRING_API size_t find(StringImpl*);
679     WTF_EXPORT_STRING_API size_t find(StringImpl*, unsigned index);
680     size_t findIgnoringCase(const LChar*, unsigned index = 0);
681     ALWAYS_INLINE size_t findIgnoringCase(const char* s, unsigned index = 0) { return findIgnoringCase(reinterpret_cast<const LChar*>(s), index); }
682     WTF_EXPORT_STRING_API size_t findIgnoringCase(StringImpl*, unsigned index = 0);
683     WTF_EXPORT_STRING_API size_t findIgnoringASCIICase(const StringImpl&) const;
684     WTF_EXPORT_STRING_API size_t findIgnoringASCIICase(const StringImpl&, unsigned startOffset) const;
685     WTF_EXPORT_STRING_API size_t findIgnoringASCIICase(const StringImpl*) const;
686     WTF_EXPORT_STRING_API size_t findIgnoringASCIICase(const StringImpl*, unsigned startOffset) const;
687
688     WTF_EXPORT_STRING_API size_t reverseFind(UChar, unsigned index = UINT_MAX);
689     WTF_EXPORT_STRING_API size_t reverseFind(StringImpl*, unsigned index = UINT_MAX);
690     WTF_EXPORT_STRING_API size_t reverseFindIgnoringCase(StringImpl*, unsigned index = UINT_MAX);
691
692     WTF_EXPORT_STRING_API bool startsWith(const StringImpl*) const;
693     WTF_EXPORT_STRING_API bool startsWith(const StringImpl&) const;
694     WTF_EXPORT_STRING_API bool startsWithIgnoringASCIICase(const StringImpl*) const;
695     WTF_EXPORT_STRING_API bool startsWithIgnoringASCIICase(const StringImpl&) const;
696     bool startsWith(StringImpl* str, bool caseSensitive) { return caseSensitive ? startsWith(str) : (reverseFindIgnoringCase(str, 0) == 0); }
697     WTF_EXPORT_STRING_API bool startsWith(UChar) const;
698     WTF_EXPORT_STRING_API bool startsWith(const char*, unsigned matchLength, bool caseSensitive) const;
699     template<unsigned matchLength>
700     bool startsWith(const char (&prefix)[matchLength], bool caseSensitive = true) const { return startsWith(prefix, matchLength - 1, caseSensitive); }
701     WTF_EXPORT_STRING_API bool hasInfixStartingAt(const StringImpl&, unsigned startOffset) const;
702
703     WTF_EXPORT_STRING_API bool endsWith(StringImpl*);
704     WTF_EXPORT_STRING_API bool endsWith(StringImpl&);
705     WTF_EXPORT_STRING_API bool endsWithIgnoringASCIICase(const StringImpl*) const;
706     WTF_EXPORT_STRING_API bool endsWithIgnoringASCIICase(const StringImpl&) const;
707     WTF_EXPORT_STRING_API bool endsWith(StringImpl*, bool caseSensitive);
708     WTF_EXPORT_STRING_API bool endsWith(UChar) const;
709     WTF_EXPORT_STRING_API bool endsWith(const char*, unsigned matchLength, bool caseSensitive) const;
710     template<unsigned matchLength>
711     bool endsWith(const char (&prefix)[matchLength], bool caseSensitive = true) const { return endsWith(prefix, matchLength - 1, caseSensitive); }
712     WTF_EXPORT_STRING_API bool hasInfixEndingAt(const StringImpl&, unsigned endOffset) const;
713
714     WTF_EXPORT_STRING_API Ref<StringImpl> replace(UChar, UChar);
715     WTF_EXPORT_STRING_API Ref<StringImpl> replace(UChar, StringImpl*);
716     ALWAYS_INLINE Ref<StringImpl> replace(UChar pattern, const char* replacement, unsigned replacementLength) { return replace(pattern, reinterpret_cast<const LChar*>(replacement), replacementLength); }
717     WTF_EXPORT_STRING_API Ref<StringImpl> replace(UChar, const LChar*, unsigned replacementLength);
718     Ref<StringImpl> replace(UChar, const UChar*, unsigned replacementLength);
719     WTF_EXPORT_STRING_API Ref<StringImpl> replace(StringImpl*, StringImpl*);
720     WTF_EXPORT_STRING_API Ref<StringImpl> replace(unsigned index, unsigned len, StringImpl*);
721
722     WTF_EXPORT_STRING_API UCharDirection defaultWritingDirection(bool* hasStrongDirectionality = nullptr);
723
724 #if USE(CF)
725     RetainPtr<CFStringRef> createCFString();
726 #endif
727 #ifdef __OBJC__
728     WTF_EXPORT_STRING_API operator NSString *();
729 #endif
730
731 #if STRING_STATS
732     ALWAYS_INLINE static StringStats& stringStats() { return m_stringStats; }
733 #endif
734
735 protected:
736     ~StringImpl();
737
738     enum CreateSymbolTag { CreateSymbol };
739
740     // Used to create new symbol strings that holds existing 8-bit [[Description]] string as a substring buffer (BufferSubstring).
741     StringImpl(CreateSymbolTag, const LChar* characters, unsigned length)
742         : m_refCount(s_refCountIncrement)
743         , m_length(length)
744         , m_data8(characters)
745         , m_hashAndFlags(s_hashFlag8BitBuffer | StringSymbol | BufferSubstring)
746     {
747         ASSERT(is8Bit());
748         ASSERT(m_data8);
749         STRING_STATS_ADD_8BIT_STRING2(m_length, true);
750     }
751
752     // Used to create new symbol strings that holds existing 16-bit [[Description]] string as a substring buffer (BufferSubstring).
753     StringImpl(CreateSymbolTag, const UChar* characters, unsigned length)
754         : m_refCount(s_refCountIncrement)
755         , m_length(length)
756         , m_data16(characters)
757         , m_hashAndFlags(StringSymbol | BufferSubstring)
758     {
759         ASSERT(!is8Bit());
760         ASSERT(m_data16);
761         STRING_STATS_ADD_16BIT_STRING2(m_length, true);
762     }
763
764     // Null symbol.
765     StringImpl(CreateSymbolTag)
766         : m_refCount(s_refCountIncrement)
767         , m_length(0)
768         , m_data8(empty()->characters8())
769         , m_hashAndFlags(s_hashFlag8BitBuffer | StringSymbol | BufferSubstring)
770     {
771         ASSERT(is8Bit());
772         ASSERT(m_data8);
773         STRING_STATS_ADD_8BIT_STRING2(m_length, true);
774     }
775
776     template<typename T>
777     static size_t allocationSize(Checked<size_t> tailElementCount)
778     {
779         return (tailOffset<T>() + tailElementCount * sizeof(T)).unsafeGet();
780     }
781
782     template<typename T>
783     static size_t tailOffset()
784     {
785 #if COMPILER(MSVC)
786         // MSVC doesn't support alignof yet.
787         return roundUpToMultipleOf<sizeof(T)>(sizeof(StringImpl));
788 #else
789         return roundUpToMultipleOf<alignof(T)>(offsetof(StringImpl, m_hashAndFlags) + sizeof(StringImpl::m_hashAndFlags));
790 #endif
791     }
792
793 private:
794     bool requiresCopy() const
795     {
796         if (bufferOwnership() != BufferInternal)
797             return true;
798
799         if (is8Bit())
800             return m_data8 == tailPointer<LChar>();
801         return m_data16 == tailPointer<UChar>();
802     }
803
804     template<typename T>
805     const T* tailPointer() const
806     {
807         return reinterpret_cast_ptr<const T*>(reinterpret_cast<const uint8_t*>(this) + tailOffset<T>());
808     }
809
810     template<typename T>
811     T* tailPointer()
812     {
813         return reinterpret_cast_ptr<T*>(reinterpret_cast<uint8_t*>(this) + tailOffset<T>());
814     }
815
816     StringImpl* const& substringBuffer() const
817     {
818         ASSERT(bufferOwnership() == BufferSubstring);
819
820         return *tailPointer<StringImpl*>();
821     }
822
823     StringImpl*& substringBuffer()
824     {
825         ASSERT(bufferOwnership() == BufferSubstring);
826
827         return *tailPointer<StringImpl*>();
828     }
829
830     // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
831     static const unsigned s_copyCharsInlineCutOff = 20;
832
833     enum class CaseConvertType { Upper, Lower };
834     template<CaseConvertType type, typename CharacterType> static Ref<StringImpl> convertASCIICase(StringImpl&, const CharacterType*, unsigned);
835
836     BufferOwnership bufferOwnership() const { return static_cast<BufferOwnership>(m_hashAndFlags & s_hashMaskBufferOwnership); }
837     template <class UCharPredicate> Ref<StringImpl> stripMatchedCharacters(UCharPredicate);
838     template <typename CharType, class UCharPredicate> Ref<StringImpl> simplifyMatchedCharactersToSpace(UCharPredicate);
839     template <typename CharType> static Ref<StringImpl> constructInternal(StringImpl*, unsigned);
840     template <typename CharType> static Ref<StringImpl> createUninitializedInternal(unsigned, CharType*&);
841     template <typename CharType> static Ref<StringImpl> createUninitializedInternalNonEmpty(unsigned, CharType*&);
842     template <typename CharType> static Ref<StringImpl> reallocateInternal(Ref<StringImpl>&&, unsigned, CharType*&);
843     template <typename CharType> static Ref<StringImpl> createInternal(const CharType*, unsigned);
844     WTF_EXPORT_PRIVATE NEVER_INLINE unsigned hashSlowCase() const;
845
846     // The bottom bit in the ref count indicates a static (immortal) string.
847     static const unsigned s_refCountFlagIsStaticString = 0x1;
848     static const unsigned s_refCountIncrement = 0x2; // This allows us to ref / deref without disturbing the static string flag.
849
850 #if STRING_STATS
851     WTF_EXPORTDATA static StringStats m_stringStats;
852 #endif
853
854 public:
855 #ifndef NDEBUG
856     void assertHashIsCorrect()
857     {
858         ASSERT(hasHash());
859         ASSERT(existingHash() == StringHasher::computeHashAndMaskTop8Bits(characters8(), length()));
860     }
861 #endif
862
863 private:
864     // These member variables must match the layout of StaticStringImpl.
865     unsigned m_refCount;
866     unsigned m_length;
867     union {
868         const LChar* m_data8;
869         const UChar* m_data16;
870     };
871     mutable unsigned m_hashAndFlags;
872 };
873
874 static_assert(sizeof(StringImpl) == sizeof(StringImpl::StaticStringImpl), "");
875
876 #if !ASSERT_DISABLED
877 // StringImpls created from StaticStringImpl will ASSERT
878 // in the generic ValueCheck<T>::checkConsistency
879 // as they are not allocated by fastMalloc.
880 // We don't currently have any way to detect that case
881 // so we ignore the consistency check for all StringImpl*.
882 template<> struct
883 ValueCheck<StringImpl*> {
884     static void checkConsistency(const StringImpl*) { }
885 };
886 #endif
887
888 template <>
889 ALWAYS_INLINE Ref<StringImpl> StringImpl::constructInternal<LChar>(StringImpl* impl, unsigned length) { return adoptRef(*new (NotNull, impl) StringImpl(length, Force8BitConstructor)); }
890 template <>
891 ALWAYS_INLINE Ref<StringImpl> StringImpl::constructInternal<UChar>(StringImpl* impl, unsigned length) { return adoptRef(*new (NotNull, impl) StringImpl(length)); }
892
893 template <>
894 ALWAYS_INLINE const LChar* StringImpl::characters<LChar>() const { return characters8(); }
895
896 template <>
897 ALWAYS_INLINE const UChar* StringImpl::characters<UChar>() const { return characters16(); }
898
899 WTF_EXPORT_STRING_API bool equal(const StringImpl*, const StringImpl*);
900 WTF_EXPORT_STRING_API bool equal(const StringImpl*, const LChar*);
901 inline bool equal(const StringImpl* a, const char* b) { return equal(a, reinterpret_cast<const LChar*>(b)); }
902 WTF_EXPORT_STRING_API bool equal(const StringImpl*, const LChar*, unsigned);
903 WTF_EXPORT_STRING_API bool equal(const StringImpl*, const UChar*, unsigned);
904 inline bool equal(const StringImpl* a, const char* b, unsigned length) { return equal(a, reinterpret_cast<const LChar*>(b), length); }
905 inline bool equal(const LChar* a, StringImpl* b) { return equal(b, a); }
906 inline bool equal(const char* a, StringImpl* b) { return equal(b, reinterpret_cast<const LChar*>(a)); }
907 WTF_EXPORT_STRING_API bool equal(const StringImpl& a, const StringImpl& b);
908
909 WTF_EXPORT_STRING_API bool equalIgnoringNullity(StringImpl*, StringImpl*);
910 WTF_EXPORT_STRING_API bool equalIgnoringNullity(const UChar*, size_t length, StringImpl*);
911
912 bool equalIgnoringASCIICase(const StringImpl&, const StringImpl&);
913 WTF_EXPORT_STRING_API bool equalIgnoringASCIICase(const StringImpl*, const StringImpl*);
914 bool equalIgnoringASCIICase(const StringImpl&, const char*);
915 bool equalIgnoringASCIICase(const StringImpl*, const char*);
916
917 WTF_EXPORT_STRING_API bool equalIgnoringASCIICaseNonNull(const StringImpl*, const StringImpl*);
918
919 template<unsigned length> bool equalLettersIgnoringASCIICase(const StringImpl&, const char (&lowercaseLetters)[length]);
920 template<unsigned length> bool equalLettersIgnoringASCIICase(const StringImpl*, const char (&lowercaseLetters)[length]);
921
922 inline size_t find(const LChar* characters, unsigned length, CharacterMatchFunctionPtr matchFunction, unsigned index = 0)
923 {
924     while (index < length) {
925         if (matchFunction(characters[index]))
926             return index;
927         ++index;
928     }
929     return notFound;
930 }
931
932 inline size_t find(const UChar* characters, unsigned length, CharacterMatchFunctionPtr matchFunction, unsigned index = 0)
933 {
934     while (index < length) {
935         if (matchFunction(characters[index]))
936             return index;
937         ++index;
938     }
939     return notFound;
940 }
941
942 template<typename CharacterType>
943 inline size_t reverseFindLineTerminator(const CharacterType* characters, unsigned length, unsigned index = UINT_MAX)
944 {
945     if (!length)
946         return notFound;
947     if (index >= length)
948         index = length - 1;
949     CharacterType c = characters[index];
950     while ((c != '\n') && (c != '\r')) {
951         if (!index--)
952             return notFound;
953         c = characters[index];
954     }
955     return index;
956 }
957
958 template<typename CharacterType>
959 inline size_t reverseFind(const CharacterType* characters, unsigned length, CharacterType matchCharacter, unsigned index = UINT_MAX)
960 {
961     if (!length)
962         return notFound;
963     if (index >= length)
964         index = length - 1;
965     while (characters[index] != matchCharacter) {
966         if (!index--)
967             return notFound;
968     }
969     return index;
970 }
971
972 ALWAYS_INLINE size_t reverseFind(const UChar* characters, unsigned length, LChar matchCharacter, unsigned index = UINT_MAX)
973 {
974     return reverseFind(characters, length, static_cast<UChar>(matchCharacter), index);
975 }
976
977 inline size_t reverseFind(const LChar* characters, unsigned length, UChar matchCharacter, unsigned index = UINT_MAX)
978 {
979     if (matchCharacter & ~0xFF)
980         return notFound;
981     return reverseFind(characters, length, static_cast<LChar>(matchCharacter), index);
982 }
983
984 inline size_t StringImpl::find(LChar character, unsigned start)
985 {
986     if (is8Bit())
987         return WTF::find(characters8(), m_length, character, start);
988     return WTF::find(characters16(), m_length, character, start);
989 }
990
991 ALWAYS_INLINE size_t StringImpl::find(char character, unsigned start)
992 {
993     return find(static_cast<LChar>(character), start);
994 }
995
996 inline size_t StringImpl::find(UChar character, unsigned start)
997 {
998     if (is8Bit())
999         return WTF::find(characters8(), m_length, character, start);
1000     return WTF::find(characters16(), m_length, character, start);
1001 }
1002
1003 template<size_t inlineCapacity> inline bool equalIgnoringNullity(const Vector<UChar, inlineCapacity>& a, StringImpl* b)
1004 {
1005     return equalIgnoringNullity(a.data(), a.size(), b);
1006 }
1007
1008 template<typename CharacterType1, typename CharacterType2>
1009 inline int codePointCompare(unsigned l1, unsigned l2, const CharacterType1* c1, const CharacterType2* c2)
1010 {
1011     const unsigned lmin = l1 < l2 ? l1 : l2;
1012     unsigned pos = 0;
1013     while (pos < lmin && *c1 == *c2) {
1014         ++c1;
1015         ++c2;
1016         ++pos;
1017     }
1018
1019     if (pos < lmin)
1020         return (c1[0] > c2[0]) ? 1 : -1;
1021
1022     if (l1 == l2)
1023         return 0;
1024
1025     return (l1 > l2) ? 1 : -1;
1026 }
1027
1028 inline int codePointCompare8(const StringImpl* string1, const StringImpl* string2)
1029 {
1030     return codePointCompare(string1->length(), string2->length(), string1->characters8(), string2->characters8());
1031 }
1032
1033 inline int codePointCompare16(const StringImpl* string1, const StringImpl* string2)
1034 {
1035     return codePointCompare(string1->length(), string2->length(), string1->characters16(), string2->characters16());
1036 }
1037
1038 inline int codePointCompare8To16(const StringImpl* string1, const StringImpl* string2)
1039 {
1040     return codePointCompare(string1->length(), string2->length(), string1->characters8(), string2->characters16());
1041 }
1042
1043 inline int codePointCompare(const StringImpl* string1, const StringImpl* string2)
1044 {
1045     if (!string1)
1046         return (string2 && string2->length()) ? -1 : 0;
1047
1048     if (!string2)
1049         return string1->length() ? 1 : 0;
1050
1051     bool string1Is8Bit = string1->is8Bit();
1052     bool string2Is8Bit = string2->is8Bit();
1053     if (string1Is8Bit) {
1054         if (string2Is8Bit)
1055             return codePointCompare8(string1, string2);
1056         return codePointCompare8To16(string1, string2);
1057     }
1058     if (string2Is8Bit)
1059         return -codePointCompare8To16(string2, string1);
1060     return codePointCompare16(string1, string2);
1061 }
1062
1063 inline bool isSpaceOrNewline(UChar c)
1064 {
1065     // Use isASCIISpace() for basic Latin-1.
1066     // This will include newlines, which aren't included in Unicode DirWS.
1067     return c <= 0x7F ? isASCIISpace(c) : u_charDirection(c) == U_WHITE_SPACE_NEUTRAL;
1068 }
1069
1070 template<typename CharacterType>
1071 inline unsigned lengthOfNullTerminatedString(const CharacterType* string)
1072 {
1073     ASSERT(string);
1074     size_t length = 0;
1075     while (string[length])
1076         ++length;
1077
1078     RELEASE_ASSERT(length < std::numeric_limits<unsigned>::max());
1079     return static_cast<unsigned>(length);
1080 }
1081
1082 inline Ref<StringImpl> StringImpl::isolatedCopy() const
1083 {
1084     if (!requiresCopy()) {
1085         if (is8Bit())
1086             return StringImpl::createWithoutCopying(m_data8, m_length);
1087         return StringImpl::createWithoutCopying(m_data16, m_length);
1088     }
1089
1090     if (is8Bit())
1091         return create(m_data8, m_length);
1092     return create(m_data16, m_length);
1093 }
1094
1095 // StringHash is the default hash for StringImpl* and RefPtr<StringImpl>
1096 template<typename T> struct DefaultHash;
1097 template<> struct DefaultHash<StringImpl*> {
1098     typedef StringHash Hash;
1099 };
1100 template<> struct DefaultHash<RefPtr<StringImpl>> {
1101     typedef StringHash Hash;
1102 };
1103
1104 inline bool equalIgnoringASCIICase(const StringImpl& a, const StringImpl& b)
1105 {
1106     return equalIgnoringASCIICaseCommon(a, b);
1107 }
1108
1109 inline bool equalIgnoringASCIICase(const StringImpl& a, const char* b)
1110 {
1111     return equalIgnoringASCIICaseCommon(a, b);
1112 }
1113
1114 inline bool equalIgnoringASCIICase(const StringImpl* a, const char* b)
1115 {
1116     return a && equalIgnoringASCIICase(*a, b);
1117 }
1118
1119 template<unsigned length> inline bool startsWithLettersIgnoringASCIICase(const StringImpl& string, const char (&lowercaseLetters)[length])
1120 {
1121     return startsWithLettersIgnoringASCIICaseCommon(string, lowercaseLetters);
1122 }
1123
1124 template<unsigned length> inline bool startsWithLettersIgnoringASCIICase(const StringImpl* string, const char (&lowercaseLetters)[length])
1125 {
1126     return string && startsWithLettersIgnoringASCIICase(*string, lowercaseLetters);
1127 }
1128
1129 template<unsigned length> inline bool equalLettersIgnoringASCIICase(const StringImpl& string, const char (&lowercaseLetters)[length])
1130 {
1131     return equalLettersIgnoringASCIICaseCommon(string, lowercaseLetters);
1132 }
1133
1134 template<unsigned length> inline bool equalLettersIgnoringASCIICase(const StringImpl* string, const char (&lowercaseLetters)[length])
1135 {
1136     return string && equalLettersIgnoringASCIICase(*string, lowercaseLetters);
1137 }
1138
1139 } // namespace WTF
1140
1141 using WTF::StringImpl;
1142 using WTF::equal;
1143 using WTF::TextCaseSensitivity;
1144 using WTF::TextCaseSensitive;
1145 using WTF::TextCaseInsensitive;
1146
1147 #endif