/// <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); } }
/// <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); }
/// <summary> /// Traversals of the given FSA. /// </summary> /// <param name="fsa">The target automaton for traversals.</param> public FSATraversal(FSA fsa) { this.fsa = fsa; }
public ByteSequenceEnumerable(FSA fsa, int node) { this.fsa = fsa; this.node = node; }
/// <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()) { }