예제 #1
0
        /// <summary>
        /// Create an instance of the enumerator for a given node.
        /// </summary>
        /// <param name="fsa">The automaton to iterate over.</param>
        /// <param name="node">The starting node's identifier (can be the <see cref="FSA.GetRootNode()"/>.</param>
        public ByteSequenceEnumerator(FSA fsa, int node)
        {
            this.bufferWrapper = ByteBuffer.Wrap(buffer);
            this.fsa           = fsa;

            if (fsa.GetFirstArc(node) != 0)
            {
                RestartFrom(node);
            }
        }
예제 #2
0
        /// <summary>
        /// Same as <see cref="Match(byte[], int, int, int)"/>, but allows passing
        /// a reusable <see cref="MatchResult"/> object so that no intermediate garbage is
        /// produced.
        /// </summary>
        /// <param name="reuse">The <see cref="MatchResult"/> to reuse.</param>
        /// <param name="sequence">Input sequence to look for in the automaton.</param>
        /// <param name="start">Start index in the sequence array.</param>
        /// <param name="length">Length of the byte sequence, must be at least 1.</param>
        /// <param name="node">The node to start traversal from, typically the root node (<see cref="FSA.GetRootNode()"/>).</param>
        /// <returns>The same object as <paramref name="reuse"/>, but with updated match <see cref="MatchResult.Kind"/>
        /// and other relevant fields.</returns>
        public MatchResult Match(MatchResult reuse, byte[] sequence, int start, int length, int node)
        {
            if (node == 0)
            {
                reuse.Reset(MatchResult.NoMatch, start, node);
                return(reuse);
            }

            FSA fsa = this.fsa;
            int end = start + length;

            for (int i = start; i < end; i++)
            {
                int arc = fsa.GetArc(node, sequence[i]);
                if (arc != 0)
                {
                    if (i + 1 == end && fsa.IsArcFinal(arc))
                    {
                        /* The automaton has an exact match of the input sequence. */
                        reuse.Reset(MatchResult.ExactMatch, i, node);
                        return(reuse);
                    }

                    if (fsa.IsArcTerminal(arc))
                    {
                        /* The automaton contains a prefix of the input sequence. */
                        reuse.Reset(MatchResult.AutomatonHasPrefix, i + 1, node);
                        return(reuse);
                    }

                    // Make a transition along the arc.
                    node = fsa.GetEndNode(arc);
                }
                else
                {
                    if (i > start)
                    {
                        reuse.Reset(MatchResult.AutomatonHasPrefix, i, node);
                    }
                    else
                    {
                        reuse.Reset(MatchResult.NoMatch, i, node);
                    }
                    return(reuse);
                }
            }

            /* The sequence is a prefix of at least one sequence in the automaton. */
            reuse.Reset(MatchResult.SequenceIsAPrefix, 0, node);
            return(reuse);
        }
예제 #3
0
 /// <summary>
 /// Traversals of the given FSA.
 /// </summary>
 /// <param name="fsa">The target automaton for traversals.</param>
 public FSATraversal(FSA fsa)
 {
     this.fsa = fsa;
 }
예제 #4
0
 public ByteSequenceEnumerable(FSA fsa, int node)
 {
     this.fsa  = fsa;
     this.node = node;
 }
예제 #5
0
 /// <summary>
 /// Create an instance of the enumerator iterating over all automaton sequences.
 /// </summary>
 /// <param name="fsa">The automaton to iterate over.</param>
 public ByteSequenceEnumerator(FSA fsa)
     : this(fsa, fsa.GetRootNode())
 {
 }