Diff
Modified: trunk/Source/WTF/ChangeLog (184866 => 184867)
--- trunk/Source/WTF/ChangeLog 2015-05-26 18:56:42 UTC (rev 184866)
+++ trunk/Source/WTF/ChangeLog 2015-05-26 18:57:00 UTC (rev 184867)
@@ -1,3 +1,29 @@
+2015-05-26 Andreas Kling <[email protected]>
+
+ StringView should have find(StringView, start).
+ <https://webkit.org/b/145351>
+
+ Reviewed by Darin Adler.
+
+ Move the class agnostic guts of StringImpl's find() implementation from StringImpl
+ to StringCommon.h and templatize the code into a findCommon() helper.
+
+ StringImpl::find() and StringView::find() now both call findCommon().
+
+ * wtf/text/StringCommon.h:
+ (WTF::findInner):
+ (WTF::find):
+ (WTF::findCommon):
+ * wtf/text/StringImpl.cpp:
+ (WTF::StringImpl::find):
+ (WTF::findInner): Deleted.
+ * wtf/text/StringImpl.h:
+ (WTF::find): Deleted.
+ * wtf/text/StringView.cpp:
+ (WTF::StringView::find):
+ * wtf/text/StringView.h:
+
+
2015-05-26 Dan Bernstein <[email protected]>
<rdar://problem/21104551> Update build settings
Modified: trunk/Source/WTF/wtf/text/StringCommon.h (184866 => 184867)
--- trunk/Source/WTF/wtf/text/StringCommon.h 2015-05-26 18:56:42 UTC (rev 184866)
+++ trunk/Source/WTF/wtf/text/StringCommon.h 2015-05-26 18:57:00 UTC (rev 184867)
@@ -461,6 +461,90 @@
return findIgnoringASCIICase(source.characters16(), stringToFind.characters16(), startOffset, searchLength, matchLength);
}
+template <typename SearchCharacterType, typename MatchCharacterType>
+ALWAYS_INLINE static size_t findInner(const SearchCharacterType* searchCharacters, const MatchCharacterType* matchCharacters, unsigned index, unsigned searchLength, unsigned matchLength)
+{
+ // Optimization: keep a running hash of the strings,
+ // only call equal() if the hashes match.
+
+ // delta is the number of additional times to test; delta == 0 means test only once.
+ unsigned delta = searchLength - matchLength;
+
+ unsigned searchHash = 0;
+ unsigned matchHash = 0;
+
+ for (unsigned i = 0; i < matchLength; ++i) {
+ searchHash += searchCharacters[i];
+ matchHash += matchCharacters[i];
+ }
+
+ unsigned i = 0;
+ // keep looping until we match
+ while (searchHash != matchHash || !equal(searchCharacters + i, matchCharacters, matchLength)) {
+ if (i == delta)
+ return notFound;
+ searchHash += searchCharacters[i + matchLength];
+ searchHash -= searchCharacters[i];
+ ++i;
+ }
+ return index + i;
}
+template<typename CharacterType>
+inline size_t find(const CharacterType* characters, unsigned length, CharacterType matchCharacter, unsigned index = 0)
+{
+ while (index < length) {
+ if (characters[index] == matchCharacter)
+ return index;
+ ++index;
+ }
+ return notFound;
+}
+
+ALWAYS_INLINE size_t find(const UChar* characters, unsigned length, LChar matchCharacter, unsigned index = 0)
+{
+ return find(characters, length, static_cast<UChar>(matchCharacter), index);
+}
+
+inline size_t find(const LChar* characters, unsigned length, UChar matchCharacter, unsigned index = 0)
+{
+ if (matchCharacter & ~0xFF)
+ return notFound;
+ return find(characters, length, static_cast<LChar>(matchCharacter), index);
+}
+
+template<typename StringClass>
+size_t findCommon(const StringClass& haystack, const StringClass& needle, unsigned start)
+{
+ unsigned needleLength = needle.length();
+
+ if (needleLength == 1) {
+ if (haystack.is8Bit())
+ return WTF::find(haystack.characters8(), haystack.length(), needle[0], start);
+ return WTF::find(haystack.characters16(), haystack.length(), needle[0], start);
+ }
+
+ if (!needleLength)
+ return std::min(start, haystack.length());
+
+ if (start > haystack.length())
+ return notFound;
+ unsigned searchLength = haystack.length() - start;
+ if (needleLength > searchLength)
+ return notFound;
+
+ if (haystack.is8Bit()) {
+ if (needle.is8Bit())
+ return findInner(haystack.characters8() + start, needle.characters8(), start, searchLength, needleLength);
+ return findInner(haystack.characters8() + start, needle.characters16(), start, searchLength, needleLength);
+ }
+
+ if (needle.is8Bit())
+ return findInner(haystack.characters16() + start, needle.characters8(), start, searchLength, needleLength);
+
+ return findInner(haystack.characters16() + start, needle.characters16(), start, searchLength, needleLength);
+}
+
+}
+
#endif // StringCommon_h
Modified: trunk/Source/WTF/wtf/text/StringImpl.cpp (184866 => 184867)
--- trunk/Source/WTF/wtf/text/StringImpl.cpp 2015-05-26 18:56:42 UTC (rev 184866)
+++ trunk/Source/WTF/wtf/text/StringImpl.cpp 2015-05-26 18:57:00 UTC (rev 184867)
@@ -1092,35 +1092,6 @@
return index + i;
}
-template <typename SearchCharacterType, typename MatchCharacterType>
-ALWAYS_INLINE static size_t findInner(const SearchCharacterType* searchCharacters, const MatchCharacterType* matchCharacters, unsigned index, unsigned searchLength, unsigned matchLength)
-{
- // Optimization: keep a running hash of the strings,
- // only call equal() if the hashes match.
-
- // delta is the number of additional times to test; delta == 0 means test only once.
- unsigned delta = searchLength - matchLength;
-
- unsigned searchHash = 0;
- unsigned matchHash = 0;
-
- for (unsigned i = 0; i < matchLength; ++i) {
- searchHash += searchCharacters[i];
- matchHash += matchCharacters[i];
- }
-
- unsigned i = 0;
- // keep looping until we match
- while (searchHash != matchHash || !equal(searchCharacters + i, matchCharacters, matchLength)) {
- if (i == delta)
- return notFound;
- searchHash += searchCharacters[i + matchLength];
- searchHash -= searchCharacters[i];
- ++i;
- }
- return index + i;
-}
-
size_t StringImpl::find(StringImpl* matchString)
{
// Check for null string to match against
@@ -1166,35 +1137,7 @@
if (UNLIKELY(!matchString))
return notFound;
- unsigned matchLength = matchString->length();
-
- // Optimization 1: fast case for strings of length 1.
- if (matchLength == 1) {
- if (is8Bit())
- return WTF::find(characters8(), length(), (*matchString)[0], index);
- return WTF::find(characters16(), length(), (*matchString)[0], index);
- }
-
- if (UNLIKELY(!matchLength))
- return std::min(index, length());
-
- // Check index & matchLength are in range.
- if (index > length())
- return notFound;
- unsigned searchLength = length() - index;
- if (matchLength > searchLength)
- return notFound;
-
- if (is8Bit()) {
- if (matchString->is8Bit())
- return findInner(characters8() + index, matchString->characters8(), index, searchLength, matchLength);
- return findInner(characters8() + index, matchString->characters16(), index, searchLength, matchLength);
- }
-
- if (matchString->is8Bit())
- return findInner(characters16() + index, matchString->characters8(), index, searchLength, matchLength);
-
- return findInner(characters16() + index, matchString->characters16(), index, searchLength, matchLength);
+ return findCommon(*this, *matchString, index);
}
template <typename SearchCharacterType, typename MatchCharacterType>
Modified: trunk/Source/WTF/wtf/text/StringImpl.h (184866 => 184867)
--- trunk/Source/WTF/wtf/text/StringImpl.h 2015-05-26 18:56:42 UTC (rev 184866)
+++ trunk/Source/WTF/wtf/text/StringImpl.h 2015-05-26 18:57:00 UTC (rev 184867)
@@ -33,6 +33,7 @@
#include <wtf/StringHasher.h>
#include <wtf/Vector.h>
#include <wtf/text/ConversionMode.h>
+#include <wtf/text/StringCommon.h>
#if USE(CF)
typedef const struct __CFString * CFStringRef;
@@ -983,29 +984,6 @@
return a ? equalIgnoringASCIICase(*a, b, charactersCount - 1) : false;
}
-template<typename CharacterType>
-inline size_t find(const CharacterType* characters, unsigned length, CharacterType matchCharacter, unsigned index = 0)
-{
- while (index < length) {
- if (characters[index] == matchCharacter)
- return index;
- ++index;
- }
- return notFound;
-}
-
-ALWAYS_INLINE size_t find(const UChar* characters, unsigned length, LChar matchCharacter, unsigned index = 0)
-{
- return find(characters, length, static_cast<UChar>(matchCharacter), index);
-}
-
-inline size_t find(const LChar* characters, unsigned length, UChar matchCharacter, unsigned index = 0)
-{
- if (matchCharacter & ~0xFF)
- return notFound;
- return find(characters, length, static_cast<LChar>(matchCharacter), index);
-}
-
inline size_t find(const LChar* characters, unsigned length, CharacterMatchFunctionPtr matchFunction, unsigned index = 0)
{
while (index < length) {
Modified: trunk/Source/WTF/wtf/text/StringView.cpp (184866 => 184867)
--- trunk/Source/WTF/wtf/text/StringView.cpp 2015-05-26 18:56:42 UTC (rev 184866)
+++ trunk/Source/WTF/wtf/text/StringView.cpp 2015-05-26 18:57:00 UTC (rev 184867)
@@ -96,6 +96,11 @@
return StringImpl::utf8ForCharacters(characters16(), length(), mode);
}
+size_t StringView::find(StringView matchString, unsigned start) const
+{
+ return findCommon(*this, matchString, start);
+}
+
#if CHECK_STRINGVIEW_LIFETIME
// Manage reference count manually so UnderlyingString does not need to be defined in the header.
Modified: trunk/Source/WTF/wtf/text/StringView.h (184866 => 184867)
--- trunk/Source/WTF/wtf/text/StringView.h 2015-05-26 18:56:42 UTC (rev 184866)
+++ trunk/Source/WTF/wtf/text/StringView.h 2015-05-26 18:57:00 UTC (rev 184867)
@@ -109,6 +109,9 @@
StringView substring(unsigned start, unsigned length = std::numeric_limits<unsigned>::max()) const;
size_t find(UChar, unsigned start = 0) const;
+
+ WTF_EXPORT_STRING_API size_t find(StringView, unsigned start) const;
+
WTF_EXPORT_STRING_API size_t findIgnoringASCIICase(const StringView&) const;
WTF_EXPORT_STRING_API size_t findIgnoringASCIICase(const StringView&, unsigned startOffset) const;