#pragma once
#if ENABLE(CONTENT_EXTENSIONS)
#include "ContentExtensionsDebugging.h"
#include <wtf/HashMap.h>
#include <wtf/Vector.h>
namespace WebCore {
namespace ContentExtensions {
struct DFA;
struct CharRange {
char first;
char last;
unsigned size() const { return last - first + 1; }
};
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 };
}
void kill(DFA&);
Vector<uint64_t> 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);
} }
#endif // ENABLE(CONTENT_EXTENSIONS)