diff options
Diffstat (limited to 'Source/WebCore/platform/text/SegmentedString.cpp')
-rw-r--r-- | Source/WebCore/platform/text/SegmentedString.cpp | 148 |
1 files changed, 126 insertions, 22 deletions
diff --git a/Source/WebCore/platform/text/SegmentedString.cpp b/Source/WebCore/platform/text/SegmentedString.cpp index 63373ba7a..9edb83c92 100644 --- a/Source/WebCore/platform/text/SegmentedString.cpp +++ b/Source/WebCore/platform/text/SegmentedString.cpp @@ -28,13 +28,17 @@ SegmentedString::SegmentedString(const SegmentedString& other) , m_currentString(other.m_currentString) , m_substrings(other.m_substrings) , m_closed(other.m_closed) + , m_empty(other.m_empty) + , m_fastPathFlags(other.m_fastPathFlags) + , m_advanceFunc(other.m_advanceFunc) + , m_advanceAndUpdateLineNumberFunc(other.m_advanceAndUpdateLineNumberFunc) { - if (other.m_currentChar == &other.m_pushedChar1) - m_currentChar = &m_pushedChar1; - else if (other.m_currentChar == &other.m_pushedChar2) - m_currentChar = &m_pushedChar2; + if (m_pushedChar2) + m_currentChar = m_pushedChar2; + else if (m_pushedChar1) + m_currentChar = m_pushedChar1; else - m_currentChar = other.m_currentChar; + m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0; } const SegmentedString& SegmentedString::operator=(const SegmentedString& other) @@ -43,17 +47,23 @@ const SegmentedString& SegmentedString::operator=(const SegmentedString& other) m_pushedChar2 = other.m_pushedChar2; m_currentString = other.m_currentString; m_substrings = other.m_substrings; - if (other.m_currentChar == &other.m_pushedChar1) - m_currentChar = &m_pushedChar1; - else if (other.m_currentChar == &other.m_pushedChar2) - m_currentChar = &m_pushedChar2; + if (m_pushedChar2) + m_currentChar = m_pushedChar2; + else if (m_pushedChar1) + m_currentChar = m_pushedChar1; else - m_currentChar = other.m_currentChar; + m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0; + m_closed = other.m_closed; + m_empty = other.m_empty; + m_fastPathFlags = other.m_fastPathFlags; m_numberOfCharactersConsumedPriorToCurrentString = other.m_numberOfCharactersConsumedPriorToCurrentString; m_numberOfCharactersConsumedPriorToCurrentLine = other.m_numberOfCharactersConsumedPriorToCurrentLine; m_currentLine = other.m_currentLine; + m_advanceFunc = other.m_advanceFunc; + m_advanceAndUpdateLineNumberFunc = other.m_advanceAndUpdateLineNumberFunc; + return *this; } @@ -96,6 +106,10 @@ void SegmentedString::clear() m_currentLine = 0; m_substrings.clear(); m_closed = false; + m_empty = true; + m_fastPathFlags = NoFastPath; + m_advanceFunc = &SegmentedString::advanceEmpty; + m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; } void SegmentedString::append(const SegmentedSubstring& s) @@ -107,8 +121,10 @@ void SegmentedString::append(const SegmentedSubstring& s) if (!m_currentString.m_length) { m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed(); m_currentString = s; + updateAdvanceFunctionPointers(); } else m_substrings.append(s); + m_empty = false; } void SegmentedString::prepend(const SegmentedSubstring& s) @@ -125,13 +141,16 @@ void SegmentedString::prepend(const SegmentedSubstring& s) // cases in the future. m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed(); m_numberOfCharactersConsumedPriorToCurrentString -= s.m_length; - if (!m_currentString.m_length) + if (!m_currentString.m_length) { m_currentString = s; - else { + updateAdvanceFunctionPointers(); + } else { // Shift our m_currentString into our list. m_substrings.prepend(m_currentString); m_currentString = s; + updateAdvanceFunctionPointers(); } + m_empty = false; } void SegmentedString::close() @@ -152,7 +171,7 @@ void SegmentedString::append(const SegmentedString& s) for (; it != e; ++it) append(*it); } - m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current; + m_currentChar = m_pushedChar1 ? m_pushedChar1 : (m_currentString.m_length ? m_currentString.getCurrentChar() : 0); } void SegmentedString::prepend(const SegmentedString& s) @@ -166,7 +185,7 @@ void SegmentedString::prepend(const SegmentedString& s) prepend(*it); } prepend(s.m_currentString); - m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current; + m_currentChar = m_pushedChar1 ? m_pushedChar1 : (m_currentString.m_length ? m_currentString.getCurrentChar() : 0); } void SegmentedString::advanceSubstring() @@ -178,8 +197,14 @@ void SegmentedString::advanceSubstring() // string, we now account for those characters as part of the current // string, not as part of "prior to current string." m_numberOfCharactersConsumedPriorToCurrentString -= m_currentString.numberOfCharactersConsumed(); - } else + updateAdvanceFunctionPointers(); + } else { m_currentString.clear(); + m_empty = true; + m_fastPathFlags = NoFastPath; + m_advanceFunc = &SegmentedString::advanceEmpty; + m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; + } } String SegmentedString::toString() const @@ -204,22 +229,72 @@ void SegmentedString::advance(unsigned count, UChar* consumedCharacters) { ASSERT(count <= length()); for (unsigned i = 0; i < count; ++i) { - consumedCharacters[i] = *current(); + consumedCharacters[i] = currentChar(); advance(); } } +void SegmentedString::advance8() +{ + ASSERT(!m_pushedChar1); + decrementAndCheckLength(); + m_currentChar = m_currentString.incrementAndGetCurrentChar8(); +} + +void SegmentedString::advance16() +{ + ASSERT(!m_pushedChar1); + decrementAndCheckLength(); + m_currentChar = m_currentString.incrementAndGetCurrentChar16(); +} + +void SegmentedString::advanceAndUpdateLineNumber8() +{ + ASSERT(!m_pushedChar1); + ASSERT(m_currentString.getCurrentChar() == m_currentChar); + if (m_currentChar == '\n') { + ++m_currentLine; + m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1; + } + decrementAndCheckLength(); + m_currentChar = m_currentString.incrementAndGetCurrentChar8(); +} + +void SegmentedString::advanceAndUpdateLineNumber16() +{ + ASSERT(!m_pushedChar1); + ASSERT(m_currentString.getCurrentChar() == m_currentChar); + if (m_currentChar == '\n') { + ++m_currentLine; + m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1; + } + decrementAndCheckLength(); + m_currentChar = m_currentString.incrementAndGetCurrentChar16(); +} + void SegmentedString::advanceSlowCase() { if (m_pushedChar1) { m_pushedChar1 = m_pushedChar2; m_pushedChar2 = 0; - } else if (m_currentString.m_current) { - ++m_currentString.m_current; + + if (m_pushedChar1) { + m_currentChar = m_pushedChar1; + return; + } + + updateAdvanceFunctionPointers(); + } else if (m_currentString.m_length) { if (--m_currentString.m_length == 0) advanceSubstring(); + } else if (!isComposite()) { + m_currentString.clear(); + m_empty = true; + m_fastPathFlags = NoFastPath; + m_advanceFunc = &SegmentedString::advanceEmpty; + m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; } - m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current; + m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0; } void SegmentedString::advanceAndUpdateLineNumberSlowCase() @@ -227,16 +302,45 @@ void SegmentedString::advanceAndUpdateLineNumberSlowCase() if (m_pushedChar1) { m_pushedChar1 = m_pushedChar2; m_pushedChar2 = 0; - } else if (m_currentString.m_current) { - if (*m_currentString.m_current++ == '\n' && m_currentString.doNotExcludeLineNumbers()) { + + if (m_pushedChar1) { + m_currentChar = m_pushedChar1; + return; + } + + updateAdvanceFunctionPointers(); + } else if (m_currentString.m_length) { + if (m_currentString.getCurrentChar() == '\n' && m_currentString.doNotExcludeLineNumbers()) { ++m_currentLine; // Plus 1 because numberOfCharactersConsumed value hasn't incremented yet; it does with m_length decrement below. m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1; } if (--m_currentString.m_length == 0) advanceSubstring(); + else + m_currentString.incrementAndGetCurrentChar(); // Only need the ++ + } else if (!isComposite()) { + m_currentString.clear(); + m_empty = true; + m_fastPathFlags = NoFastPath; + m_advanceFunc = &SegmentedString::advanceEmpty; + m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; } - m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current; + + m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0; +} + +void SegmentedString::advanceEmpty() +{ + ASSERT(!m_currentString.m_length && !isComposite()); + m_currentChar = 0; +} + +void SegmentedString::updateSlowCaseFunctionPointers() +{ + m_fastPathFlags = NoFastPath; + m_advanceFunc = &SegmentedString::advanceSlowCase; + m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceAndUpdateLineNumberSlowCase; } OrdinalNumber SegmentedString::currentLine() const |