/// <summary> /// Adds the specified node to this instance. /// </summary> /// <param name="nodes">The nodes to add.</param> /// <param name="index">The starting index of the first node to add.</param> /// <param name="value">The value to associate with the route.</param> public void Add(IReadOnlyList <IMatchNode> nodes, int index, T value) { IMatchNode matcher = nodes[index]; RouteNode <T> node = null; if (this.children != null) { node = this.children.FirstOrDefault(n => n.matcher.Equals(matcher)); } if (node == null) { node = new RouteNode <T>(matcher); this.AddChild(node); } index++; if (index == nodes.Count) { node.Value = value; } else { node.Add(nodes, index, value); } }
private RouteNode <T> Match(IReadOnlyList <StringSegment> segments, int index, Dictionary <string, object> captures) { NodeMatchResult match = NodeMatchResult.None; if (index >= 0) { match = this.matcher.Match(segments[index]); if (!match.Success) { return(null); } } index++; RouteNode <T> result = null; if (index == segments.Count) { result = this; } else { result = this.MatchChildren(segments, index, captures); } // Add this after we've searched out children, as during that search // we might clear the captures as we head down wrong paths if ((result != null) && (match.Name != null)) { captures[match.Name] = match.Value; } return(result); }
private void AddRoute(string verb, IMatchNode[] nodes, MethodInfo method) { RouteNode <MethodInfo> parent; if (!this.verbs.TryGetValue(verb, out parent)) { parent = new RouteNode <MethodInfo>(null); this.verbs.Add(verb, parent); } parent.Add(nodes, 0, method); }
/// <summary> /// Determines whether the specified URL matches any added to this /// instance or not. /// </summary> /// <param name="url">The URL to match.</param> /// <returns> /// <c>true</c> if this instance matched the URL; otherwise, <c>false</c>. /// </returns> public MatchResult Match(string url) { var segments = new List <StringSegment>(UrlParser.GetSegments(url)); var captures = new Dictionary <string, object>(); RouteNode <T> node = this.Match(segments, -1, captures); if (node == null) { return(default(MatchResult)); } else { return(new MatchResult(captures, node.Value)); } }
private void AddChild(RouteNode <T> node) { if (this.children == null) { this.children = new[] { node }; } else { int length = this.children.Length; Array.Resize(ref this.children, length + 1); this.children[length] = node; // Sort largest first (hence b compare to a) Array.Sort(this.children, (a, b) => b.matcher.Priority.CompareTo(a.matcher.Priority)); } }
/// <inheritdoc /> public MethodInfo Match(string verb, string path, ILookup <string, string> query, out IReadOnlyDictionary <string, object> parameters) { RouteNode <MethodInfo> node; if (this.verbs.TryGetValue(verb, out node)) { RouteNode <MethodInfo> .MatchResult match = node.Match(path); if (match.Success) { parameters = match.Captures; return(match.Value); } } parameters = null; return(null); }
private RouteNode <T> MatchChildren(IReadOnlyList <StringSegment> segments, int index, Dictionary <string, object> captures) { if (this.children != null) { for (int i = 0; i < this.children.Length; i++) { // Clear any previously captured parameters as we're searching // down a new branch captures.Clear(); RouteNode <T> result = this.children[i].Match(segments, index, captures); if (result != null) { return(result); } } } return(null); }