| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2001 Dirk Mueller ( mueller@kde.org ) | 4 * (C) 2001 Dirk Mueller ( mueller@kde.org ) |
| 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All r
ights reserved. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All |
| 6 * rights reserved. |
| 6 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) | 7 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) |
| 7 * | 8 * |
| 8 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 11 * License as published by the Free Software Foundation; either |
| 11 * version 2 of the License, or (at your option) any later version. | 12 * version 2 of the License, or (at your option) any later version. |
| 12 * | 13 * |
| 13 * This library is distributed in the hope that it will be useful, | 14 * This library is distributed in the hope that it will be useful, |
| 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 "StringImpl should stay small"); | 61 "StringImpl should stay small"); |
| 61 | 62 |
| 62 #ifdef STRING_STATS | 63 #ifdef STRING_STATS |
| 63 | 64 |
| 64 static Mutex& statsMutex() { | 65 static Mutex& statsMutex() { |
| 65 DEFINE_STATIC_LOCAL(Mutex, mutex, ()); | 66 DEFINE_STATIC_LOCAL(Mutex, mutex, ()); |
| 66 return mutex; | 67 return mutex; |
| 67 } | 68 } |
| 68 | 69 |
| 69 static HashSet<void*>& liveStrings() { | 70 static HashSet<void*>& liveStrings() { |
| 70 // Notice that we can't use HashSet<StringImpl*> because then HashSet would de
dup identical strings. | 71 // Notice that we can't use HashSet<StringImpl*> because then HashSet would |
| 72 // dedup identical strings. |
| 71 DEFINE_STATIC_LOCAL(HashSet<void*>, strings, ()); | 73 DEFINE_STATIC_LOCAL(HashSet<void*>, strings, ()); |
| 72 return strings; | 74 return strings; |
| 73 } | 75 } |
| 74 | 76 |
| 75 void addStringForStats(StringImpl* string) { | 77 void addStringForStats(StringImpl* string) { |
| 76 MutexLocker locker(statsMutex()); | 78 MutexLocker locker(statsMutex()); |
| 77 liveStrings().add(string); | 79 liveStrings().add(string); |
| 78 } | 80 } |
| 79 | 81 |
| 80 void removeStringForStats(StringImpl* string) { | 82 void removeStringForStats(StringImpl* string) { |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 // Do a faster loop for the case where all the characters are ASCII. | 679 // Do a faster loop for the case where all the characters are ASCII. |
| 678 LChar ored = 0; | 680 LChar ored = 0; |
| 679 for (int i = 0; i < length; ++i) { | 681 for (int i = 0; i < length; ++i) { |
| 680 LChar c = characters8()[i]; | 682 LChar c = characters8()[i]; |
| 681 ored |= c; | 683 ored |= c; |
| 682 data8[i] = toASCIIUpper(c); | 684 data8[i] = toASCIIUpper(c); |
| 683 } | 685 } |
| 684 if (!(ored & ~0x7F)) | 686 if (!(ored & ~0x7F)) |
| 685 return newImpl.release(); | 687 return newImpl.release(); |
| 686 | 688 |
| 687 // Do a slower implementation for cases that include non-ASCII Latin-1 chara
cters. | 689 // Do a slower implementation for cases that include non-ASCII Latin-1 |
| 690 // characters. |
| 688 int numberSharpSCharacters = 0; | 691 int numberSharpSCharacters = 0; |
| 689 | 692 |
| 690 // There are two special cases. | 693 // There are two special cases. |
| 691 // 1. latin-1 characters when converted to upper case are 16 bit characters
. | 694 // 1. latin-1 characters when converted to upper case are 16 bit |
| 695 // characters. |
| 692 // 2. Lower case sharp-S converts to "SS" (two characters) | 696 // 2. Lower case sharp-S converts to "SS" (two characters) |
| 693 for (int32_t i = 0; i < length; ++i) { | 697 for (int32_t i = 0; i < length; ++i) { |
| 694 LChar c = characters8()[i]; | 698 LChar c = characters8()[i]; |
| 695 if (UNLIKELY(c == smallLetterSharpSCharacter)) | 699 if (UNLIKELY(c == smallLetterSharpSCharacter)) |
| 696 ++numberSharpSCharacters; | 700 ++numberSharpSCharacters; |
| 697 UChar upper = static_cast<UChar>(Unicode::toUpper(c)); | 701 UChar upper = static_cast<UChar>(Unicode::toUpper(c)); |
| 698 if (UNLIKELY(upper > 0xff)) { | 702 if (UNLIKELY(upper > 0xff)) { |
| 699 // Since this upper-cased character does not fit in an 8-bit string, we
need to take the 16-bit path. | 703 // Since this upper-cased character does not fit in an 8-bit string, we |
| 704 // need to take the 16-bit path. |
| 700 goto upconvert; | 705 goto upconvert; |
| 701 } | 706 } |
| 702 data8[i] = static_cast<LChar>(upper); | 707 data8[i] = static_cast<LChar>(upper); |
| 703 } | 708 } |
| 704 | 709 |
| 705 if (!numberSharpSCharacters) | 710 if (!numberSharpSCharacters) |
| 706 return newImpl.release(); | 711 return newImpl.release(); |
| 707 | 712 |
| 708 // We have numberSSCharacters sharp-s characters, but none of the other spec
ial characters. | 713 // We have numberSSCharacters sharp-s characters, but none of the other |
| 714 // special characters. |
| 709 newImpl = createUninitialized(m_length + numberSharpSCharacters, data8); | 715 newImpl = createUninitialized(m_length + numberSharpSCharacters, data8); |
| 710 | 716 |
| 711 LChar* dest = data8; | 717 LChar* dest = data8; |
| 712 | 718 |
| 713 for (int32_t i = 0; i < length; ++i) { | 719 for (int32_t i = 0; i < length; ++i) { |
| 714 LChar c = characters8()[i]; | 720 LChar c = characters8()[i]; |
| 715 if (c == smallLetterSharpSCharacter) { | 721 if (c == smallLetterSharpSCharacter) { |
| 716 *dest++ = 'S'; | 722 *dest++ = 'S'; |
| 717 *dest++ = 'S'; | 723 *dest++ = 'S'; |
| 718 } else { | 724 } else { |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 891 | 897 |
| 892 for (int32_t i = 0; i < length; ++i) { | 898 for (int32_t i = 0; i < length; ++i) { |
| 893 LChar c = characters8()[i]; | 899 LChar c = characters8()[i]; |
| 894 data[i] = toASCIILower(c); | 900 data[i] = toASCIILower(c); |
| 895 ored |= c; | 901 ored |= c; |
| 896 } | 902 } |
| 897 | 903 |
| 898 if (!(ored & ~0x7F)) | 904 if (!(ored & ~0x7F)) |
| 899 return newImpl.release(); | 905 return newImpl.release(); |
| 900 | 906 |
| 901 // Do a slower implementation for cases that include non-ASCII Latin-1 chara
cters. | 907 // Do a slower implementation for cases that include non-ASCII Latin-1 |
| 908 // characters. |
| 902 for (int32_t i = 0; i < length; ++i) | 909 for (int32_t i = 0; i < length; ++i) |
| 903 data[i] = static_cast<LChar>(Unicode::toLower(characters8()[i])); | 910 data[i] = static_cast<LChar>(Unicode::toLower(characters8()[i])); |
| 904 | 911 |
| 905 return newImpl.release(); | 912 return newImpl.release(); |
| 906 } | 913 } |
| 907 | 914 |
| 908 // Do a faster loop for the case where all the characters are ASCII. | 915 // Do a faster loop for the case where all the characters are ASCII. |
| 909 UChar* data; | 916 UChar* data; |
| 910 RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); | 917 RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); |
| 911 UChar ored = 0; | 918 UChar ored = 0; |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1260 template <typename SearchCharacterType, typename MatchCharacterType> | 1267 template <typename SearchCharacterType, typename MatchCharacterType> |
| 1261 ALWAYS_INLINE static size_t findInternal( | 1268 ALWAYS_INLINE static size_t findInternal( |
| 1262 const SearchCharacterType* searchCharacters, | 1269 const SearchCharacterType* searchCharacters, |
| 1263 const MatchCharacterType* matchCharacters, | 1270 const MatchCharacterType* matchCharacters, |
| 1264 unsigned index, | 1271 unsigned index, |
| 1265 unsigned searchLength, | 1272 unsigned searchLength, |
| 1266 unsigned matchLength) { | 1273 unsigned matchLength) { |
| 1267 // Optimization: keep a running hash of the strings, | 1274 // Optimization: keep a running hash of the strings, |
| 1268 // only call equal() if the hashes match. | 1275 // only call equal() if the hashes match. |
| 1269 | 1276 |
| 1270 // delta is the number of additional times to test; delta == 0 means test only
once. | 1277 // delta is the number of additional times to test; delta == 0 means test only |
| 1278 // once. |
| 1271 unsigned delta = searchLength - matchLength; | 1279 unsigned delta = searchLength - matchLength; |
| 1272 | 1280 |
| 1273 unsigned searchHash = 0; | 1281 unsigned searchHash = 0; |
| 1274 unsigned matchHash = 0; | 1282 unsigned matchHash = 0; |
| 1275 | 1283 |
| 1276 for (unsigned i = 0; i < matchLength; ++i) { | 1284 for (unsigned i = 0; i < matchLength; ++i) { |
| 1277 searchHash += searchCharacters[i]; | 1285 searchHash += searchCharacters[i]; |
| 1278 matchHash += matchCharacters[i]; | 1286 matchHash += matchCharacters[i]; |
| 1279 } | 1287 } |
| 1280 | 1288 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1328 searchLength, matchLength); | 1336 searchLength, matchLength); |
| 1329 } | 1337 } |
| 1330 | 1338 |
| 1331 template <typename SearchCharacterType, typename MatchCharacterType> | 1339 template <typename SearchCharacterType, typename MatchCharacterType> |
| 1332 ALWAYS_INLINE static size_t findIgnoringCaseInternal( | 1340 ALWAYS_INLINE static size_t findIgnoringCaseInternal( |
| 1333 const SearchCharacterType* searchCharacters, | 1341 const SearchCharacterType* searchCharacters, |
| 1334 const MatchCharacterType* matchCharacters, | 1342 const MatchCharacterType* matchCharacters, |
| 1335 unsigned index, | 1343 unsigned index, |
| 1336 unsigned searchLength, | 1344 unsigned searchLength, |
| 1337 unsigned matchLength) { | 1345 unsigned matchLength) { |
| 1338 // delta is the number of additional times to test; delta == 0 means test only
once. | 1346 // delta is the number of additional times to test; delta == 0 means test only |
| 1347 // once. |
| 1339 unsigned delta = searchLength - matchLength; | 1348 unsigned delta = searchLength - matchLength; |
| 1340 | 1349 |
| 1341 unsigned i = 0; | 1350 unsigned i = 0; |
| 1342 // keep looping until we match | 1351 // keep looping until we match |
| 1343 while ( | 1352 while ( |
| 1344 !equalIgnoringCase(searchCharacters + i, matchCharacters, matchLength)) { | 1353 !equalIgnoringCase(searchCharacters + i, matchCharacters, matchLength)) { |
| 1345 if (i == delta) | 1354 if (i == delta) |
| 1346 return kNotFound; | 1355 return kNotFound; |
| 1347 ++i; | 1356 ++i; |
| 1348 } | 1357 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1383 searchLength, matchLength); | 1392 searchLength, matchLength); |
| 1384 } | 1393 } |
| 1385 | 1394 |
| 1386 template <typename SearchCharacterType, typename MatchCharacterType> | 1395 template <typename SearchCharacterType, typename MatchCharacterType> |
| 1387 ALWAYS_INLINE static size_t findIgnoringASCIICaseInternal( | 1396 ALWAYS_INLINE static size_t findIgnoringASCIICaseInternal( |
| 1388 const SearchCharacterType* searchCharacters, | 1397 const SearchCharacterType* searchCharacters, |
| 1389 const MatchCharacterType* matchCharacters, | 1398 const MatchCharacterType* matchCharacters, |
| 1390 unsigned index, | 1399 unsigned index, |
| 1391 unsigned searchLength, | 1400 unsigned searchLength, |
| 1392 unsigned matchLength) { | 1401 unsigned matchLength) { |
| 1393 // delta is the number of additional times to test; delta == 0 means test only
once. | 1402 // delta is the number of additional times to test; delta == 0 means test only |
| 1403 // once. |
| 1394 unsigned delta = searchLength - matchLength; | 1404 unsigned delta = searchLength - matchLength; |
| 1395 | 1405 |
| 1396 unsigned i = 0; | 1406 unsigned i = 0; |
| 1397 // keep looping until we match | 1407 // keep looping until we match |
| 1398 while (!equalIgnoringASCIICase(searchCharacters + i, matchCharacters, | 1408 while (!equalIgnoringASCIICase(searchCharacters + i, matchCharacters, |
| 1399 matchLength)) { | 1409 matchLength)) { |
| 1400 if (i == delta) | 1410 if (i == delta) |
| 1401 return kNotFound; | 1411 return kNotFound; |
| 1402 ++i; | 1412 ++i; |
| 1403 } | 1413 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1447 template <typename SearchCharacterType, typename MatchCharacterType> | 1457 template <typename SearchCharacterType, typename MatchCharacterType> |
| 1448 ALWAYS_INLINE static size_t reverseFindInternal( | 1458 ALWAYS_INLINE static size_t reverseFindInternal( |
| 1449 const SearchCharacterType* searchCharacters, | 1459 const SearchCharacterType* searchCharacters, |
| 1450 const MatchCharacterType* matchCharacters, | 1460 const MatchCharacterType* matchCharacters, |
| 1451 unsigned index, | 1461 unsigned index, |
| 1452 unsigned length, | 1462 unsigned length, |
| 1453 unsigned matchLength) { | 1463 unsigned matchLength) { |
| 1454 // Optimization: keep a running hash of the strings, | 1464 // Optimization: keep a running hash of the strings, |
| 1455 // only call equal if the hashes match. | 1465 // only call equal if the hashes match. |
| 1456 | 1466 |
| 1457 // delta is the number of additional times to test; delta == 0 means test only
once. | 1467 // delta is the number of additional times to test; delta == 0 means test only |
| 1468 // once. |
| 1458 unsigned delta = min(index, length - matchLength); | 1469 unsigned delta = min(index, length - matchLength); |
| 1459 | 1470 |
| 1460 unsigned searchHash = 0; | 1471 unsigned searchHash = 0; |
| 1461 unsigned matchHash = 0; | 1472 unsigned matchHash = 0; |
| 1462 for (unsigned i = 0; i < matchLength; ++i) { | 1473 for (unsigned i = 0; i < matchLength; ++i) { |
| 1463 searchHash += searchCharacters[delta + i]; | 1474 searchHash += searchCharacters[delta + i]; |
| 1464 matchHash += matchCharacters[i]; | 1475 matchHash += matchCharacters[i]; |
| 1465 } | 1476 } |
| 1466 | 1477 |
| 1467 // keep looping until we match | 1478 // keep looping until we match |
| (...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2174 } else if (localeIdMatchesLang(localeIdentifier, "lt")) { | 2185 } else if (localeIdMatchesLang(localeIdentifier, "lt")) { |
| 2175 // TODO(rob.buis) implement upper-casing rules for lt | 2186 // TODO(rob.buis) implement upper-casing rules for lt |
| 2176 // like in StringImpl::upper(locale). | 2187 // like in StringImpl::upper(locale). |
| 2177 } | 2188 } |
| 2178 } | 2189 } |
| 2179 | 2190 |
| 2180 return toUpper(c); | 2191 return toUpper(c); |
| 2181 } | 2192 } |
| 2182 | 2193 |
| 2183 } // namespace WTF | 2194 } // namespace WTF |
| OLD | NEW |