/* * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DFANode_h #define DFANode_h #if ENABLE(CONTENT_EXTENSIONS) #include "ContentExtensionsDebugging.h" #include #include namespace WebCore { namespace ContentExtensions { struct DFA; struct CharRange { char first; char last; unsigned size() const { return last - first + 1; } }; // A DFANode abstract the transition table out of a DFA state. If a state is accepting, the DFANode also have // the actions for that state. class DFANode { public: struct ConstRangeIterator { const DFA& dfa; uint32_t position; const ConstRangeIterator& operator*() const { return *this; } bool operator==(const ConstRangeIterator& other) const { ASSERT(&dfa == &other.dfa); return position == other.position; } bool operator!=(const ConstRangeIterator& other) const { return !(*this == other); } ConstRangeIterator& operator++() { ++position; return *this; } const CharRange& range() const; uint32_t target() const; char first() const { return range().first; } char last() const { return range().last; } uint32_t data() const { return target(); } }; struct IterableConstRange { const DFA& dfa; uint32_t rangesStart; uint32_t rangesEnd; ConstRangeIterator begin() const { return { dfa, rangesStart }; } ConstRangeIterator end() const { return { dfa, rangesEnd }; } }; IterableConstRange transitions(const DFA& dfa) const { return IterableConstRange { dfa, m_transitionsStart, m_transitionsStart + m_transitionsLength }; } struct RangeIterator { DFA& dfa; uint32_t position; RangeIterator& operator*() { return *this; } bool operator==(const RangeIterator& other) const { ASSERT(&dfa == &other.dfa); return position == other.position; } bool operator!=(const RangeIterator& other) const { return !(*this == other); } RangeIterator& operator++() { ++position; return *this; } const CharRange& range() const; uint32_t target() const; void resetTarget(uint32_t); char first() const { return range().first; } char last() const { return range().last; } uint32_t data() const { return target(); } }; struct IterableRange { DFA& dfa; uint32_t rangesStart; uint32_t rangesEnd; RangeIterator begin() const { return { dfa, rangesStart }; } RangeIterator end() const { return { dfa, rangesEnd }; } }; IterableRange transitions(DFA& dfa) { return IterableRange { dfa, m_transitionsStart, m_transitionsStart + m_transitionsLength }; } // FIXME: Stop minimizing killed nodes and add ASSERT(!isKilled()) in many functions here. void kill(DFA&); Vector actions(const DFA&) const; bool containsTransition(char, const DFA&) const; bool isKilled() const { return m_flags & IsKilled; } bool hasActions() const { return !!m_actionsLength; } uint16_t actionsLength() const { return m_actionsLength; } uint32_t actionsStart() const { return m_actionsStart; } bool canUseFallbackTransition(const DFA&) const; uint32_t bestFallbackTarget(const DFA&) const; void setActions(uint32_t start, uint16_t length) { ASSERT(!m_actionsStart); ASSERT(!m_actionsLength); m_actionsStart = start; m_actionsLength = length; } void setTransitions(uint32_t start, uint16_t length) { ASSERT(!m_transitionsStart); ASSERT(!m_transitionsLength); m_transitionsStart = start; m_transitionsLength = length; } private: uint32_t m_actionsStart { 0 }; uint32_t m_transitionsStart { 0 }; uint16_t m_actionsLength { 0 }; uint8_t m_transitionsLength { 0 }; uint8_t m_flags { 0 }; const uint8_t IsKilled = 0x01; }; COMPILE_ASSERT(sizeof(DFANode) <= 16, Keep the DFANodes small); } } // namespace WebCore #endif // ENABLE(CONTENT_EXTENSIONS) #endif // DFANode_h