public void Clear() { Id = string.Empty; Name = string.Empty; SetCode = string.Empty; StringProperties.Clear(); IntMinProperties.Clear(); IntMaxProperties.Clear(); BoolProperties.Clear(); EnumProperties.Clear(); }
public void Parse(string input) { if (input == null) { throw new ArgumentNullException(nameof(input)); } Clear(); // If some search criteria has a space in it, then that criteria should be enclosed in quotes // Using this assumption, we find all quoted areas and replace the space(s) temporarily so that we treat it as 1 word // This may not be the best solution (definitely not the cleanest), but it should get the job done var processedInput = new StringBuilder(); string unprocessedInput = input; while (unprocessedInput.Contains(Quote)) { int leftQuoteIndex = unprocessedInput.IndexOf(Quote, StringComparison.Ordinal); // Guaranteed to be found because we checked with Contains() // If the left quote is the last character, then we obviously won't find a right quote int rightQuoteIndex = leftQuoteIndex == unprocessedInput.Length - Quote.Length ? -1 : unprocessedInput.IndexOf(Quote, leftQuoteIndex + Quote.Length, StringComparison.Ordinal); string beforeQuote = unprocessedInput.Substring(0, leftQuoteIndex); var quotation = string.Empty; if (rightQuoteIndex != -1) // If there's no right quote, then we don't have a quotation { int startIndex = leftQuoteIndex + Quote.Length; quotation = unprocessedInput.Substring(startIndex, rightQuoteIndex - startIndex) .Replace(Delimiter, Quote); } processedInput.Append(beforeQuote + quotation); // If there's no quotation, we'll finish by taking everything after the 1 quote // Otherwise, we'll keep checking the rest of the input for quotations unprocessedInput = rightQuoteIndex == -1 ? unprocessedInput.Substring(leftQuoteIndex + Quote.Length) : unprocessedInput.Substring(rightQuoteIndex + Quote.Length); } processedInput.Append(unprocessedInput); foreach (string word in processedInput.ToString() .Split(new[] { Delimiter }, StringSplitOptions.RemoveEmptyEntries)) { string token = word.Replace(Quote, Delimiter); // Restore spaces that we temporarily replaced if (token.StartsWith(KeywordId)) { Id = token.Substring(KeywordId.Length); } else if (token.StartsWith(KeywordSet)) { SetCode = token.Substring(KeywordSet.Length); } else if (token.StartsWith(KeywordIs)) { BoolProperties.Add(token.Substring(KeywordIs.Length), true); } else if (token.StartsWith(KeywordNot)) { BoolProperties.Add(token.Substring(KeywordNot.Length), false); } else if (token.Contains(KeywordString)) { StringProperties.Add(token.Substring(0, token.IndexOf(KeywordString, StringComparison.Ordinal)), token.Substring(token.IndexOf(KeywordString, StringComparison.Ordinal) + KeywordString.Length)); } else if (token.Contains(KeywordIntMin) && int.TryParse( token.Substring(token.IndexOf(KeywordIntMin, StringComparison.Ordinal) + KeywordIntMin.Length), out int minValue)) { IntMinProperties.Add(token.Substring(0, token.IndexOf(KeywordIntMin, StringComparison.Ordinal)), minValue); } else if (token.Contains(KeywordIntMax) && int.TryParse( token.Substring(token.IndexOf(KeywordIntMax, StringComparison.Ordinal) + KeywordIntMax.Length), out int maxValue)) { IntMaxProperties.Add(token.Substring(0, token.IndexOf(KeywordIntMax, StringComparison.Ordinal)), maxValue); } else if (token.Contains(KeywordEnum) && int.TryParse( token.Substring(token.IndexOf(KeywordEnum, StringComparison.Ordinal) + KeywordEnum.Length), out int enumValue)) { EnumProperties.Add(token.Substring(0, token.IndexOf(KeywordEnum, StringComparison.Ordinal)), enumValue); } else { Name += (string.IsNullOrEmpty(Name) ? string.Empty : Delimiter) + token; } } }
public string ToString(CardGame forGame) { string filters = string.Empty; if (!string.IsNullOrEmpty(Name)) { filters += "name:\"" + Name + "\"; "; } if (!string.IsNullOrEmpty(Id)) { filters += "id:" + Id + "; "; } if (!string.IsNullOrEmpty(SetCode)) { filters += "set:" + SetCode + "; "; } foreach (PropertyDef property in forGame.CardProperties) { switch (property.Type) { case PropertyType.ObjectEnum: case PropertyType.ObjectEnumList: case PropertyType.StringEnum: case PropertyType.StringEnumList: if (!EnumProperties.ContainsKey(property.Name)) { break; } EnumDef enumDef = forGame.Enums.FirstOrDefault(def => def.Property.Equals(property.Name)); if (enumDef != null) { string filterValue = enumDef.GetStringFromLookupFlags(EnumProperties[property.Name]); if (filterValue.Contains(' ')) { filterValue = "\'" + filterValue + "\'"; } filters += property.Name + ":" + filterValue + "; "; } break; case PropertyType.Integer: if (IntMinProperties.ContainsKey(property.Name)) { filters += property.Name + ">=" + IntMinProperties[property.Name] + "; "; } if (IntMaxProperties.ContainsKey(property.Name)) { filters += property.Name + "<=" + IntMaxProperties[property.Name] + "; "; } break; case PropertyType.Object: case PropertyType.ObjectList: case PropertyType.Number: case PropertyType.Boolean: case PropertyType.StringList: case PropertyType.EscapedString: case PropertyType.String: default: if (StringProperties.ContainsKey(property.Name)) { filters += property.Name + ":\"" + StringProperties[property.Name] + "\"; "; } break; } } return(filters); }