| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| using System; |
| |
| using IndexReader = Lucene.Net.Index.IndexReader; |
| using Term = Lucene.Net.Index.Term; |
| |
| namespace Lucene.Net.Search |
| { |
| |
| /// <summary> Subclass of FilteredTermEnum for enumerating all terms that match the |
| /// specified wildcard filter term. |
| /// <p/> |
| /// Term enumerations are always ordered by Term.compareTo(). Each term in |
| /// the enumeration is greater than all that precede it. |
| /// </summary> |
| public class WildcardTermEnum : FilteredTermEnum |
| { |
| internal Term searchTerm; |
| internal System.String field; |
| internal System.String text; |
| internal System.String pre; |
| internal int preLen; |
| internal bool endEnum = false; |
| |
| /// <summary> Creates a new <c>WildcardTermEnum</c>. |
| /// <p/> |
| /// After calling the constructor the enumeration is already pointing to the first |
| /// valid term if such a term exists. |
| /// </summary> |
| public WildcardTermEnum(IndexReader reader, Term term):base() |
| { |
| searchTerm = term; |
| field = searchTerm.Field; |
| System.String searchTermText = searchTerm.Text; |
| |
| int sidx = searchTermText.IndexOf((System.Char) WILDCARD_STRING); |
| int cidx = searchTermText.IndexOf((System.Char) WILDCARD_CHAR); |
| int idx = sidx; |
| if (idx == - 1) |
| { |
| idx = cidx; |
| } |
| else if (cidx >= 0) |
| { |
| idx = System.Math.Min(idx, cidx); |
| } |
| pre = idx != - 1?searchTerm.Text.Substring(0, (idx) - (0)):""; |
| |
| preLen = pre.Length; |
| text = searchTermText.Substring(preLen); |
| SetEnum(reader.Terms(new Term(searchTerm.Field, pre))); |
| } |
| |
| /*protected internal*/ protected internal override bool TermCompare(Term term) |
| { |
| if ((System.Object) field == (System.Object) term.Field) |
| { |
| System.String searchText = term.Text; |
| if (searchText.StartsWith(pre)) |
| { |
| return WildcardEquals(text, 0, searchText, preLen); |
| } |
| } |
| endEnum = true; |
| return false; |
| } |
| |
| public override float Difference() |
| { |
| return 1.0f; |
| } |
| |
| public override bool EndEnum() |
| { |
| return endEnum; |
| } |
| |
| /// <summary>***************************************** |
| /// String equality with support for wildcards |
| /// ****************************************** |
| /// </summary> |
| |
| public const char WILDCARD_STRING = '*'; |
| public const char WILDCARD_CHAR = '?'; |
| |
| /// <summary> Determines if a word matches a wildcard pattern. |
| /// <small>Work released by Granta Design Ltd after originally being done on |
| /// company time.</small> |
| /// </summary> |
| public static bool WildcardEquals(System.String pattern, int patternIdx, System.String string_Renamed, int stringIdx) |
| { |
| int p = patternIdx; |
| |
| for (int s = stringIdx; ; ++p, ++s) |
| { |
| // End of string yet? |
| bool sEnd = (s >= string_Renamed.Length); |
| // End of pattern yet? |
| bool pEnd = (p >= pattern.Length); |
| |
| // If we're looking at the end of the string... |
| if (sEnd) |
| { |
| // Assume the only thing left on the pattern is/are wildcards |
| bool justWildcardsLeft = true; |
| |
| // Current wildcard position |
| int wildcardSearchPos = p; |
| // While we haven't found the end of the pattern, |
| // and haven't encountered any non-wildcard characters |
| while (wildcardSearchPos < pattern.Length && justWildcardsLeft) |
| { |
| // Check the character at the current position |
| char wildchar = pattern[wildcardSearchPos]; |
| |
| // If it's not a wildcard character, then there is more |
| // pattern information after this/these wildcards. |
| if (wildchar != WILDCARD_CHAR && wildchar != WILDCARD_STRING) |
| { |
| justWildcardsLeft = false; |
| } |
| else |
| { |
| // to prevent "cat" matches "ca??" |
| if (wildchar == WILDCARD_CHAR) |
| { |
| return false; |
| } |
| |
| // Look at the next character |
| wildcardSearchPos++; |
| } |
| } |
| |
| // This was a prefix wildcard search, and we've matched, so |
| // return true. |
| if (justWildcardsLeft) |
| { |
| return true; |
| } |
| } |
| |
| // If we've gone past the end of the string, or the pattern, |
| // return false. |
| if (sEnd || pEnd) |
| { |
| break; |
| } |
| |
| // Match a single character, so continue. |
| if (pattern[p] == WILDCARD_CHAR) |
| { |
| continue; |
| } |
| |
| // |
| if (pattern[p] == WILDCARD_STRING) |
| { |
| // Look at the character beyond the '*' characters. |
| while (p < pattern.Length && pattern[p] == WILDCARD_STRING) |
| ++p; |
| // Examine the string, starting at the last character. |
| for (int i = string_Renamed.Length; i >= s; --i) |
| { |
| if (WildcardEquals(pattern, p, string_Renamed, i)) |
| { |
| return true; |
| } |
| } |
| break; |
| } |
| if (pattern[p] != string_Renamed[s]) |
| { |
| break; |
| } |
| } |
| return false; |
| } |
| } |
| } |