void SegmentedString::prepend(const SegmentedSubstring& s) { ASSERT(!escaped()); ASSERT(!s.numberOfCharactersConsumed()); if (!s.m_length) return; // FIXME: We're assuming that the prepend were originally consumed by // this SegmentedString. We're also ASSERTing that s is a fresh // SegmentedSubstring. These assumptions are sufficient for our // current use, but we might need to handle the more elaborate // cases in the future. m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed(); m_numberOfCharactersConsumedPriorToCurrentString -= s.m_length; if (!m_currentString.m_length) { m_currentString = s; updateAdvanceFunctionPointers(); } else { // Shift our m_currentString into our list. m_substrings.prepend(m_currentString); m_currentString = s; updateAdvanceFunctionPointers(); } m_empty = false; }
void SegmentedString::advanceAndUpdateLineNumberSlowCase() { if (m_pushedChar1) { m_pushedChar1 = m_pushedChar2; m_pushedChar2 = 0; 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_currentString.m_length ? m_currentString.getCurrentChar() : 0; }
void SegmentedString::setExcludeLineNumbers() { if (!m_currentSubstring.doNotExcludeLineNumbers) return; m_currentSubstring.doNotExcludeLineNumbers = false; for (auto& substring : m_otherSubstrings) substring.doNotExcludeLineNumbers = false; updateAdvanceFunctionPointers(); }
void SegmentedString::append(const SegmentedSubstring& s) { ASSERT(!m_closed); if (!s.m_length) return; 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, PrependType type) { ASSERT(!s.numberOfCharactersConsumed()); if (!s.length()) return; // FIXME: We're also ASSERTing that s is a fresh SegmentedSubstring. // The assumption is sufficient for our current use, but we might // need to handle the more elaborate cases in the future. m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed(); if (type == PrependType::Unconsume) m_numberOfCharactersConsumedPriorToCurrentString -= s.length(); if (!m_currentString.length()) { m_currentString = s; updateAdvanceFunctionPointers(); } else { // Shift our m_currentString into our list. m_substrings.prepend(m_currentString); m_currentString = s; updateAdvanceFunctionPointers(); } m_empty = false; }
inline void SegmentedString::appendSubstring(Substring&& substring) { ASSERT(!m_isClosed); if (!substring.length) return; if (m_currentSubstring.length) m_otherSubstrings.append(WTFMove(substring)); else { m_numberOfCharactersConsumedPriorToCurrentSubstring += m_currentSubstring.numberOfCharactersConsumed(); m_currentSubstring = WTFMove(substring); m_currentCharacter = m_currentSubstring.currentCharacter(); updateAdvanceFunctionPointers(); } }
inline void SegmentedString::advancePastSingleCharacterSubstringWithoutUpdatingLineNumber() { ASSERT(m_currentSubstring.length == 1); if (m_otherSubstrings.isEmpty()) { m_currentSubstring.length = 0; m_currentCharacter = 0; updateAdvanceFunctionPointersForEmptyString(); return; } m_numberOfCharactersConsumedPriorToCurrentSubstring += m_currentSubstring.numberOfCharactersConsumed(); m_currentSubstring = m_otherSubstrings.takeFirst(); // If we've previously consumed some characters of the non-current string, we now account for those // characters as part of the current string, not as part of "prior to current string." m_numberOfCharactersConsumedPriorToCurrentSubstring -= m_currentSubstring.numberOfCharactersConsumed(); m_currentCharacter = m_currentSubstring.currentCharacter(); updateAdvanceFunctionPointers(); }
void SegmentedString::advanceSubstring() { if (isComposite()) { m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed(); m_currentString = m_substrings.takeFirst(); // If we've previously consumed some characters of the non-current // 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(); updateAdvanceFunctionPointers(); } else { m_currentString.clear(); m_empty = true; m_fastPathFlags = NoFastPath; m_advanceFunc = &SegmentedString::advanceEmpty; m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty; } }
void SegmentedString::pushBack(String&& string) { // We never create a substring for an empty string. ASSERT(string.length()); // The new substring we will create won't have the doNotExcludeLineNumbers set appropriately. // That was lost when the characters were consumed before pushing them back. But this does // not matter, because clients never use this for newlines. Catch that with this assertion. ASSERT(!string.contains('\n')); // The characters in the string must be previously consumed characters from this segmented string. ASSERT(string.length() <= numberOfCharactersConsumed()); m_numberOfCharactersConsumedPriorToCurrentSubstring += m_currentSubstring.numberOfCharactersConsumed(); if (m_currentSubstring.length) m_otherSubstrings.prepend(WTFMove(m_currentSubstring)); m_currentSubstring = WTFMove(string); m_numberOfCharactersConsumedPriorToCurrentSubstring -= m_currentSubstring.length; m_currentCharacter = m_currentSubstring.currentCharacter(); updateAdvanceFunctionPointers(); }
void SegmentedString::advanceSlowCase() { if (m_pushedChar1) { m_pushedChar1 = m_pushedChar2; m_pushedChar2 = 0; 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_currentString.m_length ? m_currentString.getCurrentChar() : 0; }