15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    This library is free software; you can redistribute it and/or
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    modify it under the terms of the GNU Library General Public
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    License as published by the Free Software Foundation; either
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    version 2 of the License, or (at your option) any later version.
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    This library is distributed in the hope that it will be useful,
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    but WITHOUT ANY WARRANTY; without even the implied warranty of
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Library General Public License for more details.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    You should have received a copy of the GNU Library General Public License
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    along with this library; see the file COPYING.LIB.  If not, write to
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Boston, MA 02110-1301, USA.
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)*/
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef SegmentedString_h
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define SegmentedString_h
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
231e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/PlatformExport.h"
247757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/Deque.h"
257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/text/StringBuilder.h"
267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/text/TextPosition.h"
277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/text/WTFString.h"
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
29c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class SegmentedString;
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
331e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)class PLATFORM_EXPORT SegmentedSubstring {
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SegmentedSubstring()
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_length(0)
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_doNotExcludeLineNumbers(true)
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_is8Bit(false)
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_data.string16Ptr = 0;
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SegmentedSubstring(const String& str)
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_length(str.length())
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_doNotExcludeLineNumbers(true)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_string(str)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_length) {
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (m_string.is8Bit()) {
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_is8Bit = true;
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_data.string8Ptr = m_string.characters8();
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } else {
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_is8Bit = false;
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_data.string16Ptr = m_string.characters16();
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
561e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        } else {
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_is8Bit = false;
581e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void clear() { m_length = 0; m_data.string16Ptr = 0; m_is8Bit = false;}
6202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool is8Bit() { return m_is8Bit; }
6402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool excludeLineNumbers() const { return !m_doNotExcludeLineNumbers; }
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool doNotExcludeLineNumbers() const { return m_doNotExcludeLineNumbers; }
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setExcludeLineNumbers() { m_doNotExcludeLineNumbers = false; }
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int numberOfCharactersConsumed() const { return m_string.length() - m_length; }
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void appendTo(StringBuilder& builder) const
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int offset = m_string.length() - m_length;
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!offset) {
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (m_length)
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                builder.append(m_string);
791e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        } else {
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            builder.append(m_string.substring(offset, m_length));
811e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        }
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    UChar getCurrentChar8()
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return *m_data.string8Ptr;
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    UChar getCurrentChar16()
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_data.string16Ptr ? *m_data.string16Ptr : 0;
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    UChar incrementAndGetCurrentChar8()
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(m_data.string8Ptr);
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return *++m_data.string8Ptr;
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    UChar incrementAndGetCurrentChar16()
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(m_data.string16Ptr);
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return *++m_data.string16Ptr;
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String currentSubString(unsigned length)
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int offset = m_string.length() - m_length;
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_string.substring(offset, length);
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ALWAYS_INLINE UChar getCurrentChar()
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(m_length);
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (is8Bit())
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return getCurrentChar8();
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return getCurrentChar16();
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ALWAYS_INLINE UChar incrementAndGetCurrentChar()
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(m_length);
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (is8Bit())
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return incrementAndGetCurrentChar8();
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return incrementAndGetCurrentChar16();
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    union {
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const LChar* string8Ptr;
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const UChar* string16Ptr;
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } m_data;
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_length;
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_doNotExcludeLineNumbers;
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_is8Bit;
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String m_string;
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1411e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)class PLATFORM_EXPORT SegmentedString {
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SegmentedString()
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_pushedChar1(0)
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_pushedChar2(0)
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_currentChar(0)
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_numberOfCharactersConsumedPriorToCurrentString(0)
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_numberOfCharactersConsumedPriorToCurrentLine(0)
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_currentLine(0)
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_closed(false)
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_empty(true)
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_fastPathFlags(NoFastPath)
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_advanceFunc(&SegmentedString::advanceEmpty)
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_advanceAndUpdateLineNumberFunc(&SegmentedString::advanceEmpty)
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SegmentedString(const String& str)
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_pushedChar1(0)
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_pushedChar2(0)
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_currentString(str)
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_currentChar(0)
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_numberOfCharactersConsumedPriorToCurrentString(0)
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_numberOfCharactersConsumedPriorToCurrentLine(0)
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_currentLine(0)
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_closed(false)
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_empty(!str.length())
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_fastPathFlags(NoFastPath)
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_currentString.m_length)
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_currentChar = m_currentString.getCurrentChar();
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updateAdvanceFunctionPointers();
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void clear();
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void close();
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void append(const SegmentedString&);
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void prepend(const SegmentedString&);
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool excludeLineNumbers() const { return m_currentString.excludeLineNumbers(); }
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setExcludeLineNumbers();
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void push(UChar c)
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!m_pushedChar1) {
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_pushedChar1 = c;
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_currentChar = m_pushedChar1 ? m_pushedChar1 : m_currentString.getCurrentChar();
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            updateSlowCaseFunctionPointers();
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(!m_pushedChar2);
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_pushedChar2 = c;
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isEmpty() const { return m_empty; }
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned length() const;
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isClosed() const { return m_closed; }
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    enum LookAheadResult {
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DidNotMatch,
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DidMatch,
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        NotEnoughCharacters,
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LookAheadResult lookAhead(const String& string) { return lookAheadInline(string, true); }
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LookAheadResult lookAheadIgnoringCase(const String& string) { return lookAheadInline(string, false); }
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advance()
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_fastPathFlags & Use8BitAdvance) {
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(!m_pushedChar1);
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            bool haveOneCharacterLeft = (--m_currentString.m_length == 1);
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_currentChar = m_currentString.incrementAndGetCurrentChar8();
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!haveOneCharacterLeft)
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return;
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            updateSlowCaseFunctionPointers();
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        (this->*m_advanceFunc)();
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    inline void advanceAndUpdateLineNumber()
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_fastPathFlags & Use8BitAdvance) {
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(!m_pushedChar1);
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            bool haveNewLine = (m_currentChar == '\n') & !!(m_fastPathFlags & Use8BitAdvanceAndUpdateLineNumbers);
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            bool haveOneCharacterLeft = (--m_currentString.m_length == 1);
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_currentChar = m_currentString.incrementAndGetCurrentChar8();
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (!(haveNewLine | haveOneCharacterLeft))
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return;
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (haveNewLine) {
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ++m_currentLine;
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_numberOfCharactersConsumedPriorToCurrentLine =  m_numberOfCharactersConsumedPriorToCurrentString + m_currentString.numberOfCharactersConsumed();
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (haveOneCharacterLeft)
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                updateSlowCaseFunctionPointers();
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        (this->*m_advanceAndUpdateLineNumberFunc)();
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advanceAndASSERT(UChar expectedCharacter)
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT_UNUSED(expectedCharacter, currentChar() == expectedCharacter);
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        advance();
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advanceAndASSERTIgnoringCase(UChar expectedCharacter)
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT_UNUSED(expectedCharacter, WTF::Unicode::foldCase(currentChar()) == WTF::Unicode::foldCase(expectedCharacter));
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        advance();
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advancePastNonNewline()
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(currentChar() != '\n');
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        advance();
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advancePastNewlineAndUpdateLineNumber()
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(currentChar() == '\n');
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!m_pushedChar1 && m_currentString.m_length > 1) {
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            int newLineFlag = m_currentString.doNotExcludeLineNumbers();
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_currentLine += newLineFlag;
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (newLineFlag)
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1;
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            decrementAndCheckLength();
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_currentChar = m_currentString.incrementAndGetCurrentChar();
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        advanceAndUpdateLineNumberSlowCase();
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Writes the consumed characters into consumedCharacters, which must
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // have space for at least |count| characters.
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advance(unsigned count, UChar* consumedCharacters);
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool escaped() const { return m_pushedChar1; }
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int numberOfCharactersConsumed() const
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int numberOfPushedCharacters = 0;
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_pushedChar1) {
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ++numberOfPushedCharacters;
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (m_pushedChar2)
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ++numberOfPushedCharacters;
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_numberOfCharactersConsumedPriorToCurrentString + m_currentString.numberOfCharactersConsumed() - numberOfPushedCharacters;
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String toString() const;
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
30702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    UChar currentChar() const { return m_currentChar; }
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The method is moderately slow, comparing to currentLine method.
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    OrdinalNumber currentColumn() const;
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    OrdinalNumber currentLine() const;
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Sets value of line/column variables. Column is specified indirectly by a parameter columnAftreProlog
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // which is a value of column that we should get after a prolog (first prologLength characters) has been consumed.
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setCurrentPosition(OrdinalNumber line, OrdinalNumber columnAftreProlog, int prologLength);
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    enum FastPathFlags {
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        NoFastPath = 0,
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Use8BitAdvanceAndUpdateLineNumbers = 1 << 0,
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Use8BitAdvance = 1 << 1,
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void append(const SegmentedSubstring&);
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void prepend(const SegmentedSubstring&);
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advance8();
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advance16();
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advanceAndUpdateLineNumber8();
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advanceAndUpdateLineNumber16();
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advanceSlowCase();
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advanceAndUpdateLineNumberSlowCase();
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advanceEmpty();
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void advanceSubstring();
33402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void updateSlowCaseFunctionPointers();
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void decrementAndCheckLength()
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(m_currentString.m_length > 1);
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (--m_currentString.m_length == 1)
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            updateSlowCaseFunctionPointers();
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void updateAdvanceFunctionPointers()
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if ((m_currentString.m_length > 1) && !m_pushedChar1) {
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (m_currentString.is8Bit()) {
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_advanceFunc = &SegmentedString::advance8;
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_fastPathFlags = Use8BitAdvance;
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (m_currentString.doNotExcludeLineNumbers()) {
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceAndUpdateLineNumber8;
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    m_fastPathFlags |= Use8BitAdvanceAndUpdateLineNumbers;
3531e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                } else {
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance8;
3551e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                }
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return;
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_advanceFunc = &SegmentedString::advance16;
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_fastPathFlags = NoFastPath;
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (m_currentString.doNotExcludeLineNumbers())
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceAndUpdateLineNumber16;
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance16;
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!m_currentString.m_length && !isComposite()) {
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_advanceFunc = &SegmentedString::advanceEmpty;
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_fastPathFlags = NoFastPath;
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty;
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        updateSlowCaseFunctionPointers();
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    inline LookAheadResult lookAheadInline(const String& string, bool caseSensitive)
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!m_pushedChar1 && string.length() <= static_cast<unsigned>(m_currentString.m_length)) {
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            String currentSubstring = m_currentString.currentSubString(string.length());
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (currentSubstring.startsWith(string, caseSensitive))
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return DidMatch;
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return DidNotMatch;
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return lookAheadSlowCase(string, caseSensitive);
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
38702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    LookAheadResult lookAheadSlowCase(const String& string, bool caseSensitive)
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        unsigned count = string.length();
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (count > length())
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return NotEnoughCharacters;
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        UChar* consumedCharacters;
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        String consumedString = String::createUninitialized(count, consumedCharacters);
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        advance(count, consumedCharacters);
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LookAheadResult result = DidNotMatch;
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (consumedString.startsWith(string, caseSensitive))
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result = DidMatch;
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        prepend(SegmentedString(consumedString));
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return result;
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isComposite() const { return !m_substrings.isEmpty(); }
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    UChar m_pushedChar1;
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    UChar m_pushedChar2;
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SegmentedSubstring m_currentString;
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    UChar m_currentChar;
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_numberOfCharactersConsumedPriorToCurrentString;
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_numberOfCharactersConsumedPriorToCurrentLine;
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_currentLine;
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Deque<SegmentedSubstring> m_substrings;
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_closed;
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_empty;
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned char m_fastPathFlags;
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void (SegmentedString::*m_advanceFunc)();
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void (SegmentedString::*m_advanceAndUpdateLineNumberFunc)();
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
423