| 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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.m_impl->is8Bit()) { |
| 94 LChar* data; | 94 LChar* data; |
| 95 RELEASE_ASSERT(string.length() <= std::numeric_limits<unsigned>::max() -
m_impl->length()); | 95 CHECK_LE(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 CHECK_LE(string.length(), std::numeric_limits<unsigned>::max() - m_impl->len
gth()); |
| 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.impl()->is8Bit()) |
| 113 StringImpl::copyChars(data + m_impl->length(), string.impl()->characters
8(), string.impl()->length()); | 113 StringImpl::copyChars(data + m_impl->length(), string.impl()->characters
8(), string.impl()->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.impl()->characters
16(), string.impl()->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 |
| 126 // then it's going to require a call into the allocator every single time. | 126 // then it's going to require a call into the allocator every single time. |
| 127 if (!m_impl) { | 127 if (!m_impl) { |
| 128 m_impl = StringImpl::create(&c, 1); | 128 m_impl = StringImpl::create(&c, 1); |
| 129 return; | 129 return; |
| 130 } | 130 } |
| 131 | 131 |
| 132 // FIXME: We should be able to create an 8 bit string via this code path. | 132 // FIXME: We should be able to create an 8 bit string via this code path. |
| 133 UChar* data; | 133 UChar* data; |
| 134 RELEASE_ASSERT(m_impl->length() < std::numeric_limits<unsigned>::max()); | 134 CHECK_LT(m_impl->length(), std::numeric_limits<unsigned>::max()); |
| 135 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length(
) + 1, data); | 135 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length(
) + 1, data); |
| 136 if (m_impl->is8Bit()) | 136 if (m_impl->is8Bit()) |
| 137 StringImpl::copyChars(data, m_impl->characters8(), m_impl->length()); | 137 StringImpl::copyChars(data, m_impl->characters8(), m_impl->length()); |
| 138 else | 138 else |
| 139 StringImpl::copyChars(data, m_impl->characters16(), m_impl->length()); | 139 StringImpl::copyChars(data, m_impl->characters16(), m_impl->length()); |
| 140 data[m_impl->length()] = c; | 140 data[m_impl->length()] = c; |
| 141 m_impl = newImpl.release(); | 141 m_impl = newImpl.release(); |
| 142 } | 142 } |
| 143 | 143 |
| 144 void String::append(LChar c) | 144 void String::append(LChar c) |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 } | 182 } |
| 183 | 183 |
| 184 if (!lengthToAppend) | 184 if (!lengthToAppend) |
| 185 return; | 185 return; |
| 186 | 186 |
| 187 ASSERT(charactersToAppend); | 187 ASSERT(charactersToAppend); |
| 188 | 188 |
| 189 unsigned strLength = m_impl->length(); | 189 unsigned strLength = m_impl->length(); |
| 190 | 190 |
| 191 if (m_impl->is8Bit()) { | 191 if (m_impl->is8Bit()) { |
| 192 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() -
strLength); | 192 CHECK_LE(lengthToAppend, std::numeric_limits<unsigned>::max() - strLengt
h); |
| 193 LChar* data; | 193 LChar* data; |
| 194 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength +
lengthToAppend, data); | 194 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength +
lengthToAppend, data); |
| 195 StringImpl::copyChars(data, m_impl->characters8(), strLength); | 195 StringImpl::copyChars(data, m_impl->characters8(), strLength); |
| 196 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppe
nd); | 196 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppe
nd); |
| 197 m_impl = newImpl.release(); | 197 m_impl = newImpl.release(); |
| 198 return; | 198 return; |
| 199 } | 199 } |
| 200 | 200 |
| 201 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strL
ength); | 201 CHECK_LE(lengthToAppend, std::numeric_limits<unsigned>::max() - strLength); |
| 202 UChar* data; | 202 UChar* data; |
| 203 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + leng
thToAppend, data); | 203 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + leng
thToAppend, data); |
| 204 StringImpl::copyChars(data, m_impl->characters16(), strLength); | 204 StringImpl::copyChars(data, m_impl->characters16(), strLength); |
| 205 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); | 205 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); |
| 206 m_impl = newImpl.release(); | 206 m_impl = newImpl.release(); |
| 207 } | 207 } |
| 208 | 208 |
| 209 void String::append(const UChar* charactersToAppend, unsigned lengthToAppend) | 209 void String::append(const UChar* charactersToAppend, unsigned lengthToAppend) |
| 210 { | 210 { |
| 211 if (!m_impl) { | 211 if (!m_impl) { |
| 212 if (!charactersToAppend) | 212 if (!charactersToAppend) |
| 213 return; | 213 return; |
| 214 m_impl = StringImpl::create(charactersToAppend, lengthToAppend); | 214 m_impl = StringImpl::create(charactersToAppend, lengthToAppend); |
| 215 return; | 215 return; |
| 216 } | 216 } |
| 217 | 217 |
| 218 if (!lengthToAppend) | 218 if (!lengthToAppend) |
| 219 return; | 219 return; |
| 220 | 220 |
| 221 unsigned strLength = m_impl->length(); | 221 unsigned strLength = m_impl->length(); |
| 222 | 222 |
| 223 ASSERT(charactersToAppend); | 223 ASSERT(charactersToAppend); |
| 224 RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strL
ength); | 224 CHECK_LE(lengthToAppend, std::numeric_limits<unsigned>::max() - strLength); |
| 225 UChar* data; | 225 UChar* data; |
| 226 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + len
gthToAppend, data); | 226 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + len
gthToAppend, data); |
| 227 if (m_impl->is8Bit()) | 227 if (m_impl->is8Bit()) |
| 228 StringImpl::copyChars(data, characters8(), strLength); | 228 StringImpl::copyChars(data, characters8(), strLength); |
| 229 else | 229 else |
| 230 StringImpl::copyChars(data, characters16(), strLength); | 230 StringImpl::copyChars(data, characters16(), strLength); |
| 231 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); | 231 StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); |
| 232 m_impl = newImpl.release(); | 232 m_impl = newImpl.release(); |
| 233 } | 233 } |
| 234 | 234 |
| 235 template<typename CharType> | 235 template<typename CharType> |
| 236 PassRefPtr<StringImpl> insertInternal(PassRefPtr<StringImpl> impl, const CharTyp
e* charactersToInsert, unsigned lengthToInsert, unsigned position) | 236 PassRefPtr<StringImpl> insertInternal(PassRefPtr<StringImpl> impl, const CharTyp
e* charactersToInsert, unsigned lengthToInsert, unsigned position) |
| 237 { | 237 { |
| 238 if (!lengthToInsert) | 238 if (!lengthToInsert) |
| 239 return impl; | 239 return impl; |
| 240 | 240 |
| 241 ASSERT(charactersToInsert); | 241 ASSERT(charactersToInsert); |
| 242 UChar* data; // FIXME: We should be able to create an 8 bit string here. | 242 UChar* data; // FIXME: We should be able to create an 8 bit string here. |
| 243 RELEASE_ASSERT(lengthToInsert <= std::numeric_limits<unsigned>::max() - impl
->length()); | 243 CHECK_LE(lengthToInsert, std::numeric_limits<unsigned>::max() - impl->length
()); |
| 244 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(impl->length()
+ lengthToInsert, data); | 244 RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(impl->length()
+ lengthToInsert, data); |
| 245 | 245 |
| 246 if (impl->is8Bit()) | 246 if (impl->is8Bit()) |
| 247 StringImpl::copyChars(data, impl->characters8(), position); | 247 StringImpl::copyChars(data, impl->characters8(), position); |
| 248 else | 248 else |
| 249 StringImpl::copyChars(data, impl->characters16(), position); | 249 StringImpl::copyChars(data, impl->characters16(), position); |
| 250 | 250 |
| 251 StringImpl::copyChars(data + position, charactersToInsert, lengthToInsert); | 251 StringImpl::copyChars(data + position, charactersToInsert, lengthToInsert); |
| 252 | 252 |
| 253 if (impl->is8Bit()) | 253 if (impl->is8Bit()) |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 Vector<UChar> result; | 425 Vector<UChar> result; |
| 426 result.reserveInitialCapacity(length() + 1); | 426 result.reserveInitialCapacity(length() + 1); |
| 427 appendTo(result); | 427 appendTo(result); |
| 428 result.append('\0'); | 428 result.append('\0'); |
| 429 return result; | 429 return result; |
| 430 } | 430 } |
| 431 | 431 |
| 432 unsigned String::copyTo(UChar* buffer, unsigned pos, unsigned maxLength) const | 432 unsigned String::copyTo(UChar* buffer, unsigned pos, unsigned maxLength) const |
| 433 { | 433 { |
| 434 unsigned length = this->length(); | 434 unsigned length = this->length(); |
| 435 RELEASE_ASSERT(pos <= length); | 435 CHECK_LE(pos, length); |
| 436 unsigned numCharacters = std::min(length - pos, maxLength); | 436 unsigned numCharacters = std::min(length - pos, maxLength); |
| 437 if (!numCharacters) | 437 if (!numCharacters) |
| 438 return 0; | 438 return 0; |
| 439 if (is8Bit()) | 439 if (is8Bit()) |
| 440 StringImpl::copyChars(buffer, characters8() + pos, numCharacters); | 440 StringImpl::copyChars(buffer, characters8() + pos, numCharacters); |
| 441 else | 441 else |
| 442 StringImpl::copyChars(buffer, characters16() + pos, numCharacters); | 442 StringImpl::copyChars(buffer, characters16() + pos, numCharacters); |
| 443 return numCharacters; | 443 return numCharacters; |
| 444 } | 444 } |
| 445 | 445 |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 UChar* destination; | 864 UChar* destination; |
| 865 String result = String::createUninitialized(length, destination); | 865 String result = String::createUninitialized(length, destination); |
| 866 | 866 |
| 867 StringImpl::copyChars(destination, source, length); | 867 StringImpl::copyChars(destination, source, length); |
| 868 | 868 |
| 869 return result; | 869 return result; |
| 870 } | 870 } |
| 871 | 871 |
| 872 String String::fromUTF8(const LChar* stringStart, size_t length) | 872 String String::fromUTF8(const LChar* stringStart, size_t length) |
| 873 { | 873 { |
| 874 RELEASE_ASSERT(length <= std::numeric_limits<unsigned>::max()); | 874 CHECK_LE(length, std::numeric_limits<unsigned>::max()); |
| 875 | 875 |
| 876 if (!stringStart) | 876 if (!stringStart) |
| 877 return String(); | 877 return String(); |
| 878 | 878 |
| 879 if (!length) | 879 if (!length) |
| 880 return emptyString(); | 880 return emptyString(); |
| 881 | 881 |
| 882 if (charactersAreAllASCII(stringStart, length)) | 882 if (charactersAreAllASCII(stringStart, length)) |
| 883 return StringImpl::create(stringStart, length); | 883 return StringImpl::create(stringStart, length); |
| 884 | 884 |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1281 buffer.append('\0'); | 1281 buffer.append('\0'); |
| 1282 return buffer; | 1282 return buffer; |
| 1283 } | 1283 } |
| 1284 | 1284 |
| 1285 Vector<char> asciiDebug(String& string) | 1285 Vector<char> asciiDebug(String& string) |
| 1286 { | 1286 { |
| 1287 return asciiDebug(string.impl()); | 1287 return asciiDebug(string.impl()); |
| 1288 } | 1288 } |
| 1289 | 1289 |
| 1290 #endif | 1290 #endif |
| OLD | NEW |