18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 1999 Antti Koivisto (koivisto@kde.org) 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 2001 Dirk Mueller ( mueller@kde.org ) 58f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details. 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB. If not, write to 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA. 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "StringImpl.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "AtomicString.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "StringBuffer.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "StringHash.h" 31dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/StdLibExtras.h> 32dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include <wtf/WTFThreadData.h> 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenusing namespace std; 355ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 36dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochnamespace WTF { 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 38dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdochusing namespace Unicode; 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic const unsigned minLengthToShare = 20; 415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 42e78cbe89e6f337f2f1fe40315be88f742b547151Steve BlockCOMPILE_ASSERT(sizeof(StringImpl) == 2 * sizeof(int) + 3 * sizeof(void*), StringImpl_should_stay_small); 43e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectStringImpl::~StringImpl() 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 46dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(!isStatic()); 47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 4821939df44de1705786c545cd1bf519d47250322dBen Murdoch if (isAtomic()) 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project AtomicString::remove(this); 50dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if USE(JSC) 5168513a70bcd92384395513322f1b801e7bf9c729Steve Block if (isIdentifier()) { 5268513a70bcd92384395513322f1b801e7bf9c729Steve Block if (!wtfThreadData().currentIdentifierTable()->remove(this)) 5368513a70bcd92384395513322f1b801e7bf9c729Steve Block CRASH(); 5468513a70bcd92384395513322f1b801e7bf9c729Steve Block } 55dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif 56692e5dbf12901edacf14812a6fae25462920af42Steve Block 57692e5dbf12901edacf14812a6fae25462920af42Steve Block BufferOwnership ownership = bufferOwnership(); 58692e5dbf12901edacf14812a6fae25462920af42Steve Block if (ownership != BufferInternal) { 59692e5dbf12901edacf14812a6fae25462920af42Steve Block if (ownership == BufferOwned) { 60692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT(!m_sharedBuffer); 61692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT(m_data); 62692e5dbf12901edacf14812a6fae25462920af42Steve Block fastFree(const_cast<UChar*>(m_data)); 63dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } else if (ownership == BufferSubstring) { 64dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(m_substringBuffer); 65dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_substringBuffer->deref(); 66692e5dbf12901edacf14812a6fae25462920af42Steve Block } else { 67692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT(ownership == BufferShared); 68692e5dbf12901edacf14812a6fae25462920af42Steve Block ASSERT(m_sharedBuffer); 69692e5dbf12901edacf14812a6fae25462920af42Steve Block m_sharedBuffer->deref(); 70692e5dbf12901edacf14812a6fae25462920af42Steve Block } 715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 74dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockPassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*& data) 75dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 76dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!length) { 77dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block data = 0; 78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return empty(); 79dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 80dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 81dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Allocate a single buffer large enough to contain the StringImpl 82dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // struct as well as the data which it contains. This removes one 83dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // heap allocation from this call. 84a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar))) 85dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block CRASH(); 86dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block size_t size = sizeof(StringImpl) + length * sizeof(UChar); 87dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block StringImpl* string = static_cast<StringImpl*>(fastMalloc(size)); 88dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 89dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block data = reinterpret_cast<UChar*>(string + 1); 90dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return adoptRef(new (string) StringImpl(length)); 91dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 92dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 93dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockPassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned length) 94dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 95dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!characters || !length) 96dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return empty(); 97dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 98dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block UChar* data; 996b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner RefPtr<StringImpl> string = createUninitialized(length, data); 100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block memcpy(data, characters, length * sizeof(UChar)); 1016b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return string.release(); 102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockPassRefPtr<StringImpl> StringImpl::create(const char* characters, unsigned length) 105dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 106dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!characters || !length) 107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return empty(); 108dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 109dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block UChar* data; 1106b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner RefPtr<StringImpl> string = createUninitialized(length, data); 111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block for (unsigned i = 0; i != length; ++i) { 112dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block unsigned char c = characters[i]; 113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block data[i] = c; 114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 1156b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return string.release(); 116dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 117dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 118dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockPassRefPtr<StringImpl> StringImpl::create(const char* string) 119dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 120dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!string) 121dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return empty(); 1226b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner size_t length = strlen(string); 1236b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (length > numeric_limits<unsigned>::max()) 1246b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner CRASH(); 1256b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return create(string, length); 126dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 127dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 128dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockPassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer) 129dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 130dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(characters); 131dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(minLengthToShare && length >= minLengthToShare); 132dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return adoptRef(new StringImpl(characters, length, sharedBuffer)); 133dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 134dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 135dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockSharedUChar* StringImpl::sharedBuffer() 136dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 137dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (m_length < minLengthToShare) 138dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return 0; 139dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // All static strings are smaller that the minimim length to share. 140dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(!isStatic()); 141dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 142dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block BufferOwnership ownership = bufferOwnership(); 143dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 144dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (ownership == BufferInternal) 145dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return 0; 146dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (ownership == BufferSubstring) 147dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return m_substringBuffer->sharedBuffer(); 148dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (ownership == BufferOwned) { 149dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(!m_sharedBuffer); 15028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu m_sharedBuffer = SharedUChar::create(new SharableUChar(m_data)).leakRef(); 151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_refCountAndFlags = (m_refCountAndFlags & ~s_refCountMaskBufferOwnership) | BufferShared; 152dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 153dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 154dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(bufferOwnership() == BufferShared); 155dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(m_sharedBuffer); 156dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return m_sharedBuffer; 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool StringImpl::containsOnlyWhitespace() 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // FIXME: The definition of whitespace here includes a number of characters 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // that are not whitespace from the point of view of RenderText; I wonder if 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // that's a problem in practice. 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (unsigned i = 0; i < m_length; i++) 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!isASCIISpace(m_data[i])) 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochPassRefPtr<StringImpl> StringImpl::substring(unsigned start, unsigned length) 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (start >= m_length) 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return empty(); 1740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch unsigned maxLength = m_length - start; 1750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (length >= maxLength) { 1760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!start) 1770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return this; 1780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch length = maxLength; 1790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return create(m_data + start, length); 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectUChar32 StringImpl::characterStartingAt(unsigned i) 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (U16_IS_SINGLE(m_data[i])) 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return m_data[i]; 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (i + 1 < m_length && U16_IS_LEAD(m_data[i]) && U16_IS_TRAIL(m_data[i + 1])) 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return U16_GET_SUPPLEMENTARY(m_data[i], m_data[i + 1]); 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 192cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve BlockPassRefPtr<StringImpl> StringImpl::lower() 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 194cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // Note: This is a hot function in the Dromaeo benchmark, specifically the 195cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // no-op code path up through the first 'return' statement. 196cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 197cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // First scan the string for uppercase and non-ASCII characters: 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar ored = 0; 199cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block bool noUpper = true; 200cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block const UChar *end = m_data + m_length; 201cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block for (const UChar* chp = m_data; chp != end; chp++) { 202cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (UNLIKELY(isASCIIUpper(*chp))) 203cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block noUpper = false; 204cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block ored |= *chp; 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 206cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 207cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // Nothing to do if the string is all ASCII with no uppercase. 208cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (noUpper && !(ored & ~0x7F)) 209cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return this; 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2116b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max())) 2126b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner CRASH(); 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int32_t length = m_length; 2146b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 215cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block UChar* data; 216cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 218cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (!(ored & ~0x7F)) { 219cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // Do a faster loop for the case where all the characters are ASCII. 220cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block for (int i = 0; i < length; i++) { 221cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block UChar c = m_data[i]; 222cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block data[i] = toASCIILower(c); 223cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 2245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return newImpl; 225cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 226cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do a slower implementation for cases that include non-ASCII characters. 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool error; 2295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t realLength = Unicode::toLower(data, length, m_data, m_length, &error); 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!error && realLength == length) 2315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return newImpl; 2325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian newImpl = createUninitialized(realLength, data); 2335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Unicode::toLower(data, realLength, m_data, m_length, &error); 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (error) 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return this; 2365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return newImpl; 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<StringImpl> StringImpl::upper() 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 241cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // This function could be optimized for no-op cases the way lower() is, 242cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // but in empirical testing, few actual calls to upper() are no-ops, so 243cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block // it wouldn't be worth the extra time for pre-scanning. 2445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian UChar* data; 2456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); 2466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max())) 2486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner CRASH(); 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int32_t length = m_length; 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do a faster loop for the case where all the characters are ASCII. 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar ored = 0; 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = 0; i < length; i++) { 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar c = m_data[i]; 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ored |= c; 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data[i] = toASCIIUpper(c); 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!(ored & ~0x7F)) 2596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return newImpl.release(); 2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do a slower implementation for cases that include non-ASCII characters. 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool error; 2635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t realLength = Unicode::toUpper(data, length, m_data, m_length, &error); 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!error && realLength == length) 2655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return newImpl; 2665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian newImpl = createUninitialized(realLength, data); 2675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Unicode::toUpper(data, realLength, m_data, m_length, &error); 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (error) 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return this; 2706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return newImpl.release(); 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2734576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) WangPassRefPtr<StringImpl> StringImpl::secure(UChar character, LastCharacterBehavior behavior) 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2754576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang if (!m_length) 2764576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang return this; 2774576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang 2785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian UChar* data; 2796b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); 2804576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang unsigned lastCharacterIndex = m_length - 1; 2814576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang for (unsigned i = 0; i < lastCharacterIndex; ++i) 2826b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner data[i] = character; 2834576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang data[lastCharacterIndex] = (behavior == ObscureLastCharacter) ? character : m_data[lastCharacterIndex]; 2846b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return newImpl.release(); 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<StringImpl> StringImpl::foldCase() 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian UChar* data; 2906b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); 2916b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2926b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max())) 2936b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner CRASH(); 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int32_t length = m_length; 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do a faster loop for the case where all the characters are ASCII. 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar ored = 0; 2986b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner for (int32_t i = 0; i < length; i++) { 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar c = m_data[i]; 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ored |= c; 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data[i] = toASCIILower(c); 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!(ored & ~0x7F)) 3046b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return newImpl.release(); 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do a slower implementation for cases that include non-ASCII characters. 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool error; 3085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian int32_t realLength = Unicode::foldCase(data, length, m_data, m_length, &error); 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!error && realLength == length) 3106b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return newImpl.release(); 3115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian newImpl = createUninitialized(realLength, data); 3125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Unicode::foldCase(data, realLength, m_data, m_length, &error); 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (error) 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return this; 3156b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return newImpl.release(); 3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<StringImpl> StringImpl::stripWhiteSpace() 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!m_length) 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return empty(); 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned start = 0; 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned end = m_length - 1; 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // skip white space from start 3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (start <= end && isSpaceOrNewline(m_data[start])) 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project start++; 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // only white space 3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (start > end) 3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return empty(); 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // skip white space from end 3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (end && isSpaceOrNewline(m_data[end])) 3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project end--; 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 338cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (!start && end == m_length - 1) 339cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return this; 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return create(m_data + start, end + 1 - start); 3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 343635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassRefPtr<StringImpl> StringImpl::removeCharacters(CharacterMatchFunctionPtr findMatch) 344635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 345635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project const UChar* from = m_data; 346635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project const UChar* fromend = from + m_length; 347635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 348635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Assume the common case will not remove any characters 349635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project while (from != fromend && !findMatch(*from)) 350635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project from++; 351635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (from == fromend) 352635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return this; 353635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 354635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project StringBuffer data(m_length); 355635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project UChar* to = data.characters(); 356635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project unsigned outc = from - m_data; 357635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 358635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (outc) 359635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project memcpy(to, m_data, outc * sizeof(UChar)); 360635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 361635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project while (true) { 362635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project while (from != fromend && findMatch(*from)) 363635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project from++; 364635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project while (from != fromend && !findMatch(*from)) 365635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project to[outc++] = *from++; 366635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (from == fromend) 367635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project break; 368635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 369635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 370635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project data.shrink(outc); 371635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 372635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return adopt(data); 373635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 374635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<StringImpl> StringImpl::simplifyWhiteSpace() 3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project StringBuffer data(m_length); 3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const UChar* from = m_data; 3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const UChar* fromend = from + m_length; 3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int outc = 0; 382cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block bool changedToSpace = false; 3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar* to = data.characters(); 3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (true) { 387cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block while (from != fromend && isSpaceOrNewline(*from)) { 388cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (*from != ' ') 389cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block changedToSpace = true; 3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project from++; 391cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block } 3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (from != fromend && !isSpaceOrNewline(*from)) 3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to[outc++] = *from++; 3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (from != fromend) 3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project to[outc++] = ' '; 3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (outc > 0 && to[outc - 1] == ' ') 4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project outc--; 4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 403cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block if (static_cast<unsigned>(outc) == m_length && !changedToSpace) 404cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return this; 405cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block 4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data.shrink(outc); 4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return adopt(data); 4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint StringImpl::toIntStrict(bool* ok, int base) 4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return charactersToIntStrict(m_data, m_length, ok, base); 4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned StringImpl::toUIntStrict(bool* ok, int base) 4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return charactersToUIntStrict(m_data, m_length, ok, base); 4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint64_t StringImpl::toInt64Strict(bool* ok, int base) 4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return charactersToInt64Strict(m_data, m_length, ok, base); 4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectuint64_t StringImpl::toUInt64Strict(bool* ok, int base) 4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return charactersToUInt64Strict(m_data, m_length, ok, base); 4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochintptr_t StringImpl::toIntPtrStrict(bool* ok, int base) 4320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 4330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return charactersToIntPtrStrict(m_data, m_length, ok, base); 4340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 4350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint StringImpl::toInt(bool* ok) 4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return charactersToInt(m_data, m_length, ok); 4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned StringImpl::toUInt(bool* ok) 4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return charactersToUInt(m_data, m_length, ok); 4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint64_t StringImpl::toInt64(bool* ok) 4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return charactersToInt64(m_data, m_length, ok); 4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectuint64_t StringImpl::toUInt64(bool* ok) 4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return charactersToUInt64(m_data, m_length, ok); 4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochintptr_t StringImpl::toIntPtr(bool* ok) 4570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 4580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return charactersToIntPtr(m_data, m_length, ok); 4590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 4600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 46181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochdouble StringImpl::toDouble(bool* ok, bool* didReadNumber) 4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 46381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return charactersToDouble(m_data, m_length, ok, didReadNumber); 4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochfloat StringImpl::toFloat(bool* ok, bool* didReadNumber) 4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 46881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return charactersToFloat(m_data, m_length, ok, didReadNumber); 4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic bool equal(const UChar* a, const char* b, int length) 4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(length >= 0); 4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (length--) { 4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned char bc = *b++; 4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (*a++ != bc) 4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool equalIgnoringCase(const UChar* a, const char* b, unsigned length) 4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (length--) { 4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned char bc = *b++; 4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (foldCase(*a++) != foldCase(bc)) 4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline bool equalIgnoringCase(const UChar* a, const UChar* b, int length) 4938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(length >= 0); 4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return umemcasecmp(a, b, length) == 0; 4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4985af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkeint codePointCompare(const StringImpl* s1, const StringImpl* s2) 4995af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{ 5005af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke const unsigned l1 = s1 ? s1->length() : 0; 5015af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke const unsigned l2 = s2 ? s2->length() : 0; 5025af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke const unsigned lmin = l1 < l2 ? l1 : l2; 5035af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke const UChar* c1 = s1 ? s1->characters() : 0; 5045af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke const UChar* c2 = s2 ? s2->characters() : 0; 5055af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke unsigned pos = 0; 5065af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke while (pos < lmin && *c1 == *c2) { 5075af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke c1++; 5085af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke c2++; 5095af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke pos++; 5105af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke } 5115af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 5125af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (pos < lmin) 5135af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return (c1[0] > c2[0]) ? 1 : -1; 5145af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 5155af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (l1 == l2) 5165af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return 0; 5175af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 5185af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return (l1 > l2) ? 1 : -1; 5195af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke} 5205af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 521f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricksize_t StringImpl::find(UChar c, unsigned start) 5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 523f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return WTF::find(m_data, m_length, c, start); 524f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick} 5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 526f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricksize_t StringImpl::find(CharacterMatchFunctionPtr matchFunction, unsigned start) 527f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{ 528f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return WTF::find(m_data, m_length, matchFunction, start); 529f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick} 5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 531f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricksize_t StringImpl::find(const char* matchString, unsigned index) 532f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{ 533f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Check for null or empty string to match against 534f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!matchString) 535f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 5366b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner size_t matchStringLength = strlen(matchString); 5376b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (matchStringLength > numeric_limits<unsigned>::max()) 5386b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner CRASH(); 5396b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner unsigned matchLength = matchStringLength; 540f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!matchLength) 541f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return min(index, length()); 542f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 543f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Optimization 1: fast case for strings of length 1. 544f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (matchLength == 1) 545f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return WTF::find(characters(), length(), *(const unsigned char*)matchString, index); 546f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 547f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Check index & matchLength are in range. 548f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (index > length()) 549f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 550f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned searchLength = length() - index; 551f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (matchLength > searchLength) 552f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 553f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // delta is the number of additional times to test; delta == 0 means test only once. 554f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned delta = searchLength - matchLength; 555f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 556f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* searchCharacters = characters() + index; 557f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const unsigned char* matchCharacters = (const unsigned char*)matchString; 558f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 559f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Optimization 2: keep a running hash of the strings, 560f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // only call memcmp if the hashes match. 561f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned searchHash = 0; 562f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned matchHash = 0; 563f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick for (unsigned i = 0; i < matchLength; ++i) { 564f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick searchHash += searchCharacters[i]; 565f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick matchHash += matchCharacters[i]; 5668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 5678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 568f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned i = 0; 569f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // keep looping until we match 570f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick while (searchHash != matchHash || !equal(searchCharacters + i, matchString, matchLength)) { 571f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (i == delta) 572f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 573f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick searchHash += searchCharacters[i + matchLength]; 574f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick searchHash -= searchCharacters[i]; 575f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ++i; 576f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 577f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return index + i; 578f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick} 579f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 580f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricksize_t StringImpl::findIgnoringCase(const char* matchString, unsigned index) 581f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{ 582f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Check for null or empty string to match against 583f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!matchString) 584f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 5856b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner size_t matchStringLength = strlen(matchString); 5866b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (matchStringLength > numeric_limits<unsigned>::max()) 5876b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner CRASH(); 5886b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner unsigned matchLength = matchStringLength; 589f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!matchLength) 590f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return min(index, length()); 591f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 592f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Check index & matchLength are in range. 593f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (index > length()) 594f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 595f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned searchLength = length() - index; 596f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (matchLength > searchLength) 597f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 598f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // delta is the number of additional times to test; delta == 0 means test only once. 599f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned delta = searchLength - matchLength; 600f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 601f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* searchCharacters = characters() + index; 602f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 603f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned i = 0; 604f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // keep looping until we match 605f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick while (!equalIgnoringCase(searchCharacters + i, matchString, matchLength)) { 606f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (i == delta) 607f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 608f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ++i; 609f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 610f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return index + i; 611f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick} 612f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 613f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricksize_t StringImpl::find(StringImpl* matchString, unsigned index) 614f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{ 615f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Check for null or empty string to match against 616f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!matchString) 617f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 618f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned matchLength = matchString->length(); 619f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!matchLength) 620f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return min(index, length()); 621f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 622f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Optimization 1: fast case for strings of length 1. 623f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (matchLength == 1) 624f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return WTF::find(characters(), length(), matchString->characters()[0], index); 625f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 626f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Check index & matchLength are in range. 627f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (index > length()) 628f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 629f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned searchLength = length() - index; 630f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (matchLength > searchLength) 631f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 632f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // delta is the number of additional times to test; delta == 0 means test only once. 633f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned delta = searchLength - matchLength; 634f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 635f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* searchCharacters = characters() + index; 636f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* matchCharacters = matchString->characters(); 637f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 638f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Optimization 2: keep a running hash of the strings, 639f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // only call memcmp if the hashes match. 640f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned searchHash = 0; 641f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned matchHash = 0; 642f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick for (unsigned i = 0; i < matchLength; ++i) { 643f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick searchHash += searchCharacters[i]; 644f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick matchHash += matchCharacters[i]; 645f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 646f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 647f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned i = 0; 648f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // keep looping until we match 649f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick while (searchHash != matchHash || memcmp(searchCharacters + i, matchCharacters, matchLength * sizeof(UChar))) { 650f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (i == delta) 651f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 652f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick searchHash += searchCharacters[i + matchLength]; 653f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick searchHash -= searchCharacters[i]; 654f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ++i; 655f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 656f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return index + i; 657f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick} 658f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 659f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricksize_t StringImpl::findIgnoringCase(StringImpl* matchString, unsigned index) 660f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick{ 661f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Check for null or empty string to match against 662f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!matchString) 663f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 664f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned matchLength = matchString->length(); 665f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!matchLength) 666f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return min(index, length()); 667f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 668f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Check index & matchLength are in range. 669f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (index > length()) 670f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 671f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned searchLength = length() - index; 672f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (matchLength > searchLength) 673f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 674f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // delta is the number of additional times to test; delta == 0 means test only once. 675f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned delta = searchLength - matchLength; 676f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 677f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* searchCharacters = characters() + index; 678f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar* matchCharacters = matchString->characters(); 679f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 680f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned i = 0; 681f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // keep looping until we match 682f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick while (!equalIgnoringCase(searchCharacters + i, matchCharacters, matchLength)) { 683f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (i == delta) 684f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 685f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ++i; 686f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 687f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return index + i; 6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 690f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricksize_t StringImpl::reverseFind(UChar c, unsigned index) 6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 692f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return WTF::reverseFind(m_data, m_length, c, index); 6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 6948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 695f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricksize_t StringImpl::reverseFind(StringImpl* matchString, unsigned index) 696635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 697f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Check for null or empty string to match against 698f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!matchString) 699f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 700f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned matchLength = matchString->length(); 701f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!matchLength) 702f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return min(index, length()); 703635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 704f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Optimization 1: fast case for strings of length 1. 705f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (matchLength == 1) 706f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return WTF::reverseFind(characters(), length(), matchString->characters()[0], index); 707f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 708f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Check index & matchLength are in range. 709f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (matchLength > length()) 710f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 711f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // delta is the number of additional times to test; delta == 0 means test only once. 712f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned delta = min(index, length() - matchLength); 713f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 714f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar *searchCharacters = characters(); 715f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar *matchCharacters = matchString->characters(); 716f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 717f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Optimization 2: keep a running hash of the strings, 718f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // only call memcmp if the hashes match. 719f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned searchHash = 0; 720f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned matchHash = 0; 721f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick for (unsigned i = 0; i < matchLength; ++i) { 722f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick searchHash += searchCharacters[delta + i]; 723f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick matchHash += matchCharacters[i]; 7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 726f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // keep looping until we match 727f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick while (searchHash != matchHash || memcmp(searchCharacters + delta, matchCharacters, matchLength * sizeof(UChar))) { 728f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!delta) 729f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 730f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick delta--; 731f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick searchHash -= searchCharacters[delta + matchLength]; 732f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick searchHash += searchCharacters[delta]; 733f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 734f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return delta; 7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 737f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merricksize_t StringImpl::reverseFindIgnoringCase(StringImpl* matchString, unsigned index) 7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 739f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Check for null or empty string to match against 740f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!matchString) 741f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 742f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned matchLength = matchString->length(); 743f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!matchLength) 744f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return min(index, length()); 745f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 746f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // Check index & matchLength are in range. 747f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (matchLength > length()) 748f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 749f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // delta is the number of additional times to test; delta == 0 means test only once. 750f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned delta = min(index, length() - matchLength); 7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 752f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar *searchCharacters = characters(); 753f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick const UChar *matchCharacters = matchString->characters(); 754f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick 755f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick // keep looping until we match 756f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick while (!equalIgnoringCase(searchCharacters + delta, matchCharacters, matchLength)) { 757f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!delta) 758f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return notFound; 759f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick delta--; 7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 761f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return delta; 7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool StringImpl::endsWith(StringImpl* m_data, bool caseSensitive) 7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(m_data); 767f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (m_length >= m_data->m_length) { 768f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned start = m_length - m_data->m_length; 769f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick return (caseSensitive ? find(m_data, start) : findIgnoringCase(m_data, start)) == start; 770f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick } 7718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<StringImpl> StringImpl::replace(UChar oldC, UChar newC) 7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (oldC == newC) 7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return this; 7788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned i; 7798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (i = 0; i != m_length; ++i) 7808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_data[i] == oldC) 7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (i == m_length) 7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return this; 7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian UChar* data; 7866b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); 7875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 7888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (i = 0; i != m_length; ++i) { 7898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar ch = m_data[i]; 7908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ch == oldC) 7918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ch = newC; 7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project data[i] = ch; 7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 7946b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return newImpl.release(); 7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<StringImpl> StringImpl::replace(unsigned position, unsigned lengthToReplace, StringImpl* str) 7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project position = min(position, length()); 8008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lengthToReplace = min(lengthToReplace, length() - position); 8018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned lengthToInsert = str ? str->length() : 0; 8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!lengthToReplace && !lengthToInsert) 8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return this; 8045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian UChar* data; 8055ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 8065ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if ((length() - lengthToReplace) >= (numeric_limits<unsigned>::max() - lengthToInsert)) 8075ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen CRASH(); 8085ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 8096b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner RefPtr<StringImpl> newImpl = 8105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian createUninitialized(length() - lengthToReplace + lengthToInsert, data); 8115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian memcpy(data, characters(), position * sizeof(UChar)); 8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (str) 8135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian memcpy(data + position, str->characters(), lengthToInsert * sizeof(UChar)); 8145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian memcpy(data + position + lengthToInsert, characters() + position + lengthToReplace, 8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project (length() - position - lengthToReplace) * sizeof(UChar)); 8166b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return newImpl.release(); 8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacement) 8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!replacement) 8228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return this; 8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 824f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned repStrLength = replacement->length(); 825f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick size_t srcSegmentStart = 0; 826f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned matchCount = 0; 8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Count the matches 829f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick while ((srcSegmentStart = find(pattern, srcSegmentStart)) != notFound) { 8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++matchCount; 8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++srcSegmentStart; 8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we have 0 matches, we don't have to do any more work 8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!matchCount) 8368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return this; 8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (repStrLength && matchCount > numeric_limits<unsigned>::max() / repStrLength) 8395ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen CRASH(); 8405ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 8415ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen unsigned replaceSize = matchCount * repStrLength; 8425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen unsigned newSize = m_length - matchCount; 8435ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (newSize >= (numeric_limits<unsigned>::max() - replaceSize)) 8445ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen CRASH(); 8455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 8465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen newSize += replaceSize; 8475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 8485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian UChar* data; 8496b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner RefPtr<StringImpl> newImpl = createUninitialized(newSize, data); 8505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Construct the new data 852f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick size_t srcSegmentEnd; 853f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned srcSegmentLength; 8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project srcSegmentStart = 0; 855f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned dstOffset = 0; 8568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 857f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) { 8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project srcSegmentLength = srcSegmentEnd - srcSegmentStart; 8595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar)); 8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dstOffset += srcSegmentLength; 8615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian memcpy(data + dstOffset, replacement->m_data, repStrLength * sizeof(UChar)); 8628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dstOffset += repStrLength; 8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project srcSegmentStart = srcSegmentEnd + 1; 8648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project srcSegmentLength = m_length - srcSegmentStart; 8675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar)); 8688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 869f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ASSERT(dstOffset + srcSegmentLength == newImpl->length()); 8708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8716b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return newImpl.release(); 8728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 8738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* replacement) 8758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 8768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!pattern || !replacement) 8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return this; 8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 879f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned patternLength = pattern->length(); 8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!patternLength) 8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return this; 8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 883f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned repStrLength = replacement->length(); 884f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick size_t srcSegmentStart = 0; 885f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned matchCount = 0; 8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Count the matches 888f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick while ((srcSegmentStart = find(pattern, srcSegmentStart)) != notFound) { 8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++matchCount; 8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project srcSegmentStart += patternLength; 8918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 8928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If we have 0 matches, we don't have to do any more work 8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!matchCount) 8958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return this; 8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 8975ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen unsigned newSize = m_length - matchCount * patternLength; 8985ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (repStrLength && matchCount > numeric_limits<unsigned>::max() / repStrLength) 8995ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen CRASH(); 9005ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 9015ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen if (newSize > (numeric_limits<unsigned>::max() - matchCount * repStrLength)) 9025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen CRASH(); 9035ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 9045ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen newSize += matchCount * repStrLength; 9055ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 9065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian UChar* data; 9076b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner RefPtr<StringImpl> newImpl = createUninitialized(newSize, data); 9088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Construct the new data 910f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick size_t srcSegmentEnd; 911f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned srcSegmentLength; 9128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project srcSegmentStart = 0; 913f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned dstOffset = 0; 9148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 915f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) { 9168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project srcSegmentLength = srcSegmentEnd - srcSegmentStart; 9175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar)); 9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dstOffset += srcSegmentLength; 9195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian memcpy(data + dstOffset, replacement->m_data, repStrLength * sizeof(UChar)); 9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project dstOffset += repStrLength; 9218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project srcSegmentStart = srcSegmentEnd + patternLength; 9228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project srcSegmentLength = m_length - srcSegmentStart; 9255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar)); 9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 927f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick ASSERT(dstOffset + srcSegmentLength == newImpl->length()); 9288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner return newImpl.release(); 9308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 932dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool equal(const StringImpl* a, const StringImpl* b) 9338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return StringHash::equal(a, b); 9358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 937dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockbool equal(const StringImpl* a, const char* b) 9388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!a) 9408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return !b; 9418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!b) 9428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return !a; 9438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned length = a->length(); 9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const UChar* as = a->characters(); 9468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (unsigned i = 0; i != length; ++i) { 9478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned char bc = b[i]; 9488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!bc) 9498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 9508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (as[i] != bc) 9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return !b[length]; 9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool equalIgnoringCase(StringImpl* a, StringImpl* b) 9588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return CaseFoldingHash::equal(a, b); 9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool equalIgnoringCase(StringImpl* a, const char* b) 9638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!a) 9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return !b; 9668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!b) 9678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return !a; 9688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned length = a->length(); 9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const UChar* as = a->characters(); 9718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do a faster loop for the case where all the characters are ASCII. 9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar ored = 0; 9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool equal = true; 9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (unsigned i = 0; i != length; ++i) { 9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project char bc = b[i]; 9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!bc) 9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UChar ac = as[i]; 9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ored |= ac; 9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project equal = equal && (toASCIILower(ac) == toASCIILower(bc)); 9828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do a slower implementation for cases that include non-ASCII characters. 9858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ored & ~0x7F) { 9868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project equal = true; 9878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (unsigned i = 0; i != length; ++i) { 9888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned char bc = b[i]; 9898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project equal = equal && (foldCase(as[i]) == foldCase(bc)); 9908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 9928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return equal && !b[length]; 9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 9958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 9960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool equalIgnoringNullity(StringImpl* a, StringImpl* b) 9970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 9980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (StringHash::equal(a, b)) 9990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return true; 10000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!a && b && !b->length()) 10010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return true; 10020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!b && a && !a->length()) 10030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return true; 10040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 10050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return false; 10060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 10070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 100881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochWTF::Unicode::Direction StringImpl::defaultWritingDirection(bool* hasStrongDirectionality) 10098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 10108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (unsigned i = 0; i < m_length; ++i) { 10118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project WTF::Unicode::Direction charDirection = WTF::Unicode::direction(m_data[i]); 101281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (charDirection == WTF::Unicode::LeftToRight) { 101381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (hasStrongDirectionality) 101481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *hasStrongDirectionality = true; 10158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return WTF::Unicode::LeftToRight; 101681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 101781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (charDirection == WTF::Unicode::RightToLeft || charDirection == WTF::Unicode::RightToLeftArabic) { 101881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (hasStrongDirectionality) 101981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *hasStrongDirectionality = true; 10208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return WTF::Unicode::RightToLeft; 102181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch } 10228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 102381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch if (hasStrongDirectionality) 102481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch *hasStrongDirectionality = false; 10258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return WTF::Unicode::LeftToRight; 10268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// This is a hot function because it's used when parsing HTML. 10298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng QianPassRefPtr<StringImpl> StringImpl::createStrippingNullCharactersSlowCase(const UChar* characters, unsigned length) 10308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 10318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project StringBuffer strippedCopy(length); 10328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned strippedLength = 0; 10338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (unsigned i = 0; i < length; i++) { 10348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (int c = characters[i]) 10358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project strippedCopy[strippedLength++] = c; 10368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 10378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(strippedLength < length); // Only take the slow case when stripping. 10388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project strippedCopy.shrink(strippedLength); 10398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return adopt(strippedCopy); 10408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<StringImpl> StringImpl::adopt(StringBuffer& buffer) 10438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 10448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned length = buffer.length(); 10458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (length == 0) 10468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return empty(); 1047cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block return adoptRef(new StringImpl(buffer.release(), length)); 10488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 10508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<StringImpl> StringImpl::createWithTerminatingNullCharacter(const StringImpl& string) 10518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1052231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Use createUninitialized instead of 'new StringImpl' so that the string and its buffer 10536b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // get allocated in a single memory block. 1054231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block UChar* data; 10556b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner unsigned length = string.m_length; 10566b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (length >= numeric_limits<unsigned>::max()) 10576b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner CRASH(); 1058231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block RefPtr<StringImpl> terminatedString = createUninitialized(length + 1, data); 1059231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block memcpy(data, string.m_data, length * sizeof(UChar)); 1060231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block data[length] = 0; 1061231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block terminatedString->m_length--; 1062231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block terminatedString->m_hash = string.m_hash; 1063692e5dbf12901edacf14812a6fae25462920af42Steve Block terminatedString->m_refCountAndFlags |= s_refCountFlagHasTerminatingNullCharacter; 1064231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return terminatedString.release(); 10658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1067231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockPassRefPtr<StringImpl> StringImpl::threadsafeCopy() const 10688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1069231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return create(m_data, m_length); 1070231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 1071231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1072231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockPassRefPtr<StringImpl> StringImpl::crossThreadString() 1073231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 1074692e5dbf12901edacf14812a6fae25462920af42Steve Block if (SharedUChar* sharedBuffer = this->sharedBuffer()) 1075692e5dbf12901edacf14812a6fae25462920af42Steve Block return adoptRef(new StringImpl(m_data, m_length, sharedBuffer->crossThreadCopy())); 1076231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 1077231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If no shared buffer is available, create a copy. 1078231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return threadsafeCopy(); 10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 10808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1081dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch} // namespace WTF 1082