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