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 |