Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(212)

Side by Side Diff: third_party/WebKit/Source/wtf/text/StringImpl.cpp

Issue 2225173002: Use StringView for String::find. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add missing null check. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 r ights reserved.
6 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) 6 * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 1144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 return true; 1155 return true;
1156 } 1156 }
1157 1157
1158 size_t StringImpl::find(CharacterMatchFunctionPtr matchFunction, unsigned start) 1158 size_t StringImpl::find(CharacterMatchFunctionPtr matchFunction, unsigned start)
1159 { 1159 {
1160 if (is8Bit()) 1160 if (is8Bit())
1161 return WTF::find(characters8(), m_length, matchFunction, start); 1161 return WTF::find(characters8(), m_length, matchFunction, start);
1162 return WTF::find(characters16(), m_length, matchFunction, start); 1162 return WTF::find(characters16(), m_length, matchFunction, start);
1163 } 1163 }
1164 1164
1165 size_t StringImpl::find(const LChar* matchString, unsigned index)
1166 {
1167 // Check for null or empty string to match against
1168 if (!matchString)
1169 return kNotFound;
1170 size_t matchStringLength = strlen(reinterpret_cast<const char*>(matchString) );
1171 RELEASE_ASSERT(matchStringLength <= numeric_limits<unsigned>::max());
1172 unsigned matchLength = matchStringLength;
1173 if (!matchLength)
1174 return min(index, length());
1175
1176 // Optimization 1: fast case for strings of length 1.
1177 if (matchLength == 1)
1178 return WTF::find(characters16(), length(), *matchString, index);
1179
1180 // Check index & matchLength are in range.
1181 if (index > length())
1182 return kNotFound;
1183 unsigned searchLength = length() - index;
1184 if (matchLength > searchLength)
1185 return kNotFound;
1186 // delta is the number of additional times to test; delta == 0 means test on ly once.
1187 unsigned delta = searchLength - matchLength;
1188
1189 const UChar* searchCharacters = characters16() + index;
1190
1191 // Optimization 2: keep a running hash of the strings,
1192 // only call equal if the hashes match.
1193 unsigned searchHash = 0;
1194 unsigned matchHash = 0;
1195 for (unsigned i = 0; i < matchLength; ++i) {
1196 searchHash += searchCharacters[i];
1197 matchHash += matchString[i];
1198 }
1199
1200 unsigned i = 0;
1201 // keep looping until we match
1202 while (searchHash != matchHash || !equal(searchCharacters + i, matchString, matchLength)) {
1203 if (i == delta)
1204 return kNotFound;
1205 searchHash += searchCharacters[i + matchLength];
1206 searchHash -= searchCharacters[i];
1207 ++i;
1208 }
1209 return index + i;
1210 }
1211
1212 template<typename CharType>
1213 ALWAYS_INLINE size_t findIgnoringCaseInternal(const CharType* searchCharacters, const LChar* matchString, unsigned index, unsigned searchLength, unsigned matchL ength)
1214 {
1215 // delta is the number of additional times to test; delta == 0 means test on ly once.
1216 unsigned delta = searchLength - matchLength;
1217
1218 unsigned i = 0;
1219 while (!equalIgnoringCase(searchCharacters + i, matchString, matchLength)) {
1220 if (i == delta)
1221 return kNotFound;
1222 ++i;
1223 }
1224 return index + i;
1225 }
1226
1227 size_t StringImpl::findIgnoringCase(const LChar* matchString, unsigned index)
1228 {
1229 // Check for null or empty string to match against
1230 if (!matchString)
1231 return kNotFound;
1232 size_t matchStringLength = strlen(reinterpret_cast<const char*>(matchString) );
1233 RELEASE_ASSERT(matchStringLength <= numeric_limits<unsigned>::max());
1234 unsigned matchLength = matchStringLength;
1235 if (!matchLength)
1236 return min(index, length());
1237
1238 // Check index & matchLength are in range.
1239 if (index > length())
1240 return kNotFound;
1241 unsigned searchLength = length() - index;
1242 if (matchLength > searchLength)
1243 return kNotFound;
1244
1245 if (is8Bit())
1246 return findIgnoringCaseInternal(characters8() + index, matchString, inde x, searchLength, matchLength);
1247 return findIgnoringCaseInternal(characters16() + index, matchString, index, searchLength, matchLength);
1248 }
1249
1250 template <typename SearchCharacterType, typename MatchCharacterType> 1165 template <typename SearchCharacterType, typename MatchCharacterType>
1251 ALWAYS_INLINE static size_t findInternal(const SearchCharacterType* searchCharac ters, const MatchCharacterType* matchCharacters, unsigned index, unsigned search Length, unsigned matchLength) 1166 ALWAYS_INLINE static size_t findInternal(const SearchCharacterType* searchCharac ters, const MatchCharacterType* matchCharacters, unsigned index, unsigned search Length, unsigned matchLength)
1252 { 1167 {
1253 // Optimization: keep a running hash of the strings, 1168 // Optimization: keep a running hash of the strings,
1254 // only call equal() if the hashes match. 1169 // only call equal() if the hashes match.
1255 1170
1256 // delta is the number of additional times to test; delta == 0 means test on ly once. 1171 // delta is the number of additional times to test; delta == 0 means test on ly once.
1257 unsigned delta = searchLength - matchLength; 1172 unsigned delta = searchLength - matchLength;
1258 1173
1259 unsigned searchHash = 0; 1174 unsigned searchHash = 0;
1260 unsigned matchHash = 0; 1175 unsigned matchHash = 0;
1261 1176
1262 for (unsigned i = 0; i < matchLength; ++i) { 1177 for (unsigned i = 0; i < matchLength; ++i) {
1263 searchHash += searchCharacters[i]; 1178 searchHash += searchCharacters[i];
1264 matchHash += matchCharacters[i]; 1179 matchHash += matchCharacters[i];
1265 } 1180 }
1266 1181
1267 unsigned i = 0; 1182 unsigned i = 0;
1268 // keep looping until we match 1183 // keep looping until we match
1269 while (searchHash != matchHash || !equal(searchCharacters + i, matchCharacte rs, matchLength)) { 1184 while (searchHash != matchHash || !equal(searchCharacters + i, matchCharacte rs, matchLength)) {
1270 if (i == delta) 1185 if (i == delta)
1271 return kNotFound; 1186 return kNotFound;
1272 searchHash += searchCharacters[i + matchLength]; 1187 searchHash += searchCharacters[i + matchLength];
1273 searchHash -= searchCharacters[i]; 1188 searchHash -= searchCharacters[i];
1274 ++i; 1189 ++i;
1275 } 1190 }
1276 return index + i; 1191 return index + i;
1277 } 1192 }
1278 1193
1279 size_t StringImpl::find(StringImpl* matchString) 1194 size_t StringImpl::find(const StringView& matchString, unsigned index)
1280 { 1195 {
1281 // Check for null string to match against 1196 if (UNLIKELY(matchString.isNull()))
1282 if (UNLIKELY(!matchString))
1283 return kNotFound;
1284 unsigned matchLength = matchString->length();
1285
1286 // Optimization 1: fast case for strings of length 1.
1287 if (matchLength == 1) {
1288 if (is8Bit()) {
1289 if (matchString->is8Bit())
1290 return WTF::find(characters8(), length(), matchString->character s8()[0]);
1291 return WTF::find(characters8(), length(), matchString->characters16( )[0]);
1292 }
1293 if (matchString->is8Bit())
1294 return WTF::find(characters16(), length(), matchString->characters8( )[0]);
1295 return WTF::find(characters16(), length(), matchString->characters16()[0 ]);
1296 }
1297
1298 // Check matchLength is in range.
1299 if (matchLength > length())
1300 return kNotFound; 1197 return kNotFound;
1301 1198
1302 // Check for empty string to match against 1199 unsigned matchLength = matchString.length();
1303 if (UNLIKELY(!matchLength))
1304 return 0;
1305
1306 if (is8Bit()) {
1307 if (matchString->is8Bit())
1308 return findInternal(characters8(), matchString->characters8(), 0, le ngth(), matchLength);
1309 return findInternal(characters8(), matchString->characters16(), 0, lengt h(), matchLength);
1310 }
1311
1312 if (matchString->is8Bit())
1313 return findInternal(characters16(), matchString->characters8(), 0, lengt h(), matchLength);
1314
1315 return findInternal(characters16(), matchString->characters16(), 0, length() , matchLength);
1316 }
1317
1318 size_t StringImpl::find(StringImpl* matchString, unsigned index)
1319 {
1320 // Check for null or empty string to match against
1321 if (UNLIKELY(!matchString))
1322 return kNotFound;
1323
1324 unsigned matchLength = matchString->length();
1325 1200
1326 // Optimization 1: fast case for strings of length 1. 1201 // Optimization 1: fast case for strings of length 1.
1327 if (matchLength == 1) { 1202 if (matchLength == 1) {
1328 if (is8Bit()) 1203 if (is8Bit())
1329 return WTF::find(characters8(), length(), (*matchString)[0], index); 1204 return WTF::find(characters8(), length(), matchString[0], index);
1330 return WTF::find(characters16(), length(), (*matchString)[0], index); 1205 return WTF::find(characters16(), length(), matchString[0], index);
1331 } 1206 }
1332 1207
1333 if (UNLIKELY(!matchLength)) 1208 if (UNLIKELY(!matchLength))
1334 return min(index, length()); 1209 return min(index, length());
1335 1210
1336 // Check index & matchLength are in range. 1211 // Check index & matchLength are in range.
1337 if (index > length()) 1212 if (index > length())
1338 return kNotFound; 1213 return kNotFound;
1339 unsigned searchLength = length() - index; 1214 unsigned searchLength = length() - index;
1340 if (matchLength > searchLength) 1215 if (matchLength > searchLength)
1341 return kNotFound; 1216 return kNotFound;
1342 1217
1343 if (is8Bit()) { 1218 if (is8Bit()) {
1344 if (matchString->is8Bit()) 1219 if (matchString.is8Bit())
1345 return findInternal(characters8() + index, matchString->characters8( ), index, searchLength, matchLength); 1220 return findInternal(characters8() + index, matchString.characters8() , index, searchLength, matchLength);
1346 return findInternal(characters8() + index, matchString->characters16(), index, searchLength, matchLength); 1221 return findInternal(characters8() + index, matchString.characters16(), i ndex, searchLength, matchLength);
1347 } 1222 }
1348 1223 if (matchString.is8Bit())
1349 if (matchString->is8Bit()) 1224 return findInternal(characters16() + index, matchString.characters8(), i ndex, searchLength, matchLength);
1350 return findInternal(characters16() + index, matchString->characters8(), index, searchLength, matchLength); 1225 return findInternal(characters16() + index, matchString.characters16(), inde x, searchLength, matchLength);
1351
1352 return findInternal(characters16() + index, matchString->characters16(), ind ex, searchLength, matchLength);
1353 } 1226 }
1354 1227
1355 template <typename SearchCharacterType, typename MatchCharacterType> 1228 template <typename SearchCharacterType, typename MatchCharacterType>
1356 ALWAYS_INLINE static size_t findIgnoringCaseInner(const SearchCharacterType* sea rchCharacters, const MatchCharacterType* matchCharacters, unsigned index, unsign ed searchLength, unsigned matchLength) 1229 ALWAYS_INLINE static size_t findIgnoringCaseInternal(const SearchCharacterType* searchCharacters, const MatchCharacterType* matchCharacters, unsigned index, uns igned searchLength, unsigned matchLength)
1357 { 1230 {
1358 // delta is the number of additional times to test; delta == 0 means test on ly once. 1231 // delta is the number of additional times to test; delta == 0 means test on ly once.
1359 unsigned delta = searchLength - matchLength; 1232 unsigned delta = searchLength - matchLength;
1360 1233
1361 unsigned i = 0; 1234 unsigned i = 0;
1362 // keep looping until we match 1235 // keep looping until we match
1363 while (!equalIgnoringCase(searchCharacters + i, matchCharacters, matchLength )) { 1236 while (!equalIgnoringCase(searchCharacters + i, matchCharacters, matchLength )) {
1364 if (i == delta) 1237 if (i == delta)
1365 return kNotFound; 1238 return kNotFound;
1366 ++i; 1239 ++i;
1367 } 1240 }
1368 return index + i; 1241 return index + i;
1369 } 1242 }
1370 1243
1371 size_t StringImpl::findIgnoringCase(StringImpl* matchString, unsigned index) 1244 size_t StringImpl::findIgnoringCase(const StringView& matchString, unsigned inde x)
1372 { 1245 {
1373 // Check for null or empty string to match against 1246 if (UNLIKELY(matchString.isNull()))
1374 if (!matchString)
1375 return kNotFound; 1247 return kNotFound;
1376 unsigned matchLength = matchString->length(); 1248
1249 unsigned matchLength = matchString.length();
1377 if (!matchLength) 1250 if (!matchLength)
1378 return min(index, length()); 1251 return min(index, length());
1379 1252
1380 // Check index & matchLength are in range. 1253 // Check index & matchLength are in range.
1381 if (index > length()) 1254 if (index > length())
1382 return kNotFound; 1255 return kNotFound;
1383 unsigned searchLength = length() - index; 1256 unsigned searchLength = length() - index;
1384 if (matchLength > searchLength) 1257 if (matchLength > searchLength)
1385 return kNotFound; 1258 return kNotFound;
1386 1259
1387 if (is8Bit()) { 1260 if (is8Bit()) {
1388 if (matchString->is8Bit()) 1261 if (matchString.is8Bit())
1389 return findIgnoringCaseInner(characters8() + index, matchString->cha racters8(), index, searchLength, matchLength); 1262 return findIgnoringCaseInternal(characters8() + index, matchString.c haracters8(), index, searchLength, matchLength);
1390 return findIgnoringCaseInner(characters8() + index, matchString->charact ers16(), index, searchLength, matchLength); 1263 return findIgnoringCaseInternal(characters8() + index, matchString.chara cters16(), index, searchLength, matchLength);
1391 } 1264 }
1392 1265 if (matchString.is8Bit())
1393 if (matchString->is8Bit()) 1266 return findIgnoringCaseInternal(characters16() + index, matchString.char acters8(), index, searchLength, matchLength);
1394 return findIgnoringCaseInner(characters16() + index, matchString->charac ters8(), index, searchLength, matchLength); 1267 return findIgnoringCaseInternal(characters16() + index, matchString.characte rs16(), index, searchLength, matchLength);
1395
1396 return findIgnoringCaseInner(characters16() + index, matchString->characters 16(), index, searchLength, matchLength);
1397 } 1268 }
1398 1269
1399 template <typename SearchCharacterType, typename MatchCharacterType> 1270 template <typename SearchCharacterType, typename MatchCharacterType>
1400 ALWAYS_INLINE static size_t findIgnoringASCIICaseInner(const SearchCharacterType * searchCharacters, const MatchCharacterType* matchCharacters, unsigned index, u nsigned searchLength, unsigned matchLength) 1271 ALWAYS_INLINE static size_t findIgnoringASCIICaseInternal(const SearchCharacterT ype* searchCharacters, const MatchCharacterType* matchCharacters, unsigned index , unsigned searchLength, unsigned matchLength)
1401 { 1272 {
1402 // delta is the number of additional times to test; delta == 0 means test on ly once. 1273 // delta is the number of additional times to test; delta == 0 means test on ly once.
1403 unsigned delta = searchLength - matchLength; 1274 unsigned delta = searchLength - matchLength;
1404 1275
1405 unsigned i = 0; 1276 unsigned i = 0;
1406 // keep looping until we match 1277 // keep looping until we match
1407 while (!equalIgnoringASCIICase(searchCharacters + i, matchCharacters, matchL ength)) { 1278 while (!equalIgnoringASCIICase(searchCharacters + i, matchCharacters, matchL ength)) {
1408 if (i == delta) 1279 if (i == delta)
1409 return kNotFound; 1280 return kNotFound;
1410 ++i; 1281 ++i;
1411 } 1282 }
1412 return index + i; 1283 return index + i;
1413 } 1284 }
1414 1285
1415 size_t StringImpl::findIgnoringASCIICase(StringImpl* matchString, unsigned index ) 1286 size_t StringImpl::findIgnoringASCIICase(const StringView& matchString, unsigned index)
1416 { 1287 {
1417 // Check for null or empty string to match against 1288 if (UNLIKELY(matchString.isNull()))
1418 if (!matchString)
1419 return kNotFound; 1289 return kNotFound;
1420 unsigned matchLength = matchString->length(); 1290
1291 unsigned matchLength = matchString.length();
1421 if (!matchLength) 1292 if (!matchLength)
1422 return min(index, length()); 1293 return min(index, length());
1423 1294
1424 // Check index & matchLength are in range. 1295 // Check index & matchLength are in range.
1425 if (index > length()) 1296 if (index > length())
1426 return kNotFound; 1297 return kNotFound;
1427 unsigned searchLength = length() - index; 1298 unsigned searchLength = length() - index;
1428 if (matchLength > searchLength) 1299 if (matchLength > searchLength)
1429 return kNotFound; 1300 return kNotFound;
1430 1301
1431 if (is8Bit()) { 1302 if (is8Bit()) {
1432 const LChar* searchStart = characters8() + index; 1303 if (matchString.is8Bit())
1433 if (matchString->is8Bit()) 1304 return findIgnoringASCIICaseInternal(characters8() + index, matchStr ing.characters8(), index, searchLength, matchLength);
1434 return findIgnoringASCIICaseInner(searchStart, matchString->characte rs8(), index, searchLength, matchLength); 1305 return findIgnoringASCIICaseInternal(characters8() + index, matchString. characters16(), index, searchLength, matchLength);
1435 return findIgnoringASCIICaseInner(searchStart, matchString->characters16 (), index, searchLength, matchLength);
1436 } 1306 }
1437 1307 if (matchString.is8Bit())
1438 const UChar* searchStart = characters16() + index; 1308 return findIgnoringASCIICaseInternal(characters16() + index, matchString .characters8(), index, searchLength, matchLength);
1439 if (matchString->is8Bit()) 1309 return findIgnoringASCIICaseInternal(characters16() + index, matchString.cha racters16(), index, searchLength, matchLength);
1440 return findIgnoringASCIICaseInner(searchStart, matchString->characters8( ), index, searchLength, matchLength);
1441 return findIgnoringASCIICaseInner(searchStart, matchString->characters16(), index, searchLength, matchLength);
1442 } 1310 }
1443 1311
1444 size_t StringImpl::reverseFind(UChar c, unsigned index) 1312 size_t StringImpl::reverseFind(UChar c, unsigned index)
1445 { 1313 {
1446 if (is8Bit()) 1314 if (is8Bit())
1447 return WTF::reverseFind(characters8(), m_length, c, index); 1315 return WTF::reverseFind(characters8(), m_length, c, index);
1448 return WTF::reverseFind(characters16(), m_length, c, index); 1316 return WTF::reverseFind(characters16(), m_length, c, index);
1449 } 1317 }
1450 1318
1451 template <typename SearchCharacterType, typename MatchCharacterType> 1319 template <typename SearchCharacterType, typename MatchCharacterType>
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
2145 } else if (localeIdMatchesLang(localeIdentifier, "lt")) { 2013 } else if (localeIdMatchesLang(localeIdentifier, "lt")) {
2146 // TODO(rob.buis) implement upper-casing rules for lt 2014 // TODO(rob.buis) implement upper-casing rules for lt
2147 // like in StringImpl::upper(locale). 2015 // like in StringImpl::upper(locale).
2148 } 2016 }
2149 } 2017 }
2150 2018
2151 return toUpper(c); 2019 return toUpper(c);
2152 } 2020 }
2153 2021
2154 } // namespace WTF 2022 } // namespace WTF
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/text/StringImpl.h ('k') | third_party/WebKit/Source/wtf/text/WTFString.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698