/// <summary> /// Calculate hashcode for match. /// </summary> /// <param name="obj"></param> /// <returns></returns> public int GetHashCode(IReadOnlyDictionary <string, string> obj) { // Cast if is match ILinePatternMatch match = obj as ILinePatternMatch; if (match?.Pattern != Pattern) { match = null; } // hash int hash = FNVHashBasis; // Match each capture part for (int i = 0; i < Pattern.CaptureParts.Length; i++) { string value = null; if (match != null) { value = match.PartValues[i]; } else { obj.TryGetValue(Pattern.CaptureParts[i].Identifier, out value); } hash *= FNVHashPrime; if (value != null) { hash ^= value.GetHashCode(); } } return(hash); }
/// <summary> /// Get resource names /// </summary> /// <param name="filterKey"></param> /// <returns></returns> public IEnumerable <string> GetResourceNames(ILine filterKey) { // Return all if (filterKey == null) { return(dictionary.Keys.ToList()); } // Create filter. LineQualifier filter = new LineQualifier().Rule(filterKey) as LineQualifier; // There are no rules if (!filter.HasRules) { return(dictionary.Keys.ToList()); } // Filter with pattern if (lineFormat is ILinePattern pattern_) { return(Filter1(pattern_).ToList()); } // Filter with parser if (lineFormat is ILineFormatParser parser_) { return(Filter2(parser_).ToList()); } // Return nothing return(null); IEnumerable <string> Filter1(ILinePattern pattern) { foreach (var line in dictionary) { ILinePatternMatch match = pattern.Match(line.Key); if (!match.Success || !filter.Qualify(match)) { continue; } yield return(line.Key); } } IEnumerable <string> Filter2(ILineFormatParser parser) { foreach (var line in dictionary) { ILine key; if (!parser.TryParse(line.Key, out key)) { continue; } if (!filter.Qualify(key)) { continue; } yield return(line.Key); } } }
/// <summary> /// Compare matches for equality. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public bool Equals(IReadOnlyDictionary <string, string> x, IReadOnlyDictionary <string, string> y) { if (x == null && y == null) { return(true); } if (x == null || y == null) { return(false); } // Cast if x and y are pattern matches ILinePatternMatch x_match = x as ILinePatternMatch; ILinePatternMatch y_match = y as ILinePatternMatch; if (x_match?.Pattern != Pattern) { x_match = null; } if (y_match?.Pattern != Pattern) { y_match = null; } // Match each capture part for (int i = 0; i < Pattern.CaptureParts.Length; i++) { string x_value = null, y_value = null; if (x_match != null) { x_value = x_match.PartValues[i]; } else { x.TryGetValue(Pattern.CaptureParts[i].Identifier, out x_value); } if (y_match != null) { y_value = y_match.PartValues[i]; } else { y.TryGetValue(Pattern.CaptureParts[i].Identifier, out y_value); } if (x_value != y_value) { return(false); } } return(true); }
/// <summary> /// Get cultures /// </summary> /// <returns></returns> public IEnumerable <CultureInfo> GetSupportedCultures() { if (lineFormat is ILinePattern pattern) { ILinePatternPart culturePart; if (!pattern.PartMap.TryGetValue("Culture", out culturePart)) { return(null); } Dictionary <string, CultureInfo> result = new Dictionary <string, CultureInfo>(); foreach (var kp in dictionary) { ILinePatternMatch match = pattern.Match(kp.Key); if (!match.Success) { continue; } string culture = match[culturePart.CaptureIndex]; if (culture == null) { culture = ""; } if (result.ContainsKey(culture)) { continue; } try { result[culture] = CultureInfo.GetCultureInfo(culture); } catch (CultureNotFoundException) { } } return(result.Values.ToArray()); } else if (lineFormat is ILineFormatParser parser) { //lineFormat.Parse() return(dictionary.Keys.Select(k => { ILine l; CultureInfo c; return parser.TryParse(k, out l) && l.TryGetCultureInfo(out c) ? c : null; }).Where(ci => ci != null).Distinct().ToArray()); } else { // Can't extract culture return(null); } }
/// <summary> /// Create pattern match from regular expression /// </summary> /// <param name="_match"></param> /// <param name="match"></param> /// <param name="overwrite"></param> /// <returns></returns> public static ILinePatternMatch Add(this ILinePatternMatch _match, Match match, bool overwrite = true) { foreach (var part in _match.Pattern.CaptureParts) { Group g = match.Groups[part.Identifier]; if (!g.Success) { continue; } if (!overwrite && _match.PartValues[part.CaptureIndex] != null) { continue; } _match.PartValues[part.CaptureIndex] = g.Value; } return(_match); }
/// <summary> /// Convert <paramref name="match"/> to line where occurance indices are correct. /// </summary> /// <param name="match"></param> /// <returns></returns> public static ILine ToLine(this ILinePatternMatch match) { // Apply parameter qualifiers ILine line = null; for (int i = 0; i < match.PartValues.Length; i++) { string parameterValue = match.PartValues[i]; if (parameterValue == null) { continue; } string parameterName = match.Pattern.CaptureParts[i].ParameterName; line = new LineParameter(null, line, parameterName, parameterValue); // TODO Put line parts in occurance order // } return(line); }
/// <summary> /// Add values from dictionary. /// </summary> /// <param name="match"></param> /// <param name="values"></param> /// <param name="overwrite"></param> /// <returns></returns> public static ILinePatternMatch Add(this ILinePatternMatch match, IReadOnlyDictionary <string, string> values, bool overwrite = true) { foreach (var kp in values) { if (kp.Value == null) { continue; } ILinePatternPart part; if (!match.Pattern.PartMap.TryGetValue(kp.Key, out part)) { continue; } if (!overwrite && match.PartValues[part.CaptureIndex] != null) { continue; } match.PartValues[part.CaptureIndex] = kp.Value; } return(match); }
/// <summary> /// Qualifier by <paramref name="keyMatch"/>. /// /// If <see cref="ILinePatternMatch.Success"/> is false then return false. /// /// The whole <paramref name="keyMatch"/> is matched against every qualifier, if one disqualifies then returns false. /// </summary> /// <param name="qualifier"></param> /// <param name="keyMatch">(optional) </param> /// <returns>true if line is qualified, false if disqualified</returns> public static bool Qualify(this ILineQualifier qualifier, ILinePatternMatch keyMatch) => keyMatch != null && keyMatch.Success && qualifier.Qualify(keyMatch.ToLine());
/// <summary> /// Match parameters of an object and convert into a string. /// </summary> /// <param name="pattern"></param> /// <param name="key"></param> /// <returns>match as string or null</returns> public static string MatchToString(this ILinePattern pattern, ILine key) { ILinePatternMatch match = pattern.Match(key); return(pattern.Print(match.PartValues)); }