Computes min and max for matching string. Won't return strings bigger than maxlen.
| 1973 | // Computes min and max for matching string. |
| 1974 | // Won't return strings bigger than maxlen. |
| 1975 | bool DFA::PossibleMatchRange(std::string* min, std::string* max, int maxlen) { |
| 1976 | if (!ok()) |
| 1977 | return false; |
| 1978 | |
| 1979 | // NOTE: if future users of PossibleMatchRange want more precision when |
| 1980 | // presented with infinitely repeated elements, consider making this a |
| 1981 | // parameter to PossibleMatchRange. |
| 1982 | static int kMaxEltRepetitions = 0; |
| 1983 | |
| 1984 | // Keep track of the number of times we've visited states previously. We only |
| 1985 | // revisit a given state if it's part of a repeated group, so if the value |
| 1986 | // portion of the map tuple exceeds kMaxEltRepetitions we bail out and set |
| 1987 | // |*max| to |PrefixSuccessor(*max)|. |
| 1988 | // |
| 1989 | // Also note that previously_visited_states[UnseenStatePtr] will, in the STL |
| 1990 | // tradition, implicitly insert a '0' value at first use. We take advantage |
| 1991 | // of that property below. |
| 1992 | std::unordered_map<State*, int> previously_visited_states; |
| 1993 | |
| 1994 | // Pick out start state for anchored search at beginning of text. |
| 1995 | RWLocker l(&cache_mutex_); |
| 1996 | SearchParams params(StringPiece(), StringPiece(), &l); |
| 1997 | params.anchored = true; |
| 1998 | if (!AnalyzeSearch(¶ms)) |
| 1999 | return false; |
| 2000 | if (params.start == DeadState) { // No matching strings |
| 2001 | *min = ""; |
| 2002 | *max = ""; |
| 2003 | return true; |
| 2004 | } |
| 2005 | if (params.start == FullMatchState) // Every string matches: no max |
| 2006 | return false; |
| 2007 | |
| 2008 | // The DFA is essentially a big graph rooted at params.start, |
| 2009 | // and paths in the graph correspond to accepted strings. |
| 2010 | // Each node in the graph has potentially 256+1 arrows |
| 2011 | // coming out, one for each byte plus the magic end of |
| 2012 | // text character kByteEndText. |
| 2013 | |
| 2014 | // To find the smallest possible prefix of an accepted |
| 2015 | // string, we just walk the graph preferring to follow |
| 2016 | // arrows with the lowest bytes possible. To find the |
| 2017 | // largest possible prefix, we follow the largest bytes |
| 2018 | // possible. |
| 2019 | |
| 2020 | // The test for whether there is an arrow from s on byte j is |
| 2021 | // ns = RunStateOnByteUnlocked(s, j); |
| 2022 | // if (ns == NULL) |
| 2023 | // return false; |
| 2024 | // if (ns != DeadState && ns->ninst > 0) |
| 2025 | // The RunStateOnByteUnlocked call asks the DFA to build out the graph. |
| 2026 | // It returns NULL only if the DFA has run out of memory, |
| 2027 | // in which case we can't be sure of anything. |
| 2028 | // The second check sees whether there was graph built |
| 2029 | // and whether it is interesting graph. Nodes might have |
| 2030 | // ns->ninst == 0 if they exist only to represent the fact |
| 2031 | // that a match was found on the previous byte. |
| 2032 |
nothing calls this directly
no test coverage detected