1dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block/*
2dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
4dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2009 Google Inc. All rights reserved.
5dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *
6dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * This library is free software; you can redistribute it and/or
7dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * modify it under the terms of the GNU Library General Public
8dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * License as published by the Free Software Foundation; either
9dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * version 2 of the License, or (at your option) any later version.
10dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *
11dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * This library is distributed in the hope that it will be useful,
12dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * but WITHOUT ANY WARRANTY; without even the implied warranty of
13dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Library General Public License for more details.
15dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *
16dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * You should have received a copy of the GNU Library General Public License
17dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * along with this library; see the file COPYING.LIB.  If not, write to
18dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Boston, MA 02110-1301, USA.
20dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block *
21dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block */
22dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
23dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#ifndef StringImpl_h
24dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#define StringImpl_h
25dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
26dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <limits.h>
27dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/ASCIICType.h>
28dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/CrossThreadRefCounted.h>
29dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include <wtf/Forward.h>
30dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/OwnFastMallocPtr.h>
3121939df44de1705786c545cd1bf519d47250322dBen Murdoch#include <wtf/StdLibExtras.h>
32a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include <wtf/StringHasher.h>
33dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/Vector.h>
34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/text/StringImplBase.h>
35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/unicode/Unicode.h>
36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
3781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if USE(CF)
38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blocktypedef const struct __CFString * CFStringRef;
39dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
40dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
41dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#ifdef __OBJC__
42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block@class NSString;
43dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
45dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// FIXME: This is a temporary layering violation while we move string code to WTF.
46dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// Landing the file moves in one patch, will follow on with patches to change the namespaces.
47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blocknamespace JSC {
48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstruct IdentifierCStringTranslator;
49dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstruct IdentifierUCharBufferTranslator;
50dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
51dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
52dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochnamespace WTF {
53dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
54dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstruct CStringTranslator;
55dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstruct HashAndCharactersTranslator;
56f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstruct HashAndUTF8CharactersTranslator;
57dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstruct UCharBufferTranslator;
58dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
59dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockenum TextCaseSensitivity { TextCaseSensitive, TextCaseInsensitive };
60dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
61dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blocktypedef OwnFastMallocPtr<const UChar> SharableUChar;
62dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blocktypedef CrossThreadRefCounted<SharableUChar> SharedUChar;
63dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blocktypedef bool (*CharacterMatchFunctionPtr)(UChar);
64dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
65dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockclass StringImpl : public StringImplBase {
66dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    friend struct JSC::IdentifierCStringTranslator;
67dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    friend struct JSC::IdentifierUCharBufferTranslator;
68dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    friend struct WTF::CStringTranslator;
69dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    friend struct WTF::HashAndCharactersTranslator;
70f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    friend struct WTF::HashAndUTF8CharactersTranslator;
71dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    friend struct WTF::UCharBufferTranslator;
7221939df44de1705786c545cd1bf519d47250322dBen Murdoch    friend class AtomicStringImpl;
73dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockprivate:
74dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Used to construct static strings, which have an special refCount that can never hit zero.
75dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // This means that the static string will never be destroyed, which is important because
76dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // static strings will be shared across threads & ref-counted in a non-threadsafe manner.
77dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    StringImpl(const UChar* characters, unsigned length, StaticStringConstructType)
78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        : StringImplBase(length, ConstructStaticString)
79dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        , m_data(characters)
80dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        , m_buffer(0)
81dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        , m_hash(0)
82dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
83dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // Ensure that the hash is computed so that AtomicStringHash can call existingHash()
84dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // with impunity. The empty string is special because it is never entered into
85dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // AtomicString's HashKey, but still needs to compare correctly.
86dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        hash();
87dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
88dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
89dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Create a normal string with internal storage (BufferInternal)
90dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    StringImpl(unsigned length)
91dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        : StringImplBase(length, BufferInternal)
92dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        , m_data(reinterpret_cast<const UChar*>(this + 1))
93dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        , m_buffer(0)
94dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        , m_hash(0)
95dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
96dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(m_data);
97dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(m_length);
98dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
99dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Create a StringImpl adopting ownership of the provided buffer (BufferOwned)
101dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    StringImpl(const UChar* characters, unsigned length)
102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        : StringImplBase(length, BufferOwned)
103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        , m_data(characters)
104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        , m_buffer(0)
105dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        , m_hash(0)
106dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(m_data);
108dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(m_length);
109dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
110dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Used to create new strings that are a substring of an existing StringImpl (BufferSubstring)
112dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    StringImpl(const UChar* characters, unsigned length, PassRefPtr<StringImpl> base)
113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        : StringImplBase(length, BufferSubstring)
114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        , m_data(characters)
11528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        , m_substringBuffer(base.leakRef())
116dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        , m_hash(0)
117dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
118dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(m_data);
119dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(m_length);
120dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(m_substringBuffer->bufferOwnership() != BufferSubstring);
121dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
122dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
123dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Used to construct new strings sharing an existing SharedUChar (BufferShared)
124dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    StringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer)
125dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        : StringImplBase(length, BufferShared)
126dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        , m_data(characters)
12728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        , m_sharedBuffer(sharedBuffer.leakRef())
128dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        , m_hash(0)
129dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
130dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(m_data);
131dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(m_length);
132dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
133dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
134dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // For use only by AtomicString's XXXTranslator helpers.
135dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void setHash(unsigned hash)
136dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
137dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(!isStatic());
138dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(!m_hash);
1392bde8e466a4451c7319e3a072d118917957d6554Steve Block        ASSERT(hash == StringHasher::computeHash(m_data, m_length));
140dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_hash = hash;
141dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
142dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
143dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockpublic:
144dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ~StringImpl();
145dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
146dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static PassRefPtr<StringImpl> create(const UChar*, unsigned length);
147dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static PassRefPtr<StringImpl> create(const char*, unsigned length);
148dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static PassRefPtr<StringImpl> create(const char*);
149dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static PassRefPtr<StringImpl> create(const UChar*, unsigned length, PassRefPtr<SharedUChar> sharedBuffer);
1506c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    static ALWAYS_INLINE PassRefPtr<StringImpl> create(PassRefPtr<StringImpl> rep, unsigned offset, unsigned length)
151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
152dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(rep);
153dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(length <= rep->length());
154dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
155dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!length)
156dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return empty();
157dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
158dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        StringImpl* ownerRep = (rep->bufferOwnership() == BufferSubstring) ? rep->m_substringBuffer : rep.get();
159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return adoptRef(new StringImpl(rep->m_data + offset, length, ownerRep));
160dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
161dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
162dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static PassRefPtr<StringImpl> createUninitialized(unsigned length, UChar*& data);
1636c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    static ALWAYS_INLINE PassRefPtr<StringImpl> tryCreateUninitialized(unsigned length, UChar*& output)
164dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
165dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (!length) {
166dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            output = 0;
167dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return empty();
168dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
169dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
170a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar))) {
1716c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            output = 0;
172dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return 0;
1736c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        }
174dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        StringImpl* resultImpl;
1756c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (!tryFastMalloc(sizeof(UChar) * length + sizeof(StringImpl)).getValue(resultImpl)) {
1766c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            output = 0;
177dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return 0;
1786c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        }
179dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        output = reinterpret_cast<UChar*>(resultImpl + 1);
180dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return adoptRef(new(resultImpl) StringImpl(length));
181dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
182dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
18321939df44de1705786c545cd1bf519d47250322dBen Murdoch    static unsigned dataOffset() { return OBJECT_OFFSETOF(StringImpl, m_data); }
184dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static PassRefPtr<StringImpl> createWithTerminatingNullCharacter(const StringImpl&);
185dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static PassRefPtr<StringImpl> createStrippingNullCharacters(const UChar*, unsigned length);
186dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
187dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    template<size_t inlineCapacity>
188dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static PassRefPtr<StringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
189dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
190dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (size_t size = vector.size()) {
191dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            ASSERT(vector.data());
192a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            if (size > std::numeric_limits<unsigned>::max())
193a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch                CRASH();
194dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return adoptRef(new StringImpl(vector.releaseBuffer(), size));
195dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
196dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return empty();
197dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
198dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static PassRefPtr<StringImpl> adopt(StringBuffer&);
199dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
200dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    SharedUChar* sharedBuffer();
201dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    const UChar* characters() const { return m_data; }
202dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
203dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    size_t cost()
204dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
205dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // For substrings, return the cost of the base string.
206dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (bufferOwnership() == BufferSubstring)
207dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return m_substringBuffer->cost();
208dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
209dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (m_refCountAndFlags & s_refCountFlagShouldReportedCost) {
210dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_refCountAndFlags &= ~s_refCountFlagShouldReportedCost;
211dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return m_length;
212dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
213dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return 0;
214dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
215dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
216dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool isIdentifier() const { return m_refCountAndFlags & s_refCountFlagIsIdentifier; }
217dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void setIsIdentifier(bool isIdentifier)
218dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
219dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT(!isStatic());
220dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (isIdentifier)
221dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_refCountAndFlags |= s_refCountFlagIsIdentifier;
222dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        else
223dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_refCountAndFlags &= ~s_refCountFlagIsIdentifier;
224dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
225dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
226dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool hasTerminatingNullCharacter() const { return m_refCountAndFlags & s_refCountFlagHasTerminatingNullCharacter; }
227dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
22821939df44de1705786c545cd1bf519d47250322dBen Murdoch    bool isAtomic() const { return m_refCountAndFlags & s_refCountFlagIsAtomic; }
22921939df44de1705786c545cd1bf519d47250322dBen Murdoch    void setIsAtomic(bool isIdentifier)
23021939df44de1705786c545cd1bf519d47250322dBen Murdoch    {
23121939df44de1705786c545cd1bf519d47250322dBen Murdoch        ASSERT(!isStatic());
23221939df44de1705786c545cd1bf519d47250322dBen Murdoch        if (isIdentifier)
23321939df44de1705786c545cd1bf519d47250322dBen Murdoch            m_refCountAndFlags |= s_refCountFlagIsAtomic;
23421939df44de1705786c545cd1bf519d47250322dBen Murdoch        else
23521939df44de1705786c545cd1bf519d47250322dBen Murdoch            m_refCountAndFlags &= ~s_refCountFlagIsAtomic;
23621939df44de1705786c545cd1bf519d47250322dBen Murdoch    }
237dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2382bde8e466a4451c7319e3a072d118917957d6554Steve Block    unsigned hash() const { if (!m_hash) m_hash = StringHasher::computeHash(m_data, m_length); return m_hash; }
239dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    unsigned existingHash() const { ASSERT(m_hash); return m_hash; }
240dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
241dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) delete this; }
242dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ALWAYS_INLINE bool hasOneRef() const { return (m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic)) == s_refCountIncrement; }
243dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
244dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static StringImpl* empty();
245dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
246dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
247dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
248dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (numCharacters <= s_copyCharsInlineCutOff) {
249dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            for (unsigned i = 0; i < numCharacters; ++i)
250dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                destination[i] = source[i];
251dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        } else
252dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            memcpy(destination, source, numCharacters * sizeof(UChar));
253dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
254dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
255dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Returns a StringImpl suitable for use on another thread.
256dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PassRefPtr<StringImpl> crossThreadString();
257dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Makes a deep copy. Helpful only if you need to use a String on another thread
258dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // (use crossThreadString if the method call doesn't need to be threadsafe).
259dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Since StringImpl objects are immutable, there's no other reason to make a copy.
260dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PassRefPtr<StringImpl> threadsafeCopy() const;
261dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
262dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PassRefPtr<StringImpl> substring(unsigned pos, unsigned len = UINT_MAX);
263dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
264dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    UChar operator[](unsigned i) { ASSERT(i < m_length); return m_data[i]; }
265dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    UChar32 characterStartingAt(unsigned);
266dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
267dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool containsOnlyWhitespace();
268dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
269dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    int toIntStrict(bool* ok = 0, int base = 10);
270dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    unsigned toUIntStrict(bool* ok = 0, int base = 10);
271dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    int64_t toInt64Strict(bool* ok = 0, int base = 10);
272dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    uint64_t toUInt64Strict(bool* ok = 0, int base = 10);
273dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    intptr_t toIntPtrStrict(bool* ok = 0, int base = 10);
274dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
275dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    int toInt(bool* ok = 0); // ignores trailing garbage
276dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    unsigned toUInt(bool* ok = 0); // ignores trailing garbage
277dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    int64_t toInt64(bool* ok = 0); // ignores trailing garbage
278dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    uint64_t toUInt64(bool* ok = 0); // ignores trailing garbage
279dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    intptr_t toIntPtr(bool* ok = 0); // ignores trailing garbage
280dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
28181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    double toDouble(bool* ok = 0, bool* didReadNumber = 0);
28281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    float toFloat(bool* ok = 0, bool* didReadNumber = 0);
283dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
284dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PassRefPtr<StringImpl> lower();
285dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PassRefPtr<StringImpl> upper();
2864576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
2874576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    enum LastCharacterBehavior { ObscureLastCharacter, DisplayLastCharacter };
2884576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
2894576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    PassRefPtr<StringImpl> secure(UChar, LastCharacterBehavior = ObscureLastCharacter);
290dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PassRefPtr<StringImpl> foldCase();
291dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
292dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PassRefPtr<StringImpl> stripWhiteSpace();
293dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PassRefPtr<StringImpl> simplifyWhiteSpace();
294dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
295dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PassRefPtr<StringImpl> removeCharacters(CharacterMatchFunctionPtr);
296dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
297f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    size_t find(UChar, unsigned index = 0);
298f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    size_t find(CharacterMatchFunctionPtr, unsigned index = 0);
299f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    size_t find(const char*, unsigned index = 0);
300f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    size_t find(StringImpl*, unsigned index = 0);
301f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    size_t findIgnoringCase(const char*, unsigned index = 0);
302f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    size_t findIgnoringCase(StringImpl*, unsigned index = 0);
303f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
304f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    size_t reverseFind(UChar, unsigned index = UINT_MAX);
305f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    size_t reverseFind(StringImpl*, unsigned index = UINT_MAX);
306f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    size_t reverseFindIgnoringCase(StringImpl*, unsigned index = UINT_MAX);
307f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
308f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    bool startsWith(StringImpl* str, bool caseSensitive = true) { return (caseSensitive ? reverseFind(str, 0) : reverseFindIgnoringCase(str, 0)) == 0; }
309dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool endsWith(StringImpl*, bool caseSensitive = true);
310dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
311dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PassRefPtr<StringImpl> replace(UChar, UChar);
312dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PassRefPtr<StringImpl> replace(UChar, StringImpl*);
313dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PassRefPtr<StringImpl> replace(StringImpl*, StringImpl*);
314dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    PassRefPtr<StringImpl> replace(unsigned index, unsigned len, StringImpl*);
315dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
31681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    WTF::Unicode::Direction defaultWritingDirection(bool* hasStrongDirectionality = 0);
317dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
31881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if USE(CF)
319dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    CFStringRef createCFString();
320dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
321dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#ifdef __OBJC__
322dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    operator NSString*();
323dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
324dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
325dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockprivate:
326dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
327dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static const unsigned s_copyCharsInlineCutOff = 20;
328dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
329dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    static PassRefPtr<StringImpl> createStrippingNullCharactersSlowCase(const UChar*, unsigned length);
330dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
331dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    BufferOwnership bufferOwnership() const { return static_cast<BufferOwnership>(m_refCountAndFlags & s_refCountMaskBufferOwnership); }
332dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; }
333dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    const UChar* m_data;
334dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    union {
335dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        void* m_buffer;
336dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        StringImpl* m_substringBuffer;
337dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        SharedUChar* m_sharedBuffer;
338dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    };
339dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    mutable unsigned m_hash;
340dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block};
341dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
342dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool equal(const StringImpl*, const StringImpl*);
343dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool equal(const StringImpl*, const char*);
344dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockinline bool equal(const char* a, StringImpl* b) { return equal(b, a); }
345dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
346dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool equalIgnoringCase(StringImpl*, StringImpl*);
347dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool equalIgnoringCase(StringImpl*, const char*);
348dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockinline bool equalIgnoringCase(const char* a, StringImpl* b) { return equalIgnoringCase(b, a); }
349dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool equalIgnoringCase(const UChar* a, const char* b, unsigned length);
350dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockinline bool equalIgnoringCase(const char* a, const UChar* b, unsigned length) { return equalIgnoringCase(b, a, length); }
351dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
352dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool equalIgnoringNullity(StringImpl*, StringImpl*);
353dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
3542fc2651226baac27029e38c9d6ef883fa32084dbSteve Blocktemplate<size_t inlineCapacity>
3552fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockbool equalIgnoringNullity(const Vector<UChar, inlineCapacity>& a, StringImpl* b)
3562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
3572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!b)
3582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return !a.size();
3592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (a.size() != b->length())
3602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return false;
3612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return !memcmp(a.data(), b->characters(), b->length());
3622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
3632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkeint codePointCompare(const StringImpl*, const StringImpl*);
3655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
366dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic inline bool isSpaceOrNewline(UChar c)
367dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
368dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Use isASCIISpace() for basic Latin-1.
369dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // This will include newlines, which aren't included in Unicode DirWS.
370dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return c <= 0x7F ? WTF::isASCIISpace(c) : WTF::Unicode::direction(c) == WTF::Unicode::WhiteSpaceNeutral;
371dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
372dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
373dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block// This is a hot function because it's used when parsing HTML.
374dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockinline PassRefPtr<StringImpl> StringImpl::createStrippingNullCharacters(const UChar* characters, unsigned length)
375dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
376dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ASSERT(characters);
377dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    ASSERT(length);
378dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
379dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Optimize for the case where there are no Null characters by quickly
380dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // searching for nulls, and then using StringImpl::create, which will
381dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // memcpy the whole buffer.  This is faster than assigning character by
382dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // character during the loop.
383dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
384dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Fast case.
385dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    int foundNull = 0;
386dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    for (unsigned i = 0; !foundNull && i < length; i++) {
387dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        int c = characters[i]; // more efficient than using UChar here (at least on Intel Mac OS)
388dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        foundNull |= !c;
389dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
390dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (!foundNull)
391dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return StringImpl::create(characters, length);
392dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
393dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return StringImpl::createStrippingNullCharactersSlowCase(characters, length);
394dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
395dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
396dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochstruct StringHash;
397dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
398dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch// StringHash is the default hash for StringImpl* and RefPtr<StringImpl>
399dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochtemplate<typename T> struct DefaultHash;
400dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochtemplate<> struct DefaultHash<StringImpl*> {
401dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    typedef StringHash Hash;
402dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch};
403dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochtemplate<> struct DefaultHash<RefPtr<StringImpl> > {
404dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    typedef StringHash Hash;
405dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch};
406dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
407dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
408dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
409dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochusing WTF::StringImpl;
410dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochusing WTF::equal;
411dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochusing WTF::TextCaseSensitivity;
412dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochusing WTF::TextCaseSensitive;
413dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochusing WTF::TextCaseInsensitive;
414dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
415dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif
416