| OLD | NEW |
| 1 /* | 1 /* |
| 2 * (C) 1999 Lars Knoll (knoll@kde.org) | 2 * (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2012 Apple Inc. All rights
reserved. | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2012 Apple Inc. All rights
reserved. |
| 4 * Copyright (C) 2007-2009 Torch Mobile, Inc. | 4 * Copyright (C) 2007-2009 Torch Mobile, Inc. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 String::String(const LChar* characters) | 69 String::String(const LChar* characters) |
| 70 : m_impl(characters ? StringImpl::create(characters) : nullptr) | 70 : m_impl(characters ? StringImpl::create(characters) : nullptr) |
| 71 { | 71 { |
| 72 } | 72 } |
| 73 | 73 |
| 74 String::String(const char* characters) | 74 String::String(const char* characters) |
| 75 : m_impl(characters ? StringImpl::create(reinterpret_cast<const LChar*>(char
acters)) : nullptr) | 75 : m_impl(characters ? StringImpl::create(reinterpret_cast<const LChar*>(char
acters)) : nullptr) |
| 76 { | 76 { |
| 77 } | 77 } |
| 78 | 78 |
| 79 void String::append(const String& string) | 79 void String::append(const StringView& string) |
| 80 { | 80 { |
| 81 if (string.isEmpty()) | 81 if (string.isEmpty()) |
| 82 return; | 82 return; |
| 83 if (!m_impl) { | 83 if (!m_impl) { |
| 84 m_impl = string.m_impl; | 84 m_impl = string.toString().releaseImpl(); |
| 85 return; | 85 return; |
| 86 } | 86 } |
| 87 | 87 |
| 88 // FIXME: This is extremely inefficient. So much so that we might want to | 88 // FIXME: This is extremely inefficient. So much so that we might want to |
| 89 // take this out of String's API. We can make it better by optimizing the | 89 // take this out of String's API. We can make it better by optimizing the |
| 90 // case where exactly one String is pointing at this StringImpl, but even | 90 // case where exactly one String is pointing at this StringImpl, but even |
| 91 // then it's going to require a call into the allocator every single time. | 91 // then it's going to require a call into the allocator every single time. |
| 92 | 92 |
| 93 if (m_impl->is8Bit() && string.m_impl->is8Bit()) { | 93 if (m_impl->is8Bit() && string.is8Bit()) { |
| 94 LChar* data; | 94 LChar* data; |
| 95 RELEASE_ASSERT(string.length() <= std::numeric_limits<unsigned>::max() -
m_impl->length()); | 95 RELEASE_ASSERT(string.length() <= std::numeric_limits<unsigned>::max() -
m_impl->length()); |
| 96 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->len
gth() + string.length(), data); | 96 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->len
gth() + string.length(), data); |
| 97 memcpy(data, m_impl->characters8(), m_impl->length() * sizeof(LChar)); | 97 memcpy(data, m_impl->characters8(), m_impl->length() * sizeof(LChar)); |
| 98 memcpy(data + m_impl->length(), string.characters8(), string.length() *
sizeof(LChar)); | 98 memcpy(data + m_impl->length(), string.characters8(), string.length() *
sizeof(LChar)); |
| 99 m_impl = newImpl.release(); | 99 m_impl = newImpl.release(); |
| 100 return; | 100 return; |
| 101 } | 101 } |
| 102 | 102 |
| 103 UChar* data; | 103 UChar* data; |
| 104 RELEASE_ASSERT(string.length() <= std::numeric_limits<unsigned>::max() - m_i
mpl->length()); | 104 RELEASE_ASSERT(string.length() <= std::numeric_limits<unsigned>::max() - m_i
mpl->length()); |
| 105 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length(
) + string.length(), data); | 105 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length(
) + string.length(), data); |
| 106 | 106 |
| 107 if (m_impl->is8Bit()) | 107 if (m_impl->is8Bit()) |
| 108 StringImpl::copyChars(data, m_impl->characters8(), m_impl->length()); | 108 StringImpl::copyChars(data, m_impl->characters8(), m_impl->length()); |
| 109 else | 109 else |
| 110 StringImpl::copyChars(data, m_impl->characters16(), m_impl->length()); | 110 StringImpl::copyChars(data, m_impl->characters16(), m_impl->length()); |
| 111 | 111 |
| 112 if (string.impl()->is8Bit()) | 112 if (string.is8Bit()) |
| 113 StringImpl::copyChars(data + m_impl->length(), string.impl()->characters
8(), string.impl()->length()); | 113 StringImpl::copyChars(data + m_impl->length(), string.characters8(), str
ing.length()); |
| 114 else | 114 else |
| 115 StringImpl::copyChars(data + m_impl->length(), string.impl()->characters
16(), string.impl()->length()); | 115 StringImpl::copyChars(data + m_impl->length(), string.characters16(), st
ring.length()); |
| 116 | 116 |
| 117 m_impl = newImpl.release(); | 117 m_impl = newImpl.release(); |
| 118 } | 118 } |
| 119 | 119 |
| 120 template <typename CharacterType> | 120 template <typename CharacterType> |
| 121 inline void String::appendInternal(CharacterType c) | 121 inline void String::appendInternal(CharacterType c) |
| 122 { | 122 { |
| 123 // FIXME: This is extremely inefficient. So much so that we might want to | 123 // FIXME: This is extremely inefficient. So much so that we might want to |
| 124 // take this out of String's API. We can make it better by optimizing the | 124 // take this out of String's API. We can make it better by optimizing the |
| 125 // case where exactly one String is pointing at this StringImpl, but even | 125 // case where exactly one String is pointing at this StringImpl, but even |
| (...skipping 28 matching lines...) Expand all Loading... |
| 154 int codePointCompare(const String& a, const String& b) | 154 int codePointCompare(const String& a, const String& b) |
| 155 { | 155 { |
| 156 return codePointCompare(a.impl(), b.impl()); | 156 return codePointCompare(a.impl(), b.impl()); |
| 157 } | 157 } |
| 158 | 158 |
| 159 int codePointCompareIgnoringASCIICase(const String& a, const char* b) | 159 int codePointCompareIgnoringASCIICase(const String& a, const char* b) |
| 160 { | 160 { |
| 161 return codePointCompareIgnoringASCIICase(a.impl(), reinterpret_cast<const LC
har*>(b)); | 161 return codePointCompareIgnoringASCIICase(a.impl(), reinterpret_cast<const LC
har*>(b)); |
| 162 } | 162 } |
| 163 | 163 |
| 164 void String::insert(const String& string, unsigned position) | |
| 165 { | |
| 166 if (string.isEmpty()) { | |
| 167 if (string.isNull()) | |
| 168 return; | |
| 169 if (isNull()) | |
| 170 m_impl = string.impl(); | |
| 171 return; | |
| 172 } | |
| 173 | |
| 174 if (string.is8Bit()) | |
| 175 insert(string.impl()->characters8(), string.length(), position); | |
| 176 else | |
| 177 insert(string.impl()->characters16(), string.length(), position); | |
| 178 } | |
| 179 | |
| 180 void String::append(const LChar* charactersToAppend, unsigned lengthToAppend) | |
| 181 { | |
| 182 if (!m_impl) { | |
| 183 if (!charactersToAppend) | |
| 184 return; | |
| 185 m_impl = StringImpl::create(charactersToAppend, lengthToAppend); | |
| 186 return; | |
| 187 } | |
| 188 | |
| 189 if (!lengthToAppend) | |
| 190 return; | |
| 191 | |
| 192 ASSERT(charactersToAppend); | |
| 193 | |
| 194 unsigned strLength = m_impl->length(); | |
| 195 | |
| 196 if (m_impl->is8Bit()) { | |
| 197 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() -
strLength); | |
| 198 LChar* data; | |
| 199 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength +
lengthToAppend, data); | |
| 200 StringImpl::copyChars(data, m_impl->characters8(), strLength); | |
| 201 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppe
nd); | |
| 202 m_impl = newImpl.release(); | |
| 203 return; | |
| 204 } | |
| 205 | |
| 206 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strL
ength); | |
| 207 UChar* data; | |
| 208 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + leng
thToAppend, data); | |
| 209 StringImpl::copyChars(data, m_impl->characters16(), strLength); | |
| 210 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); | |
| 211 m_impl = newImpl.release(); | |
| 212 } | |
| 213 | |
| 214 void String::append(const UChar* charactersToAppend, unsigned lengthToAppend) | |
| 215 { | |
| 216 if (!m_impl) { | |
| 217 if (!charactersToAppend) | |
| 218 return; | |
| 219 m_impl = StringImpl::create(charactersToAppend, lengthToAppend); | |
| 220 return; | |
| 221 } | |
| 222 | |
| 223 if (!lengthToAppend) | |
| 224 return; | |
| 225 | |
| 226 unsigned strLength = m_impl->length(); | |
| 227 | |
| 228 ASSERT(charactersToAppend); | |
| 229 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strL
ength); | |
| 230 UChar* data; | |
| 231 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + len
gthToAppend, data); | |
| 232 if (m_impl->is8Bit()) | |
| 233 StringImpl::copyChars(data, characters8(), strLength); | |
| 234 else | |
| 235 StringImpl::copyChars(data, characters16(), strLength); | |
| 236 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); | |
| 237 m_impl = newImpl.release(); | |
| 238 } | |
| 239 | |
| 240 template<typename CharType> | 164 template<typename CharType> |
| 241 PassRefPtr<StringImpl> insertInternal(PassRefPtr<StringImpl> impl, const CharTyp
e* charactersToInsert, unsigned lengthToInsert, unsigned position) | 165 PassRefPtr<StringImpl> insertInternal(PassRefPtr<StringImpl> impl, const CharTyp
e* charactersToInsert, unsigned lengthToInsert, unsigned position) |
| 242 { | 166 { |
| 243 if (!lengthToInsert) | 167 if (!lengthToInsert) |
| 244 return impl; | 168 return impl; |
| 245 | 169 |
| 246 ASSERT(charactersToInsert); | 170 ASSERT(charactersToInsert); |
| 247 UChar* data; // FIXME: We should be able to create an 8 bit string here. | 171 UChar* data; // FIXME: We should be able to create an 8 bit string here. |
| 248 RELEASE_ASSERT(lengthToInsert <= std::numeric_limits<unsigned>::max() - impl
->length()); | 172 RELEASE_ASSERT(lengthToInsert <= std::numeric_limits<unsigned>::max() - impl
->length()); |
| 249 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(impl->length()
+ lengthToInsert, data); | 173 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(impl->length()
+ lengthToInsert, data); |
| 250 | 174 |
| 251 if (impl->is8Bit()) | 175 if (impl->is8Bit()) |
| 252 StringImpl::copyChars(data, impl->characters8(), position); | 176 StringImpl::copyChars(data, impl->characters8(), position); |
| 253 else | 177 else |
| 254 StringImpl::copyChars(data, impl->characters16(), position); | 178 StringImpl::copyChars(data, impl->characters16(), position); |
| 255 | 179 |
| 256 StringImpl::copyChars(data + position, charactersToInsert, lengthToInsert); | 180 StringImpl::copyChars(data + position, charactersToInsert, lengthToInsert); |
| 257 | 181 |
| 258 if (impl->is8Bit()) | 182 if (impl->is8Bit()) |
| 259 StringImpl::copyChars(data + position + lengthToInsert, impl->characters
8() + position, impl->length() - position); | 183 StringImpl::copyChars(data + position + lengthToInsert, impl->characters
8() + position, impl->length() - position); |
| 260 else | 184 else |
| 261 StringImpl::copyChars(data + position + lengthToInsert, impl->characters
16() + position, impl->length() - position); | 185 StringImpl::copyChars(data + position + lengthToInsert, impl->characters
16() + position, impl->length() - position); |
| 262 | 186 |
| 263 return newImpl.release(); | 187 return newImpl.release(); |
| 264 } | 188 } |
| 265 | 189 |
| 266 void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, un
signed position) | 190 void String::insert(const StringView& string, unsigned position) |
| 267 { | 191 { |
| 268 if (position >= length()) { | 192 if (string.isEmpty()) { |
| 269 append(charactersToInsert, lengthToInsert); | 193 if (string.isNull()) |
| 194 return; |
| 195 if (isNull()) |
| 196 m_impl = string.toString().releaseImpl(); |
| 270 return; | 197 return; |
| 271 } | 198 } |
| 272 ASSERT(m_impl); | |
| 273 m_impl = insertInternal(m_impl.release(), charactersToInsert, lengthToInsert
, position); | |
| 274 } | |
| 275 | 199 |
| 276 void String::insert(const LChar* charactersToInsert, unsigned lengthToInsert, un
signed position) | |
| 277 { | |
| 278 if (position >= length()) { | 200 if (position >= length()) { |
| 279 append(charactersToInsert, lengthToInsert); | 201 if (string.is8Bit()) |
| 202 append(string); |
| 203 else |
| 204 append(string); |
| 280 return; | 205 return; |
| 281 } | 206 } |
| 282 ASSERT(m_impl); | 207 |
| 283 m_impl = insertInternal(m_impl.release(), charactersToInsert, lengthToInsert
, position); | 208 DCHECK(m_impl); |
| 209 if (string.is8Bit()) |
| 210 m_impl = insertInternal(m_impl.release(), string.characters8(), string.l
ength(), position); |
| 211 else |
| 212 m_impl = insertInternal(m_impl.release(), string.characters16(), string.
length(), position); |
| 284 } | 213 } |
| 285 | 214 |
| 286 UChar32 String::characterStartingAt(unsigned i) const | 215 UChar32 String::characterStartingAt(unsigned i) const |
| 287 { | 216 { |
| 288 if (!m_impl || i >= m_impl->length()) | 217 if (!m_impl || i >= m_impl->length()) |
| 289 return 0; | 218 return 0; |
| 290 return m_impl->characterStartingAt(i); | 219 return m_impl->characterStartingAt(i); |
| 291 } | 220 } |
| 292 | 221 |
| 293 void String::ensure16Bit() | 222 void String::ensure16Bit() |
| (...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1007 buffer.append('\0'); | 936 buffer.append('\0'); |
| 1008 return buffer; | 937 return buffer; |
| 1009 } | 938 } |
| 1010 | 939 |
| 1011 Vector<char> asciiDebug(String& string) | 940 Vector<char> asciiDebug(String& string) |
| 1012 { | 941 { |
| 1013 return asciiDebug(string.impl()); | 942 return asciiDebug(string.impl()); |
| 1014 } | 943 } |
| 1015 | 944 |
| 1016 #endif | 945 #endif |
| OLD | NEW |