15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (C) 1999 Antti Koivisto (koivisto@kde.org) 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (C) 2001 Dirk Mueller ( mueller@kde.org ) 5926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved. 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 2693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/text/StringImpl.h" 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 28f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "wtf/DynamicAnnotations.h" 298abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#include "wtf/LeakAnnotations.h" 301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "wtf/MainThread.h" 31bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "wtf/PartitionAlloc.h" 3293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/StdLibExtras.h" 33bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "wtf/WTF.h" 3493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/text/AtomicString.h" 3593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/text/StringBuffer.h" 3693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/text/StringHash.h" 3793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/unicode/CharacterNames.h" 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifdef STRING_STATS 4093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/DataLog.h" 4151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "wtf/HashMap.h" 4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "wtf/HashSet.h" 43f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include "wtf/ProcessID.h" 445267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "wtf/RefCounted.h" 4551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "wtf/ThreadingPrimitives.h" 46926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#include <unistd.h> 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace std; 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WTF { 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace Unicode; 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 55f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)COMPILE_ASSERT(sizeof(StringImpl) == 3 * sizeof(int), StringImpl_should_stay_small); 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifdef STRING_STATS 5893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 5993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static Mutex& statsMutex() 6093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 6193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) DEFINE_STATIC_LOCAL(Mutex, mutex, ()); 6293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return mutex; 6393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 6493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 6593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static HashSet<void*>& liveStrings() 6693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 6793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // Notice that we can't use HashSet<StringImpl*> because then HashSet would dedup identical strings. 6893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) DEFINE_STATIC_LOCAL(HashSet<void*>, strings, ()); 6993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) return strings; 7093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 7193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 7293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void addStringForStats(StringImpl* string) 7393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 7493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) MutexLocker locker(statsMutex()); 7593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) liveStrings().add(string); 7693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 7793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 7893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)void removeStringForStats(StringImpl* string) 7993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 8093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) MutexLocker locker(statsMutex()); 8193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) liveStrings().remove(string); 8293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 8393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 8493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static void fillWithSnippet(const StringImpl* string, Vector<char>& snippet) 8593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 865267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) const unsigned kMaxSnippetLength = 64; 8793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) snippet.clear(); 885267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 895267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) size_t expectedLength = std::min(string->length(), kMaxSnippetLength); 905267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (expectedLength == kMaxSnippetLength) 915267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) expectedLength += 3; // For the "...". 925267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) ++expectedLength; // For the terminating '\0'. 935267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) snippet.reserveCapacity(expectedLength); 945267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 9593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) size_t i; 965267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) for (i = 0; i < string->length() && i < kMaxSnippetLength; ++i) { 9793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) UChar c = (*string)[i]; 9893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (isASCIIPrintable(c)) 9993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) snippet.append(c); 1005267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) else 1015267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) snippet.append('?'); 10293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 10393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (i < string->length()) { 10493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) snippet.append('.'); 10593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) snippet.append('.'); 10693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) snippet.append('.'); 10793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 10893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) snippet.append('\0'); 10993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 11093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 1115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)static bool isUnnecessarilyWide(const StringImpl* string) 1125267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles){ 1135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (string->is8Bit()) 1145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return false; 1155267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) UChar c = 0; 1165267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) for (unsigned i = 0; i < string->length(); ++i) 1175267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) c |= (*string)[i] >> 8; 1185267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return !c; 1195267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)} 1205267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 1215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)class PerStringStats : public RefCounted<PerStringStats> { 1225267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)public: 1235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) static PassRefPtr<PerStringStats> create() 12493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) { 1255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return adoptRef(new PerStringStats); 12693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 12793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 12893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) void add(const StringImpl* string) 12993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) { 13093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) ++m_numberOfCopies; 13193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (!m_length) { 13293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) m_length = string->length(); 13393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) fillWithSnippet(string, m_snippet); 13493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 13593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) if (string->isAtomic()) 13693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) ++m_numberOfAtomicCopies; 1375267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (isUnnecessarilyWide(string)) 1385267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) m_unnecessarilyWide = true; 13993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 14093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 1415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) size_t totalCharacters() const 14293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) { 1435267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return m_numberOfCopies * m_length; 14493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 14593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 14693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) void print() 14793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) { 1485267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) const char* status = "ok"; 1497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (m_unnecessarilyWide) 1505267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) status = "16"; 1515267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) dataLogF("%8u copies (%s) of length %8u %s\n", m_numberOfCopies, status, m_length, m_snippet.data()); 15293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 15393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 1545267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) bool m_unnecessarilyWide; 15593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) unsigned m_numberOfCopies; 15693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) unsigned m_length; 15793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) unsigned m_numberOfAtomicCopies; 15893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) Vector<char> m_snippet; 1595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 1605267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)private: 1615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) PerStringStats() 1627757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch : m_unnecessarilyWide(false) 1635267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) , m_numberOfCopies(0) 1645267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) , m_length(0) 1655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) , m_numberOfAtomicCopies(0) 1665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) { 1675267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) } 16893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}; 16993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 1705267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)bool operator<(const RefPtr<PerStringStats>& a, const RefPtr<PerStringStats>& b) 17193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 1725267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (a->m_unnecessarilyWide != b->m_unnecessarilyWide) 1735267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return !a->m_unnecessarilyWide && b->m_unnecessarilyWide; 1745267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (a->totalCharacters() != b->totalCharacters()) 1755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return a->totalCharacters() < b->totalCharacters(); 1765267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (a->m_numberOfCopies != b->m_numberOfCopies) 1775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return a->m_numberOfCopies < b->m_numberOfCopies; 1785267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) if (a->m_length != b->m_length) 1795267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return a->m_length < b->m_length; 1805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) return a->m_numberOfAtomicCopies < b->m_numberOfAtomicCopies; 18193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 18293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 18393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)static void printLiveStringStats(void*) 18493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){ 18593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) MutexLocker locker(statsMutex()); 18693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) HashSet<void*>& strings = liveStrings(); 18793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 1885267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) HashMap<StringImpl*, RefPtr<PerStringStats> > stats; 18993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) for (HashSet<void*>::iterator iter = strings.begin(); iter != strings.end(); ++iter) { 19093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) StringImpl* string = static_cast<StringImpl*>(*iter); 1915267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) HashMap<StringImpl*, RefPtr<PerStringStats> >::iterator entry = stats.find(string); 1925267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) RefPtr<PerStringStats> value = entry == stats.end() ? RefPtr<PerStringStats>(PerStringStats::create()) : entry->value; 1935267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) value->add(string); 1945267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) stats.set(string, value.release()); 19593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) } 19693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 1975267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) Vector<RefPtr<PerStringStats> > all; 1985267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) for (HashMap<StringImpl*, RefPtr<PerStringStats> >::iterator iter = stats.begin(); iter != stats.end(); ++iter) 19993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) all.append(iter->value); 2005267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) 20193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) std::sort(all.begin(), all.end()); 20293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) std::reverse(all.begin(), all.end()); 20393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) for (size_t i = 0; i < 20 && i < all.size(); ++i) 2045267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) all[i]->print(); 20593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)} 20693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)StringStats StringImpl::m_stringStats; 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned StringStats::s_stringRemovesTillPrintStats = StringStats::s_printStringStatsFrequency; 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void StringStats::removeString(StringImpl* string) 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned length = string->length(); 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --m_totalNumberStrings; 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (string->is8Bit()) { 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --m_number8BitStrings; 2187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch m_total8BitData -= length; 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --m_number16BitStrings; 2217757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch m_total16BitData -= length; 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!--s_stringRemovesTillPrintStats) { 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) s_stringRemovesTillPrintStats = s_printStringStatsFrequency; 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) printStats(); 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void StringStats::printStats() 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 23253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) dataLogF("String stats for process id %d:\n", getCurrentProcessID()); 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned long long totalNumberCharacters = m_total8BitData + m_total16BitData; 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double percent8Bit = m_totalNumberStrings ? ((double)m_number8BitStrings * 100) / (double)m_totalNumberStrings : 0.0; 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double average8bitLength = m_number8BitStrings ? (double)m_total8BitData / (double)m_number8BitStrings : 0.0; 237926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) dataLogF("%8u (%5.2f%%) 8 bit %12llu chars %12llu bytes avg length %6.1f\n", m_number8BitStrings, percent8Bit, m_total8BitData, m_total8BitData, average8bitLength); 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double percent16Bit = m_totalNumberStrings ? ((double)m_number16BitStrings * 100) / (double)m_totalNumberStrings : 0.0; 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double average16bitLength = m_number16BitStrings ? (double)m_total16BitData / (double)m_number16BitStrings : 0.0; 241926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) dataLogF("%8u (%5.2f%%) 16 bit %12llu chars %12llu bytes avg length %6.1f\n", m_number16BitStrings, percent16Bit, m_total16BitData, m_total16BitData * 2, average16bitLength); 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double averageLength = m_totalNumberStrings ? (double)totalNumberCharacters / (double)m_totalNumberStrings : 0.0; 2447757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch unsigned long long totalDataBytes = m_total8BitData + m_total16BitData * 2; 245926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) dataLogF("%8u Total %12llu chars %12llu bytes avg length %6.1f\n", m_totalNumberStrings, totalNumberCharacters, totalDataBytes, averageLength); 2467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch unsigned long long totalSavedBytes = m_total8BitData; 247926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) double percentSavings = totalSavedBytes ? ((double)totalSavedBytes * 100) / (double)(totalDataBytes + totalSavedBytes) : 0.0; 248926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) dataLogF(" Total savings %12llu bytes (%5.2f%%)\n", totalSavedBytes, percentSavings); 24993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) 2507757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch unsigned totalOverhead = m_totalNumberStrings * sizeof(StringImpl); 2517757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch double overheadPercent = (double)totalOverhead / (double)totalDataBytes * 100; 2527757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch dataLogF(" StringImpl overheader: %8u (%5.2f%%)\n", totalOverhead, overheadPercent); 2537757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 25493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) callOnMainThread(printLiveStringStats, 0); 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 258bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)void* StringImpl::operator new(size_t size) 259bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 260bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) ASSERT(size == sizeof(StringImpl)); 261bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return partitionAllocGeneric(Partitions::getBufferPartition(), size); 262bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 263bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 264bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)void StringImpl::operator delete(void* ptr) 265bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 266bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) partitionFreeGeneric(Partitions::getBufferPartition(), ptr); 267bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 268bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 2698abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)inline StringImpl::~StringImpl() 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!isStatic()); 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) STRING_STATS_REMOVE_STRING(this); 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isAtomic()) 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) AtomicString::remove(this); 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2798abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)void StringImpl::destroyIfNotStatic() 2808abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles){ 2818abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) if (!isStatic()) 2828abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) delete this; 2838abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)} 2848abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, LChar*& data) 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!length) { 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data = 0; 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return empty(); 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Allocate a single buffer large enough to contain the StringImpl 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // struct as well as the data which it contains. This removes one 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // heap allocation from this call. 29553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(length <= ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(LChar))); 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t size = sizeof(StringImpl) + length * sizeof(LChar); 297bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) StringImpl* string = static_cast<StringImpl*>(partitionAllocGeneric(Partitions::getBufferPartition(), size)); 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data = reinterpret_cast<LChar*>(string + 1); 300bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return adoptRef(new (string) StringImpl(length, Force8BitConstructor)); 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*& data) 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!length) { 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data = 0; 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return empty(); 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Allocate a single buffer large enough to contain the StringImpl 311591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch // struct as well as the data which it contains. This removes one 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // heap allocation from this call. 31353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(length <= ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar))); 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t size = sizeof(StringImpl) + length * sizeof(UChar); 315bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) StringImpl* string = static_cast<StringImpl*>(partitionAllocGeneric(Partitions::getBufferPartition(), size)); 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data = reinterpret_cast<UChar*>(string + 1); 318bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return adoptRef(new (string) StringImpl(length)); 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::reallocate(PassRefPtr<StringImpl> originalString, unsigned length, LChar*& data) 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(originalString->is8Bit()); 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(originalString->hasOneRef()); 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!length) { 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data = 0; 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return empty(); 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 331bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // Same as createUninitialized() except here we use realloc. 33253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(length <= ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(LChar))); 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t size = sizeof(StringImpl) + length * sizeof(LChar); 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) originalString->~StringImpl(); 335bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) StringImpl* string = static_cast<StringImpl*>(partitionReallocGeneric(Partitions::getBufferPartition(), originalString.leakRef(), size)); 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data = reinterpret_cast<LChar*>(string + 1); 338bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return adoptRef(new (string) StringImpl(length, Force8BitConstructor)); 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::reallocate(PassRefPtr<StringImpl> originalString, unsigned length, UChar*& data) 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!originalString->is8Bit()); 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(originalString->hasOneRef()); 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!length) { 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data = 0; 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return empty(); 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 351bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // Same as createUninitialized() except here we use realloc. 35253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(length <= ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar))); 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t size = sizeof(StringImpl) + length * sizeof(UChar); 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) originalString->~StringImpl(); 355bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) StringImpl* string = static_cast<StringImpl*>(partitionReallocGeneric(Partitions::getBufferPartition(), originalString.leakRef(), size)); 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data = reinterpret_cast<UChar*>(string + 1); 358bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return adoptRef(new (string) StringImpl(length)); 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 361e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)static StaticStringsTable& staticStrings() 3621e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){ 363e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) DEFINE_STATIC_LOCAL(StaticStringsTable, staticStrings, ()); 3641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return staticStrings; 3651e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)} 3661e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 3671e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#ifndef NDEBUG 3681e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)static bool s_allowCreationOfStaticStrings = true; 3691e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#endif 3701e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 371e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)const StaticStringsTable& StringImpl::allStaticStrings() 3721e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){ 3731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return staticStrings(); 3741e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)} 3751e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 3761e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)void StringImpl::freezeStaticStrings() 3771e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){ 3781e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) ASSERT(isMainThread()); 3791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 3801e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#ifndef NDEBUG 3811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) s_allowCreationOfStaticStrings = false; 3821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#endif 3831e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)} 3841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 385e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles)unsigned StringImpl::m_highestStaticStringLength = 0; 386e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) 387f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)StringImpl* StringImpl::createStatic(const char* string, unsigned length, unsigned hash) 388f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){ 3891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) ASSERT(s_allowCreationOfStaticStrings); 390f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) ASSERT(string); 391f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) ASSERT(length); 392f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 393e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) StaticStringsTable::const_iterator it = staticStrings().find(hash); 394e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) if (it != staticStrings().end()) { 395e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) ASSERT(!memcmp(string, it->value + 1, length * sizeof(LChar))); 396e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) return it->value; 397e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) } 398e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) 399f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) // Allocate a single buffer large enough to contain the StringImpl 400f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) // struct as well as the data which it contains. This removes one 401f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) // heap allocation from this call. 402f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) RELEASE_ASSERT(length <= ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(LChar))); 403f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) size_t size = sizeof(StringImpl) + length * sizeof(LChar); 404e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) 4058abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) WTF_ANNOTATE_SCOPED_MEMORY_LEAK; 406bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) StringImpl* impl = static_cast<StringImpl*>(partitionAllocGeneric(Partitions::getBufferPartition(), size)); 407f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 408f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) LChar* data = reinterpret_cast<LChar*>(impl + 1); 409bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) impl = new (impl) StringImpl(length, hash, StaticString); 410f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data, string, length * sizeof(LChar)); 411f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#ifndef NDEBUG 412f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) impl->assertHashIsCorrect(); 413f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#endif 4141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 4151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) ASSERT(isMainThread()); 416e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) m_highestStaticStringLength = std::max(m_highestStaticStringLength, length); 417e08f70592b3fc0d5e68b9b914c9196e813720070Torne (Richard Coles) staticStrings().add(hash, impl); 418f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) WTF_ANNOTATE_BENIGN_RACE(impl, 419f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles) "Benign race on the reference counter of a static string created by StringImpl::createStatic"); 4201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 421f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return impl; 422f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)} 423f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned length) 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!characters || !length) 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return empty(); 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar* data; 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> string = createUninitialized(length, data); 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) memcpy(data, characters, length * sizeof(UChar)); 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return string.release(); 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::create(const LChar* characters, unsigned length) 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!characters || !length) 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return empty(); 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar* data; 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> string = createUninitialized(length, data); 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) memcpy(data, characters, length * sizeof(LChar)); 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return string.release(); 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::create8BitIfPossible(const UChar* characters, unsigned length) 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!characters || !length) 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return empty(); 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar* data; 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> string = createUninitialized(length, data); 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < length; ++i) { 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (characters[i] & 0xff00) 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return create(characters, length); 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data[i] = static_cast<LChar>(characters[i]); 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return string.release(); 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::create(const LChar* string) 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!string) 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return empty(); 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t length = strlen(reinterpret_cast<const char*>(string)); 46853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(length <= numeric_limits<unsigned>::max()); 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return create(string, length); 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool StringImpl::containsOnlyWhitespace() 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: The definition of whitespace here includes a number of characters 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // that are not whitespace from the point of view of RenderText; I wonder if 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // that's a problem in practice. 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 478926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = 0; i < m_length; ++i) { 479f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) UChar c = characters8()[i]; 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isASCIISpace(c)) 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 487926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = 0; i < m_length; ++i) { 488f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) UChar c = characters16()[i]; 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isASCIISpace(c)) 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::substring(unsigned start, unsigned length) 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (start >= m_length) 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return empty(); 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned maxLength = m_length - start; 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (length >= maxLength) { 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!start) 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) length = maxLength; 5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 506f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return create(characters8() + start, length); 5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 508f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return create(characters16() + start, length); 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)UChar32 StringImpl::characterStartingAt(unsigned i) 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 514f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return characters8()[i]; 515f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (U16_IS_SINGLE(characters16()[i])) 516f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return characters16()[i]; 517f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) if (i + 1 < m_length && U16_IS_LEAD(characters16()[i]) && U16_IS_TRAIL(characters16()[i + 1])) 518f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return U16_GET_SUPPLEMENTARY(characters16()[i], characters16()[i + 1]); 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::lower() 5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: This is a hot function in the Dromaeo benchmark, specifically the 5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // no-op code path up through the first 'return' statement. 526591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // First scan the string for uppercase and non-ASCII characters: 5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool noUpper = true; 5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar ored = 0; 5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 531f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) const LChar* end = characters8() + m_length; 532f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) for (const LChar* chp = characters8(); chp != end; ++chp) { 5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (UNLIKELY(isASCIIUpper(*chp))) 5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) noUpper = false; 5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ored |= *chp; 5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Nothing to do if the string is all ASCII with no uppercase. 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (noUpper && !(ored & ~0x7F)) 5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 54153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(m_length <= static_cast<unsigned>(numeric_limits<int32_t>::max())); 5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int32_t length = m_length; 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar* data8; 5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(length, data8); 5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!(ored & ~0x7F)) { 548926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (int32_t i = 0; i < length; ++i) 549f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) data8[i] = toASCIILower(characters8()[i]); 5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do a slower implementation for cases that include non-ASCII Latin-1 characters. 555926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (int32_t i = 0; i < length; ++i) 556f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) data8[i] = static_cast<LChar>(Unicode::toLower(characters8()[i])); 5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 561f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) const UChar* end = characters16() + m_length; 562f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) for (const UChar* chp = characters16(); chp != end; ++chp) { 5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (UNLIKELY(isASCIIUpper(*chp))) 5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) noUpper = false; 5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ored |= *chp; 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Nothing to do if the string is all ASCII with no uppercase. 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (noUpper && !(ored & ~0x7F)) 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 57153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(m_length <= static_cast<unsigned>(numeric_limits<int32_t>::max())); 5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int32_t length = m_length; 5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!(ored & ~0x7F)) { 5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar* data16; 5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(m_length, data16); 577591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 578926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (int32_t i = 0; i < length; ++i) { 579f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) UChar c = characters16()[i]; 5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data16[i] = toASCIILower(c); 5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 584591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do a slower implementation for cases that include non-ASCII characters. 5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar* data16; 5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(m_length, data16); 5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool error; 590f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) int32_t realLength = Unicode::toLower(data16, length, characters16(), m_length, &error); 5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!error && realLength == length) 5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newImpl = createUninitialized(realLength, data16); 595f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) Unicode::toLower(data16, realLength, characters16(), m_length, &error); 5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (error) 5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::upper() 6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This function could be optimized for no-op cases the way lower() is, 6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // but in empirical testing, few actual calls to upper() are no-ops, so 6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // it wouldn't be worth the extra time for pre-scanning. 6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 60753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(m_length <= static_cast<unsigned>(numeric_limits<int32_t>::max())); 6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int32_t length = m_length; 6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 6115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar* data8; 6125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(m_length, data8); 613591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do a faster loop for the case where all the characters are ASCII. 6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar ored = 0; 616926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (int i = 0; i < length; ++i) { 617f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) LChar c = characters8()[i]; 6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ored |= c; 6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data8[i] = toASCIIUpper(c); 6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!(ored & ~0x7F)) 6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do a slower implementation for cases that include non-ASCII Latin-1 characters. 6255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int numberSharpSCharacters = 0; 6265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // There are two special cases. 6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 1. latin-1 characters when converted to upper case are 16 bit characters. 6295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 2. Lower case sharp-S converts to "SS" (two characters) 630926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (int32_t i = 0; i < length; ++i) { 631f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) LChar c = characters8()[i]; 6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (UNLIKELY(c == smallLetterSharpS)) 633926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ++numberSharpSCharacters; 6345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar upper = Unicode::toUpper(c); 6355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (UNLIKELY(upper > 0xff)) { 6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Since this upper-cased character does not fit in an 8-bit string, we need to take the 16-bit path. 6375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) goto upconvert; 6385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data8[i] = static_cast<LChar>(upper); 6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!numberSharpSCharacters) 6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We have numberSSCharacters sharp-s characters, but none of the other special characters. 6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newImpl = createUninitialized(m_length + numberSharpSCharacters, data8); 6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar* dest = data8; 6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 650926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (int32_t i = 0; i < length; ++i) { 651f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) LChar c = characters8()[i]; 6525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (c == smallLetterSharpS) { 6535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *dest++ = 'S'; 6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *dest++ = 'S'; 6555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *dest++ = static_cast<LChar>(Unicode::toUpper(c)); 6575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)upconvert: 6631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) RefPtr<StringImpl> upconverted = upconvertedString(); 6641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) const UChar* source16 = upconverted->characters16(); 6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar* data16; 6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(m_length, data16); 668591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 6695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do a faster loop for the case where all the characters are ASCII. 6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar ored = 0; 671926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (int i = 0; i < length; ++i) { 6725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar c = source16[i]; 6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ored |= c; 6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data16[i] = toASCIIUpper(c); 6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!(ored & ~0x7F)) 6775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do a slower implementation for cases that include non-ASCII characters. 6805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool error; 6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int32_t realLength = Unicode::toUpper(data16, length, source16, m_length, &error); 6825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!error && realLength == length) 6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl; 6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newImpl = createUninitialized(realLength, data16); 6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Unicode::toUpper(data16, realLength, source16, m_length, &error); 6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (error) 6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 6895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 6911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)PassRefPtr<StringImpl> StringImpl::lower(const AtomicString& localeIdentifier) 6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 6931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Use the more-optimized code path most of the time. 6941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Note the assumption here that the only locale-specific lowercasing is 6951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // in the "tr" and "az" locales. 6961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // FIXME: Could possibly optimize further by looking for the specific sequences 6971e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // that have locale-specific lowercasing. There are only three of them. 6981e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!(localeIdentifier == "tr" || localeIdentifier == "az")) 6991e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return lower(); 7001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 7011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max())) 7021e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) CRASH(); 7031e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) int length = m_length; 7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Below, we pass in the hardcoded locale "tr". Passing that is more efficient than 7061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // allocating memory just to turn localeIdentifier into a C string, and there is no 7071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // difference between the uppercasing for "tr" and "az" locales. 7081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) RefPtr<StringImpl> upconverted = upconvertedString(); 7091e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) const UChar* source16 = upconverted->characters16(); 7101e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) UChar* data16; 7111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) RefPtr<StringImpl> newString = createUninitialized(length, data16); 7121e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) do { 7131e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 7141e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) int realLength = u_strToLower(data16, length, source16, length, "tr", &status); 7151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (U_SUCCESS(status)) { 7161e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) newString->truncateAssumingIsolated(realLength); 7171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return newString.release(); 7181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } 7191e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (status != U_BUFFER_OVERFLOW_ERROR) 7201e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return this; 7211e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Expand the buffer. 7221e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) newString = createUninitialized(realLength, data16); 7231e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } while (true); 7241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)} 7251e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 7261e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)PassRefPtr<StringImpl> StringImpl::upper(const AtomicString& localeIdentifier) 7271e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){ 7281e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Use the more-optimized code path most of the time. 7291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Note the assumption here that the only locale-specific uppercasing is of the 7301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // letter "i" in the "tr" and "az" locales. 7311e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (!(localeIdentifier == "tr" || localeIdentifier == "az") || find('i') == kNotFound) 7321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return upper(); 7331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 7341e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max())) 7351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) CRASH(); 7361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) int length = m_length; 7371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 7381e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Below, we pass in the hardcoded locale "tr". Passing that is more efficient than 7391e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // allocating memory just to turn localeIdentifier into a C string, and there is no 7401e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // difference between the uppercasing for "tr" and "az" locales. 7411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) RefPtr<StringImpl> upconverted = upconvertedString(); 7421e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) const UChar* source16 = upconverted->characters16(); 7431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) UChar* data16; 7441e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) RefPtr<StringImpl> newString = createUninitialized(length, data16); 7451e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) do { 7461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 7471e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) int realLength = u_strToUpper(data16, length, source16, length, "tr", &status); 7481e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (U_SUCCESS(status)) { 7491e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) newString->truncateAssumingIsolated(realLength); 7501e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return newString.release(); 7511e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } 7521e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (status != U_BUFFER_OVERFLOW_ERROR) 7531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return this; 7541e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) // Expand the buffer. 7551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) newString = createUninitialized(realLength, data16); 7561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) } while (true); 7571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)} 7581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 7591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)PassRefPtr<StringImpl> StringImpl::fill(UChar character) 7601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){ 7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!(character & ~0x7F)) { 7625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar* data; 7635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); 7645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < m_length; ++i) 7655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data[i] = character; 7665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 7675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar* data; 7695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); 7705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < m_length; ++i) 7715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data[i] = character; 7725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 7735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 7745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::foldCase() 7765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 77753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(m_length <= static_cast<unsigned>(numeric_limits<int32_t>::max())); 7785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int32_t length = m_length; 7795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 7815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do a faster loop for the case where all the characters are ASCII. 7825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar* data; 7835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr <StringImpl>newImpl = createUninitialized(m_length, data); 7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar ored = 0; 7855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 786926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (int32_t i = 0; i < length; ++i) { 787f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) LChar c = characters8()[i]; 7885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data[i] = toASCIILower(c); 7895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ored |= c; 7905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 7915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!(ored & ~0x7F)) 7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 7945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do a slower implementation for cases that include non-ASCII Latin-1 characters. 796926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (int32_t i = 0; i < length; ++i) 797f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) data[i] = static_cast<LChar>(Unicode::toLower(characters8()[i])); 7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 7995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 8005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do a faster loop for the case where all the characters are ASCII. 8035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar* data; 8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); 8055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar ored = 0; 806926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (int32_t i = 0; i < length; ++i) { 807f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) UChar c = characters16()[i]; 8085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ored |= c; 8095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data[i] = toASCIILower(c); 8105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!(ored & ~0x7F)) 8125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 8135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do a slower implementation for cases that include non-ASCII characters. 8155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool error; 816f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) int32_t realLength = Unicode::foldCase(data, length, characters16(), m_length, &error); 8175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!error && realLength == length) 8185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 8195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newImpl = createUninitialized(realLength, data); 820f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) Unicode::foldCase(data, realLength, characters16(), m_length, &error); 8215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (error) 8225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 8235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 8245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class UCharPredicate> 8275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline PassRefPtr<StringImpl> StringImpl::stripMatchedCharacters(UCharPredicate predicate) 8285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_length) 8305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return empty(); 8315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned start = 0; 8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned end = m_length - 1; 834591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 8355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // skip white space from start 836f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) while (start <= end && predicate(is8Bit() ? characters8()[start] : characters16()[start])) 837926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ++start; 838591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 8395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // only white space 840591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (start > end) 8415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return empty(); 8425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // skip white space from end 844f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) while (end && predicate(is8Bit() ? characters8()[end] : characters16()[end])) 845926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) --end; 8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!start && end == m_length - 1) 8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 850f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return create(characters8() + start, end + 1 - start); 851f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return create(characters16() + start, end + 1 - start); 8525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class UCharPredicate { 8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 8565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) inline UCharPredicate(CharacterMatchFunctionPtr function): m_function(function) { } 8575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) inline bool operator()(UChar ch) const 8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_function(ch); 8615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 8645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const CharacterMatchFunctionPtr m_function; 8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class SpaceOrNewlinePredicate { 8685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 8695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) inline bool operator()(UChar ch) const 8705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 8715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return isSpaceOrNewline(ch); 8725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 8735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 8745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::stripWhiteSpace() 8765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return stripMatchedCharacters(SpaceOrNewlinePredicate()); 8785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::stripWhiteSpace(IsWhiteSpaceFunctionPtr isWhiteSpace) 8815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return stripMatchedCharacters(UCharPredicate(isWhiteSpace)); 8835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 8845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 8855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename CharType> 8865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ALWAYS_INLINE PassRefPtr<StringImpl> StringImpl::removeCharacters(const CharType* characters, CharacterMatchFunctionPtr findMatch) 8875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 8885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const CharType* from = characters; 8895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const CharType* fromend = from + m_length; 890591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 8915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Assume the common case will not remove any characters 8925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (from != fromend && !findMatch(*from)) 893926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ++from; 8945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (from == fromend) 8955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 896591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 8975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringBuffer<CharType> data(m_length); 8985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CharType* to = data.characters(); 8995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned outc = from - characters; 900591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 9015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (outc) 9025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) memcpy(to, characters, outc * sizeof(CharType)); 9035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (true) { 9055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (from != fromend && findMatch(*from)) 906926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ++from; 9075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (from != fromend && !findMatch(*from)) 9085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) to[outc++] = *from++; 9095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (from == fromend) 9105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 9115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 9125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data.shrink(outc); 9145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 91583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch return data.release(); 9165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 9175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::removeCharacters(CharacterMatchFunctionPtr findMatch) 9195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 9205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 9215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return removeCharacters(characters8(), findMatch); 9225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return removeCharacters(characters16(), findMatch); 9235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 9245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename CharType, class UCharPredicate> 92619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)inline PassRefPtr<StringImpl> StringImpl::simplifyMatchedCharactersToSpace(UCharPredicate predicate, StripBehavior stripBehavior) 9275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 9285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringBuffer<CharType> data(m_length); 9295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const CharType* from = getCharacters<CharType>(); 9315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const CharType* fromend = from + m_length; 9325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int outc = 0; 9335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool changedToSpace = false; 934591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 9355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CharType* to = data.characters(); 936591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 93719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) if (stripBehavior == StripExtraWhiteSpace) { 93819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) while (true) { 93919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) while (from != fromend && predicate(*from)) { 94019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) if (*from != ' ') 94119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) changedToSpace = true; 94219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) ++from; 94319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) } 94419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) while (from != fromend && !predicate(*from)) 94519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) to[outc++] = *from++; 94619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) if (from != fromend) 94719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) to[outc++] = ' '; 94819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) else 94919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) break; 9505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 951591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 95219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) if (outc > 0 && to[outc - 1] == ' ') 95319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) --outc; 95419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) } else { 95519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) for (; from != fromend; ++from) { 95619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) if (predicate(*from)) { 95719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) if (*from != ' ') 95819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) changedToSpace = true; 95919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) to[outc++] = ' '; 96019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) } else { 96119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) to[outc++] = *from; 96219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) } 96319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) } 96419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) } 965591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 9665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (static_cast<unsigned>(outc) == m_length && !changedToSpace) 9675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 968591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 9695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data.shrink(outc); 970591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 97183750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch return data.release(); 9725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 9735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 97419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)PassRefPtr<StringImpl> StringImpl::simplifyWhiteSpace(StripBehavior stripBehavior) 9755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 9765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 97719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) return StringImpl::simplifyMatchedCharactersToSpace<LChar>(SpaceOrNewlinePredicate(), stripBehavior); 97819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) return StringImpl::simplifyMatchedCharactersToSpace<UChar>(SpaceOrNewlinePredicate(), stripBehavior); 9795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 9805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 98119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)PassRefPtr<StringImpl> StringImpl::simplifyWhiteSpace(IsWhiteSpaceFunctionPtr isWhiteSpace, StripBehavior stripBehavior) 9825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 9835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 98419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) return StringImpl::simplifyMatchedCharactersToSpace<LChar>(UCharPredicate(isWhiteSpace), stripBehavior); 98519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) return StringImpl::simplifyMatchedCharactersToSpace<UChar>(UCharPredicate(isWhiteSpace), stripBehavior); 9865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 9875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int StringImpl::toIntStrict(bool* ok, int base) 9895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 9905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToIntStrict(characters8(), m_length, ok, base); 9925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToIntStrict(characters16(), m_length, ok, base); 9935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 9945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 9955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned StringImpl::toUIntStrict(bool* ok, int base) 9965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 9975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 9985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToUIntStrict(characters8(), m_length, ok, base); 9995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToUIntStrict(characters16(), m_length, ok, base); 10005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int64_t StringImpl::toInt64Strict(bool* ok, int base) 10035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 10055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToInt64Strict(characters8(), m_length, ok, base); 10065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToInt64Strict(characters16(), m_length, ok, base); 10075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)uint64_t StringImpl::toUInt64Strict(bool* ok, int base) 10105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToUInt64Strict(characters8(), m_length, ok, base); 10135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToUInt64Strict(characters16(), m_length, ok, base); 10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)intptr_t StringImpl::toIntPtrStrict(bool* ok, int base) 10175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 10195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToIntPtrStrict(characters8(), m_length, ok, base); 10205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToIntPtrStrict(characters16(), m_length, ok, base); 10215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int StringImpl::toInt(bool* ok) 10245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 10265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToInt(characters8(), m_length, ok); 10275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToInt(characters16(), m_length, ok); 10285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)unsigned StringImpl::toUInt(bool* ok) 10315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 10335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToUInt(characters8(), m_length, ok); 10345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToUInt(characters16(), m_length, ok); 10355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int64_t StringImpl::toInt64(bool* ok) 10385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 10405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToInt64(characters8(), m_length, ok); 10415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToInt64(characters16(), m_length, ok); 10425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)uint64_t StringImpl::toUInt64(bool* ok) 10455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 10475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToUInt64(characters8(), m_length, ok); 10485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToUInt64(characters16(), m_length, ok); 10495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)intptr_t StringImpl::toIntPtr(bool* ok) 10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 10545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToIntPtr(characters8(), m_length, ok); 10555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToIntPtr(characters16(), m_length, ok); 10565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double StringImpl::toDouble(bool* ok) 10595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToDouble(characters8(), m_length, ok); 10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToDouble(characters16(), m_length, ok); 10635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float StringImpl::toFloat(bool* ok) 10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 10685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToFloat(characters8(), m_length, ok); 10695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return charactersToFloat(characters16(), m_length, ok); 10705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool equalIgnoringCase(const LChar* a, const LChar* b, unsigned length) 10735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (length--) { 10755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar bc = *b++; 10765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (foldCase(*a++) != foldCase(bc)) 10775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 10785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 10805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool equalIgnoringCase(const UChar* a, const LChar* b, unsigned length) 10835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (length--) { 10855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar bc = *b++; 10865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (foldCase(*a++) != foldCase(bc)) 10875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 10885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 10895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 10905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)size_t StringImpl::find(CharacterMatchFunctionPtr matchFunction, unsigned start) 10935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 10955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return WTF::find(characters8(), m_length, matchFunction, start); 10965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return WTF::find(characters16(), m_length, matchFunction, start); 10975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 10985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 10995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)size_t StringImpl::find(const LChar* matchString, unsigned index) 11005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check for null or empty string to match against 11025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!matchString) 110306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 11045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t matchStringLength = strlen(reinterpret_cast<const char*>(matchString)); 110553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(matchStringLength <= numeric_limits<unsigned>::max()); 11065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned matchLength = matchStringLength; 11075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!matchLength) 11085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return min(index, length()); 11095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Optimization 1: fast case for strings of length 1. 11115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchLength == 1) 11125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return WTF::find(characters16(), length(), *matchString, index); 11135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check index & matchLength are in range. 11155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (index > length()) 111606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 11175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned searchLength = length() - index; 11185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchLength > searchLength) 111906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 11205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // delta is the number of additional times to test; delta == 0 means test only once. 11215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned delta = searchLength - matchLength; 11225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch const UChar* searchCharacters = characters16() + index; 11245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Optimization 2: keep a running hash of the strings, 11265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // only call equal if the hashes match. 11275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned searchHash = 0; 11285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned matchHash = 0; 11295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < matchLength; ++i) { 11305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) searchHash += searchCharacters[i]; 11315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) matchHash += matchString[i]; 11325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned i = 0; 11355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // keep looping until we match 11365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (searchHash != matchHash || !equal(searchCharacters + i, matchString, matchLength)) { 11375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (i == delta) 113806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 11395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) searchHash += searchCharacters[i + matchLength]; 11405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) searchHash -= searchCharacters[i]; 11415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++i; 11425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 11435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return index + i; 11445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochtemplate<typename CharType> 11477757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochALWAYS_INLINE size_t findIgnoringCaseInternal(const CharType* searchCharacters, const LChar* matchString, unsigned index, unsigned searchLength, unsigned matchLength) 11487757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch{ 11497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch // delta is the number of additional times to test; delta == 0 means test only once. 11507757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch unsigned delta = searchLength - matchLength; 11517757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 11527757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch unsigned i = 0; 11537757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch while (!equalIgnoringCase(searchCharacters + i, matchString, matchLength)) { 11547757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (i == delta) 115506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 11567757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch ++i; 11577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch } 11587757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return index + i; 11597757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch} 11607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 11615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)size_t StringImpl::findIgnoringCase(const LChar* matchString, unsigned index) 11625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check for null or empty string to match against 11645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!matchString) 116506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 11665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t matchStringLength = strlen(reinterpret_cast<const char*>(matchString)); 116753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(matchStringLength <= numeric_limits<unsigned>::max()); 11685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned matchLength = matchStringLength; 11695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!matchLength) 11705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return min(index, length()); 11715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check index & matchLength are in range. 11735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (index > length()) 117406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 11755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned searchLength = length() - index; 11765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchLength > searchLength) 117706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 11785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (is8Bit()) 11807757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return findIgnoringCaseInternal(characters8() + index, matchString, index, searchLength, matchLength); 11817757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return findIgnoringCaseInternal(characters16() + index, matchString, index, searchLength, matchLength); 11825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 11835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename SearchCharacterType, typename MatchCharacterType> 11857757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochALWAYS_INLINE static size_t findInternal(const SearchCharacterType* searchCharacters, const MatchCharacterType* matchCharacters, unsigned index, unsigned searchLength, unsigned matchLength) 11865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Optimization: keep a running hash of the strings, 11885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // only call equal() if the hashes match. 11895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // delta is the number of additional times to test; delta == 0 means test only once. 11915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned delta = searchLength - matchLength; 11925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned searchHash = 0; 11945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned matchHash = 0; 11955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 11965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < matchLength; ++i) { 11975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) searchHash += searchCharacters[i]; 11985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) matchHash += matchCharacters[i]; 11995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned i = 0; 12025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // keep looping until we match 12035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (searchHash != matchHash || !equal(searchCharacters + i, matchCharacters, matchLength)) { 12045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (i == delta) 120506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 12065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) searchHash += searchCharacters[i + matchLength]; 12075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) searchHash -= searchCharacters[i]; 12085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++i; 12095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1210591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return index + i; 12115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)size_t StringImpl::find(StringImpl* matchString) 12145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check for null string to match against 12165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (UNLIKELY(!matchString)) 121706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 12185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned matchLength = matchString->length(); 12195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Optimization 1: fast case for strings of length 1. 12215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchLength == 1) { 12225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 12235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchString->is8Bit()) 12245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return WTF::find(characters8(), length(), matchString->characters8()[0]); 12255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return WTF::find(characters8(), length(), matchString->characters16()[0]); 12265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchString->is8Bit()) 12285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return WTF::find(characters16(), length(), matchString->characters8()[0]); 12295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return WTF::find(characters16(), length(), matchString->characters16()[0]); 12305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check matchLength is in range. 12335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchLength > length()) 123406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 12355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check for empty string to match against 12375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (UNLIKELY(!matchLength)) 12385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 12395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 12415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchString->is8Bit()) 12427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return findInternal(characters8(), matchString->characters8(), 0, length(), matchLength); 12437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return findInternal(characters8(), matchString->characters16(), 0, length(), matchLength); 12445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchString->is8Bit()) 12477757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return findInternal(characters16(), matchString->characters8(), 0, length(), matchLength); 12485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return findInternal(characters16(), matchString->characters16(), 0, length(), matchLength); 12505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)size_t StringImpl::find(StringImpl* matchString, unsigned index) 12535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check for null or empty string to match against 12555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (UNLIKELY(!matchString)) 125606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 12575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned matchLength = matchString->length(); 12595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Optimization 1: fast case for strings of length 1. 12615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchLength == 1) { 12625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 12635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return WTF::find(characters8(), length(), (*matchString)[0], index); 12645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return WTF::find(characters16(), length(), (*matchString)[0], index); 12655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (UNLIKELY(!matchLength)) 12685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return min(index, length()); 12695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check index & matchLength are in range. 12715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (index > length()) 127206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 12735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned searchLength = length() - index; 12745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchLength > searchLength) 127506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 12765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 12785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchString->is8Bit()) 12797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return findInternal(characters8() + index, matchString->characters8(), index, searchLength, matchLength); 12807757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return findInternal(characters8() + index, matchString->characters16(), index, searchLength, matchLength); 12815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchString->is8Bit()) 12847757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return findInternal(characters16() + index, matchString->characters8(), index, searchLength, matchLength); 12855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12867757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return findInternal(characters16() + index, matchString->characters16(), index, searchLength, matchLength); 12875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 12885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename SearchCharacterType, typename MatchCharacterType> 12905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ALWAYS_INLINE static size_t findIgnoringCaseInner(const SearchCharacterType* searchCharacters, const MatchCharacterType* matchCharacters, unsigned index, unsigned searchLength, unsigned matchLength) 12915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // delta is the number of additional times to test; delta == 0 means test only once. 12935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned delta = searchLength - matchLength; 12945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 12955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned i = 0; 12965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // keep looping until we match 12975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (!equalIgnoringCase(searchCharacters + i, matchCharacters, matchLength)) { 12985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (i == delta) 129906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 13005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++i; 13015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return index + i; 13035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)size_t StringImpl::findIgnoringCase(StringImpl* matchString, unsigned index) 13065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check for null or empty string to match against 13085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!matchString) 130906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 13105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned matchLength = matchString->length(); 13115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!matchLength) 13125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return min(index, length()); 13135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check index & matchLength are in range. 13155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (index > length()) 131606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 13175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned searchLength = length() - index; 13185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchLength > searchLength) 131906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 13205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 13225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchString->is8Bit()) 13235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return findIgnoringCaseInner(characters8() + index, matchString->characters8(), index, searchLength, matchLength); 13245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return findIgnoringCaseInner(characters8() + index, matchString->characters16(), index, searchLength, matchLength); 13255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchString->is8Bit()) 13285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return findIgnoringCaseInner(characters16() + index, matchString->characters8(), index, searchLength, matchLength); 13295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return findIgnoringCaseInner(characters16() + index, matchString->characters16(), index, searchLength, matchLength); 13315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1333926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)size_t StringImpl::findNextLineStart(unsigned index) 1334926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 1335926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (is8Bit()) 1336926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return WTF::findNextLineStart(characters8(), m_length, index); 1337926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return WTF::findNextLineStart(characters16(), m_length, index); 1338926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 1339926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1340591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochsize_t StringImpl::count(LChar c) const 1341591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 1342591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int count = 0; 1343591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (is8Bit()) { 1344591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 0; i < m_length; ++i) 1345591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch count += characters8()[i] == c; 1346591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } else { 1347591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (size_t i = 0; i < m_length; ++i) 1348591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch count += characters16()[i] == c; 1349591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 1350591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return count; 1351591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 1352591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 13531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)size_t StringImpl::reverseFind(UChar c, unsigned index) 13545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 13561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return WTF::reverseFind(characters8(), m_length, c, index); 13571e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return WTF::reverseFind(characters16(), m_length, c, index); 13585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename SearchCharacterType, typename MatchCharacterType> 13611e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)ALWAYS_INLINE static size_t reverseFindInner(const SearchCharacterType* searchCharacters, const MatchCharacterType* matchCharacters, unsigned index, unsigned length, unsigned matchLength) 13625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Optimization: keep a running hash of the strings, 13645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // only call equal if the hashes match. 13655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // delta is the number of additional times to test; delta == 0 means test only once. 13675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned delta = min(index, length - matchLength); 1368591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 13695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned searchHash = 0; 13705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned matchHash = 0; 13715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < matchLength; ++i) { 13725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) searchHash += searchCharacters[delta + i]; 13735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) matchHash += matchCharacters[i]; 13745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // keep looping until we match 13775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (searchHash != matchHash || !equal(searchCharacters + delta, matchCharacters, matchLength)) { 13785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!delta) 137906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 1380926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) --delta; 13815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) searchHash -= searchCharacters[delta + matchLength]; 13825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) searchHash += searchCharacters[delta]; 13835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 13841e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return delta; 13855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13871e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)size_t StringImpl::reverseFind(StringImpl* matchString, unsigned index) 13885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check for null or empty string to match against 13905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!matchString) 139106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 13925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned matchLength = matchString->length(); 13935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned ourLength = length(); 13945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!matchLength) 13955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return min(index, ourLength); 13965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 13975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Optimization 1: fast case for strings of length 1. 13985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchLength == 1) { 13995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 14001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return WTF::reverseFind(characters8(), ourLength, (*matchString)[0], index); 14011e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return WTF::reverseFind(characters16(), ourLength, (*matchString)[0], index); 14025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check index & matchLength are in range. 14051e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (matchLength > ourLength) 140606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 14075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 14095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchString->is8Bit()) 14101e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return reverseFindInner(characters8(), matchString->characters8(), index, ourLength, matchLength); 14111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return reverseFindInner(characters8(), matchString->characters16(), index, ourLength, matchLength); 14125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1413591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 14145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchString->is8Bit()) 14151e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return reverseFindInner(characters16(), matchString->characters8(), index, ourLength, matchLength); 14165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14171e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return reverseFindInner(characters16(), matchString->characters16(), index, ourLength, matchLength); 14185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <typename SearchCharacterType, typename MatchCharacterType> 14215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ALWAYS_INLINE static size_t reverseFindIgnoringCaseInner(const SearchCharacterType* searchCharacters, const MatchCharacterType* matchCharacters, unsigned index, unsigned length, unsigned matchLength) 14225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // delta is the number of additional times to test; delta == 0 means test only once. 14245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned delta = min(index, length - matchLength); 14255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // keep looping until we match 14275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (!equalIgnoringCase(searchCharacters + delta, matchCharacters, matchLength)) { 14285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!delta) 142906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 1430926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) --delta; 14315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return delta; 14335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)size_t StringImpl::reverseFindIgnoringCase(StringImpl* matchString, unsigned index) 14365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check for null or empty string to match against 14385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!matchString) 143906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 14405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned matchLength = matchString->length(); 14415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned ourLength = length(); 14425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!matchLength) 14435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return min(index, ourLength); 14445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check index & matchLength are in range. 14465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchLength > ourLength) 144706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return kNotFound; 14485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 14505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchString->is8Bit()) 14515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return reverseFindIgnoringCaseInner(characters8(), matchString->characters8(), index, ourLength, matchLength); 14525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return reverseFindIgnoringCaseInner(characters8(), matchString->characters16(), index, ourLength, matchLength); 14535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchString->is8Bit()) 14565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return reverseFindIgnoringCaseInner(characters16(), matchString->characters8(), index, ourLength, matchLength); 14575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return reverseFindIgnoringCaseInner(characters16(), matchString->characters16(), index, ourLength, matchLength); 14595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ALWAYS_INLINE static bool equalInner(const StringImpl* stringImpl, unsigned startOffset, const char* matchString, unsigned matchLength, bool caseSensitive) 14625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(stringImpl); 14645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(matchLength <= stringImpl->length()); 14655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(startOffset + matchLength <= stringImpl->length()); 14665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (caseSensitive) { 14685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stringImpl->is8Bit()) 14695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return equal(stringImpl->characters8() + startOffset, reinterpret_cast<const LChar*>(matchString), matchLength); 14705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return equal(stringImpl->characters16() + startOffset, reinterpret_cast<const LChar*>(matchString), matchLength); 14715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stringImpl->is8Bit()) 14735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return equalIgnoringCase(stringImpl->characters8() + startOffset, reinterpret_cast<const LChar*>(matchString), matchLength); 14745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return equalIgnoringCase(stringImpl->characters16() + startOffset, reinterpret_cast<const LChar*>(matchString), matchLength); 14755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool StringImpl::startsWith(UChar character) const 14785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_length && (*this)[0] == character; 14805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool StringImpl::startsWith(const char* matchString, unsigned matchLength, bool caseSensitive) const 14835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(matchLength); 14855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchLength > length()) 14865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 14875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return equalInner(this, 0, matchString, matchLength, caseSensitive); 14885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 14905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool StringImpl::endsWith(StringImpl* matchString, bool caseSensitive) 14915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 14925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(matchString); 14935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_length >= matchString->m_length) { 14945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned start = m_length - matchString->m_length; 14955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (caseSensitive ? find(matchString, start) : findIgnoringCase(matchString, start)) == start; 14965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 14975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 14985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 14995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool StringImpl::endsWith(UChar character) const 15015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_length && (*this)[m_length - 1] == character; 15035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool StringImpl::endsWith(const char* matchString, unsigned matchLength, bool caseSensitive) const 15065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(matchLength); 15085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (matchLength > length()) 15095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 15105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned startOffset = length() - matchLength; 15115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return equalInner(this, startOffset, matchString, matchLength, caseSensitive); 15125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::replace(UChar oldC, UChar newC) 15155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (oldC == newC) 15175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 15185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned i; 15195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (i = 0; i != m_length; ++i) { 1520f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) UChar c = is8Bit() ? characters8()[i] : characters16()[i]; 15215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (c == oldC) 15225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 15235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (i == m_length) 15255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 15265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 15285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (oldC > 0xff) 15295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Looking for a 16 bit char in an 8 bit string, we're done. 15305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 15315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (newC <= 0xff) { 15335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar* data; 15345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar oldChar = static_cast<LChar>(oldC); 15355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar newChar = static_cast<LChar>(newC); 15365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); 15385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (i = 0; i != m_length; ++i) { 1540f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) LChar ch = characters8()[i]; 15415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ch == oldChar) 15425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ch = newChar; 15435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data[i] = ch; 15445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 15465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // There is the possibility we need to up convert from 8 to 16 bit, 15495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // create a 16 bit string for the result. 15505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar* data; 15515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); 15525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (i = 0; i != m_length; ++i) { 1554f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) UChar ch = characters8()[i]; 15555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ch == oldC) 15565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ch = newC; 15575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data[i] = ch; 15585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 15615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar* data; 15645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); 15655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (i = 0; i != m_length; ++i) { 1567f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) UChar ch = characters16()[i]; 15685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ch == oldC) 15695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ch = newC; 15705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data[i] = ch; 15715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 15735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 15745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::replace(unsigned position, unsigned lengthToReplace, StringImpl* str) 15765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 15775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) position = min(position, length()); 15785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lengthToReplace = min(lengthToReplace, length() - position); 15795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned lengthToInsert = str ? str->length() : 0; 15805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!lengthToReplace && !lengthToInsert) 15815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 15825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 158353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT((length() - lengthToReplace) < (numeric_limits<unsigned>::max() - lengthToInsert)); 15845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit() && (!str || str->is8Bit())) { 15865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar* data; 15875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = 15885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) createUninitialized(length() - lengthToReplace + lengthToInsert, data); 1589f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data, characters8(), position * sizeof(LChar)); 15905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (str) 1591f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + position, str->characters8(), lengthToInsert * sizeof(LChar)); 1592f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + position + lengthToInsert, characters8() + position + lengthToReplace, 15935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (length() - position - lengthToReplace) * sizeof(LChar)); 15945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 15955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 15965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar* data; 15975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = 15985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) createUninitialized(length() - lengthToReplace + lengthToInsert, data); 15995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) 1600926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = 0; i < position; ++i) 1601f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) data[i] = characters8()[i]; 16025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1603f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data, characters16(), position * sizeof(UChar)); 16045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (str) { 16055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (str->is8Bit()) 1606926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = 0; i < lengthToInsert; ++i) 1607f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) data[i + position] = str->characters8()[i]; 16085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1609f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + position, str->characters16(), lengthToInsert * sizeof(UChar)); 16105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 1612926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = 0; i < length() - position - lengthToReplace; ++i) 1613f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) data[i + position + lengthToInsert] = characters8()[i + position + lengthToReplace]; 16145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 16157757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch memcpy(data + position + lengthToInsert, characters16() + position + lengthToReplace, 16165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) (length() - position - lengthToReplace) * sizeof(UChar)); 16175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 16195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacement) 16225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!replacement) 16245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 16255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (replacement->is8Bit()) 1627f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return replace(pattern, replacement->characters8(), replacement->length()); 16285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1629f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return replace(pattern, replacement->characters16(), replacement->length()); 16305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 16315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, const LChar* replacement, unsigned repStrLength) 16335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 16345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(replacement); 16355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t srcSegmentStart = 0; 16375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned matchCount = 0; 16385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Count the matches. 164006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) while ((srcSegmentStart = find(pattern, srcSegmentStart)) != kNotFound) { 16415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++matchCount; 16425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++srcSegmentStart; 16435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we have 0 matches then we don't have to do any more work. 16465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!matchCount) 16475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 16485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 164953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(!repStrLength || matchCount <= numeric_limits<unsigned>::max() / repStrLength); 16505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned replaceSize = matchCount * repStrLength; 16525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned newSize = m_length - matchCount; 165353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(newSize < (numeric_limits<unsigned>::max() - replaceSize)); 16545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newSize += replaceSize; 16565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Construct the new data. 16585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t srcSegmentEnd; 16595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned srcSegmentLength; 16605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentStart = 0; 16615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned dstOffset = 0; 16625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 16645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar* data; 16655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(newSize, data); 16665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 166706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != kNotFound) { 16685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentLength = srcSegmentEnd - srcSegmentStart; 1669f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + dstOffset, characters8() + srcSegmentStart, srcSegmentLength * sizeof(LChar)); 16705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dstOffset += srcSegmentLength; 16715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) memcpy(data + dstOffset, replacement, repStrLength * sizeof(LChar)); 16725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dstOffset += repStrLength; 16735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentStart = srcSegmentEnd + 1; 16745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentLength = m_length - srcSegmentStart; 1677f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + dstOffset, characters8() + srcSegmentStart, srcSegmentLength * sizeof(LChar)); 16785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(dstOffset + srcSegmentLength == newImpl->length()); 16805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 16825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar* data; 16855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(newSize, data); 16865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 168706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != kNotFound) { 16885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentLength = srcSegmentEnd - srcSegmentStart; 1689f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + dstOffset, characters16() + srcSegmentStart, srcSegmentLength * sizeof(UChar)); 16905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dstOffset += srcSegmentLength; 16925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < repStrLength; ++i) 16935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) data[i + dstOffset] = replacement[i]; 16945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dstOffset += repStrLength; 16965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentStart = srcSegmentEnd + 1; 16975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 16985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentLength = m_length - srcSegmentStart; 1700f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + dstOffset, characters16() + srcSegmentStart, srcSegmentLength * sizeof(UChar)); 17015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(dstOffset + srcSegmentLength == newImpl->length()); 17035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 17055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 17065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, const UChar* replacement, unsigned repStrLength) 17085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 17095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(replacement); 17105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t srcSegmentStart = 0; 17125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned matchCount = 0; 17135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Count the matches. 171506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) while ((srcSegmentStart = find(pattern, srcSegmentStart)) != kNotFound) { 17165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++matchCount; 17175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++srcSegmentStart; 17185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we have 0 matches then we don't have to do any more work. 17215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!matchCount) 17225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 17235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 172453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(!repStrLength || matchCount <= numeric_limits<unsigned>::max() / repStrLength); 17255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned replaceSize = matchCount * repStrLength; 17275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned newSize = m_length - matchCount; 172853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(newSize < (numeric_limits<unsigned>::max() - replaceSize)); 17295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newSize += replaceSize; 17315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Construct the new data. 17335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t srcSegmentEnd; 17345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned srcSegmentLength; 17355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentStart = 0; 17365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned dstOffset = 0; 17375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (is8Bit()) { 17395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar* data; 17405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(newSize, data); 17415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 174206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != kNotFound) { 17435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentLength = srcSegmentEnd - srcSegmentStart; 17445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < srcSegmentLength; ++i) 1745f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) data[i + dstOffset] = characters8()[i + srcSegmentStart]; 17465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dstOffset += srcSegmentLength; 17485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) memcpy(data + dstOffset, replacement, repStrLength * sizeof(UChar)); 17495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dstOffset += repStrLength; 17515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentStart = srcSegmentEnd + 1; 17525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentLength = m_length - srcSegmentStart; 17555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i < srcSegmentLength; ++i) 1756f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) data[i + dstOffset] = characters8()[i + srcSegmentStart]; 17575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(dstOffset + srcSegmentLength == newImpl->length()); 17595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 17615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar* data; 17645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(newSize, data); 17655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 176606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != kNotFound) { 17675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentLength = srcSegmentEnd - srcSegmentStart; 1768f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + dstOffset, characters16() + srcSegmentStart, srcSegmentLength * sizeof(UChar)); 17695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dstOffset += srcSegmentLength; 17715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) memcpy(data + dstOffset, replacement, repStrLength * sizeof(UChar)); 17725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dstOffset += repStrLength; 17745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentStart = srcSegmentEnd + 1; 17755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 17765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentLength = m_length - srcSegmentStart; 1778f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + dstOffset, characters16() + srcSegmentStart, srcSegmentLength * sizeof(UChar)); 17795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(dstOffset + srcSegmentLength == newImpl->length()); 17815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 17835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 17845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* replacement) 17865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 17875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!pattern || !replacement) 17885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 17895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 17905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned patternLength = pattern->length(); 17915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!patternLength) 17925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 1793591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 17945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned repStrLength = replacement->length(); 17955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t srcSegmentStart = 0; 17965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned matchCount = 0; 1797591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 17985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Count the matches. 179906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) while ((srcSegmentStart = find(pattern, srcSegmentStart)) != kNotFound) { 18005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++matchCount; 18015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentStart += patternLength; 18025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1803591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 18045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we have 0 matches, we don't have to do any more work 18055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!matchCount) 18065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 1807591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 18085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned newSize = m_length - matchCount * patternLength; 180953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(!repStrLength || matchCount <= numeric_limits<unsigned>::max() / repStrLength); 18105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 181153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RELEASE_ASSERT(newSize <= (numeric_limits<unsigned>::max() - matchCount * repStrLength)); 18125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) newSize += matchCount * repStrLength; 18145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1815591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 18165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Construct the new data 18175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t srcSegmentEnd; 18185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned srcSegmentLength; 18195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentStart = 0; 18205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned dstOffset = 0; 18215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool srcIs8Bit = is8Bit(); 18225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool replacementIs8Bit = replacement->is8Bit(); 1823591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 18245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // There are 4 cases: 18255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 1. This and replacement are both 8 bit. 18265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 2. This and replacement are both 16 bit. 18275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 3. This is 8 bit and replacement is 16 bit. 18285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 4. This is 16 bit and replacement is 8 bit. 18295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (srcIs8Bit && replacementIs8Bit) { 18305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Case 1 18315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar* data; 18325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(newSize, data); 183306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != kNotFound) { 18345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentLength = srcSegmentEnd - srcSegmentStart; 1835f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + dstOffset, characters8() + srcSegmentStart, srcSegmentLength * sizeof(LChar)); 18365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dstOffset += srcSegmentLength; 1837f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + dstOffset, replacement->characters8(), repStrLength * sizeof(LChar)); 18385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dstOffset += repStrLength; 18395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentStart = srcSegmentEnd + patternLength; 18405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentLength = m_length - srcSegmentStart; 1843f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + dstOffset, characters8() + srcSegmentStart, srcSegmentLength * sizeof(LChar)); 18445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(dstOffset + srcSegmentLength == newImpl->length()); 18465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 18485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar* data; 18515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<StringImpl> newImpl = createUninitialized(newSize, data); 185206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != kNotFound) { 18535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentLength = srcSegmentEnd - srcSegmentStart; 18545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (srcIs8Bit) { 18555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Case 3. 1856926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = 0; i < srcSegmentLength; ++i) 1857f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) data[i + dstOffset] = characters8()[i + srcSegmentStart]; 18585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 18595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Case 2 & 4. 1860f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + dstOffset, characters16() + srcSegmentStart, srcSegmentLength * sizeof(UChar)); 18615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dstOffset += srcSegmentLength; 18635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (replacementIs8Bit) { 18645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Cases 2 & 3. 1865926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = 0; i < repStrLength; ++i) 1866f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) data[i + dstOffset] = replacement->characters8()[i]; 18675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 18685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Case 4 1869f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + dstOffset, replacement->characters16(), repStrLength * sizeof(UChar)); 18705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) dstOffset += repStrLength; 18725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentStart = srcSegmentEnd + patternLength; 18735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) srcSegmentLength = m_length - srcSegmentStart; 18765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (srcIs8Bit) { 18775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Case 3. 1878926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (unsigned i = 0; i < srcSegmentLength; ++i) 1879f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) data[i + dstOffset] = characters8()[i + srcSegmentStart]; 18805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 18815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Cases 2 & 4. 1882f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) memcpy(data + dstOffset, characters16() + srcSegmentStart, srcSegmentLength * sizeof(UChar)); 18835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 18845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(dstOffset + srcSegmentLength == newImpl->length()); 18865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return newImpl.release(); 18885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 18895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18901e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)PassRefPtr<StringImpl> StringImpl::upconvertedString() 18911e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles){ 18921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) if (is8Bit()) 18931e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return String::make16BitFrom8BitSource(characters8(), m_length).releaseImpl(); 18941e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) return this; 18951e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)} 18961e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) 1897926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static inline bool stringImplContentEqual(const StringImpl* a, const StringImpl* b) 1898926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 1899926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned aLength = a->length(); 1900926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned bLength = b->length(); 1901926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (aLength != bLength) 1902926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 1903926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1904926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (a->is8Bit()) { 1905926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (b->is8Bit()) 1906926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return equal(a->characters8(), b->characters8(), aLength); 1907926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1908926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return equal(a->characters8(), b->characters16(), aLength); 1909926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 1910926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1911926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (b->is8Bit()) 1912926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return equal(a->characters16(), b->characters8(), aLength); 1913926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1914926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return equal(a->characters16(), b->characters16(), aLength); 1915926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 1916926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 19175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool equal(const StringImpl* a, const StringImpl* b) 19185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1919926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (a == b) 1920926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 1921926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!a || !b) 1922926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 1923926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1924926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return stringImplContentEqual(a, b); 19255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 19265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1927e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochtemplate <typename CharType> 1928e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochinline bool equalInternal(const StringImpl* a, const CharType* b, unsigned length) 19295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 19305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!a) 19315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !b; 19325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!b) 19335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 19345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1935e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (a->length() != length) 1936e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return false; 19375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (a->is8Bit()) 19385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return equal(a->characters8(), b, length); 19395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return equal(a->characters16(), b, length); 19405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 19415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1942e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochbool equal(const StringImpl* a, const LChar* b, unsigned length) 1943e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{ 1944e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return equalInternal(a, b, length); 1945e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch} 1946e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 1947e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochbool equal(const StringImpl* a, const UChar* b, unsigned length) 1948e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{ 1949e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return equalInternal(a, b, length); 1950e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch} 1951e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 19525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool equal(const StringImpl* a, const LChar* b) 19535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 19545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!a) 19555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !b; 19565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!b) 19575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !a; 19585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned length = a->length(); 19605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (a->is8Bit()) { 19625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LChar* aPtr = a->characters8(); 19635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i != length; ++i) { 19645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar bc = b[i]; 19655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar ac = aPtr[i]; 19665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!bc) 19675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 19685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ac != bc) 19695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 19705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 19715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !b[length]; 19735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 19745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const UChar* aPtr = a->characters16(); 19765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i != length; ++i) { 19775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar bc = b[i]; 19785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!bc) 19795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 19805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (aPtr[i] != bc) 19815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 19825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 19835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 19845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !b[length]; 19855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 19865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1987926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool equalNonNull(const StringImpl* a, const StringImpl* b) 1988926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 1989926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(a && b); 1990926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (a == b) 1991926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 1992926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1993926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return stringImplContentEqual(a, b); 1994926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 1995926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 1996926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool equalIgnoringCase(const StringImpl* a, const StringImpl* b) 19975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1998926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (a == b) 1999926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 2000926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!a || !b) 2001926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 2002926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 20035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return CaseFoldingHash::equal(a, b); 20045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 20055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2006926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool equalIgnoringCase(const StringImpl* a, const LChar* b) 20075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 20085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!a) 20095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !b; 20105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!b) 20115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !a; 20125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned length = a->length(); 20145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do a faster loop for the case where all the characters are ASCII. 20165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar ored = 0; 20175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool equal = true; 20185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (a->is8Bit()) { 20195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const LChar* as = a->characters8(); 20205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i != length; ++i) { 20215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar bc = b[i]; 20225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!bc) 20235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 20245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar ac = as[i]; 20255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ored |= ac; 20265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) equal = equal && (toASCIILower(ac) == toASCIILower(bc)); 20275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2028591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 20295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do a slower implementation for cases that include non-ASCII characters. 20305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ored & ~0x7F) { 20315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) equal = true; 20325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i != length; ++i) 20335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) equal = equal && (foldCase(as[i]) == foldCase(b[i])); 20345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2035591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 2036591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return equal && !b[length]; 20375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 20385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const UChar* as = a->characters16(); 20405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i != length; ++i) { 20415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LChar bc = b[i]; 20425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!bc) 20435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 20445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) UChar ac = as[i]; 20455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ored |= ac; 20465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) equal = equal && (toASCIILower(ac) == toASCIILower(bc)); 20475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 20485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do a slower implementation for cases that include non-ASCII characters. 20505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ored & ~0x7F) { 20515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) equal = true; 20525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned i = 0; i != length; ++i) { 20535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) equal = equal && (foldCase(as[i]) == foldCase(b[i])); 20545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 20555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 20565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return equal && !b[length]; 20585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 20595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2060926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool equalIgnoringCaseNonNull(const StringImpl* a, const StringImpl* b) 20615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2062926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(a && b); 2063926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (a == b) 20645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2065926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2066926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) unsigned length = a->length(); 2067926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (length != b->length()) 2068926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 2069926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2070926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (a->is8Bit()) { 2071926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (b->is8Bit()) 2072926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return equalIgnoringCase(a->characters8(), b->characters8(), length); 2073926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2074926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return equalIgnoringCase(b->characters16(), a->characters8(), length); 2075926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 2076926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2077926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (b->is8Bit()) 2078926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return equalIgnoringCase(a->characters16(), b->characters8(), length); 2079926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2080926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return equalIgnoringCase(a->characters16(), b->characters16(), length); 2081926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 2082926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2083926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool equalIgnoringNullity(StringImpl* a, StringImpl* b) 2084926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 20855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!a && b && !b->length()) 20865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 20875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!b && a && !a->length()) 20885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2089926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return equal(a, b); 20905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 20915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 20925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)size_t StringImpl::sizeInBytes() const 20935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 20945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t size = length(); 20957757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (!is8Bit()) 20965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size *= 2; 20975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return size + sizeof(*this); 20985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 20995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 21005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WTF 2101