private static bool AtLeastOneCandidateHasQueryPart(IList <UriTemplateTableMatchCandidate> candidates) { for (int i = 0; i < candidates.Count; i++) { UriTemplateTableMatchCandidate candidate = candidates[i]; if (!UriTemplateHelpers.CanMatchQueryTrivially(candidate.Template)) { return(true); } } return(false); }
private static bool NoCandidateHasQueryLiteralRequirementsAndThereIsAnEmptyFallback(IList <UriTemplateTableMatchCandidate> candidates) { bool flag = false; for (int i = 0; i < candidates.Count; i++) { UriTemplateTableMatchCandidate candidate = candidates[i]; if (UriTemplateHelpers.HasQueryLiteralRequirements(candidate.Template)) { return(false); } UriTemplateTableMatchCandidate candidate2 = candidates[i]; if (candidate2.Template.queries.Count == 0) { flag = true; } } return(flag); }
private static bool AllEquivalent(IList <UriTemplateTableMatchCandidate> list, int a, int b) { for (int i = a; i < (b - 1); i++) { UriTemplateTableMatchCandidate candidate = list[i]; UriTemplateTableMatchCandidate candidate2 = list[i + 1]; UriTemplateTableMatchCandidate candidate3 = list[i]; if (!candidate.Template.IsPathPartiallyEquivalentAt(candidate2.Template, candidate3.SegmentsCount)) { return(false); } UriTemplateTableMatchCandidate candidate4 = list[i]; UriTemplateTableMatchCandidate candidate5 = list[i + 1]; if (!candidate4.Template.IsQueryEquivalent(candidate5.Template)) { return(false); } } return(true); }
private static bool NotAllCandidatesArePathFullyEquivalent(IList <UriTemplateTableMatchCandidate> candidates) { if (candidates.Count > 1) { int count = -1; for (int i = 0; i < candidates.Count; i++) { if (count == -1) { UriTemplateTableMatchCandidate candidate = candidates[i]; count = candidate.Template.segments.Count; } else { UriTemplateTableMatchCandidate candidate2 = candidates[i]; if (count != candidate2.Template.segments.Count) { return(true); } } } } return(false); }
public Collection <UriTemplateMatch> Match(Uri uri) { if (uri == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("uri"); } if (!uri.IsAbsoluteUri) { return(None()); } this.MakeReadOnly(true); // Matching path : Collection <String> relativeSegments; IList <UriTemplateTableMatchCandidate> candidates; if (!FastComputeRelativeSegmentsAndLookup(uri, out relativeSegments, out candidates)) { return(None()); } // Matching query : NameValueCollection queryParameters = null; if (!this.noTemplateHasQueryPart && AtLeastOneCandidateHasQueryPart(candidates)) { Collection <UriTemplateTableMatchCandidate> nextCandidates = new Collection <UriTemplateTableMatchCandidate>(); Fx.Assert(nextCandidates.Count == 0, "nextCandidates should be empty"); // then deal with query queryParameters = UriTemplateHelpers.ParseQueryString(uri.Query); bool mustBeEspeciallyInteresting = NoCandidateHasQueryLiteralRequirementsAndThereIsAnEmptyFallback(candidates); for (int i = 0; i < candidates.Count; i++) { if (UriTemplateHelpers.CanMatchQueryInterestingly(candidates[i].Template, queryParameters, mustBeEspeciallyInteresting)) { nextCandidates.Add(candidates[i]); } } if (nextCandidates.Count > 1) { Fx.Assert(AllEquivalent(nextCandidates, 0, nextCandidates.Count), "demux algorithm problem, multiple non-equivalent matches"); } if (nextCandidates.Count == 0) { for (int i = 0; i < candidates.Count; i++) { if (UriTemplateHelpers.CanMatchQueryTrivially(candidates[i].Template)) { nextCandidates.Add(candidates[i]); } } } if (nextCandidates.Count == 0) { return(None()); } if (nextCandidates.Count > 1) { Fx.Assert(AllEquivalent(nextCandidates, 0, nextCandidates.Count), "demux algorithm problem, multiple non-equivalent matches"); } candidates = nextCandidates; } // Verifying that we have not broken the allowDuplicates settings because of terminal defaults // This situation can be caused when we are hosting ".../" and ".../{foo=xyz}" in the same // table. They are not equivalent; yet they reside together in the same path partially-equivalent // set. If we hit a uri that ends up in that particular end-of-path set, we want to provide the // user only the 'best' match and not both; thus preventing inconsistancy between the MakeReadonly // settings and the matching results. We will assume that the 'best' matches will be the ones with // the smallest number of segments - this will prefer ".../" over ".../{x=1}[/...]". if (NotAllCandidatesArePathFullyEquivalent(candidates)) { Collection <UriTemplateTableMatchCandidate> nextCandidates = new Collection <UriTemplateTableMatchCandidate>(); int minSegmentsCount = -1; for (int i = 0; i < candidates.Count; i++) { UriTemplateTableMatchCandidate candidate = candidates[i]; if (minSegmentsCount == -1) { minSegmentsCount = candidate.Template.segments.Count; nextCandidates.Add(candidate); } else if (candidate.Template.segments.Count < minSegmentsCount) { minSegmentsCount = candidate.Template.segments.Count; nextCandidates.Clear(); nextCandidates.Add(candidate); } else if (candidate.Template.segments.Count == minSegmentsCount) { nextCandidates.Add(candidate); } } Fx.Assert(minSegmentsCount != -1, "At least the first entry in the list should be kept"); Fx.Assert(nextCandidates.Count >= 1, "At least the first entry in the list should be kept"); Fx.Assert(nextCandidates[0].Template.segments.Count == minSegmentsCount, "Trivial"); candidates = nextCandidates; } // Building the actual result Collection <UriTemplateMatch> actualResults = new Collection <UriTemplateMatch>(); for (int i = 0; i < candidates.Count; i++) { UriTemplateTableMatchCandidate candidate = candidates[i]; UriTemplateMatch match = candidate.Template.CreateUriTemplateMatch(this.originalUncanonicalizedBaseAddress, uri, candidate.Data, candidate.SegmentsCount, relativeSegments, queryParameters); actualResults.Add(match); } return(actualResults); }
public Collection <UriTemplateMatch> Match(Uri uri) { Collection <string> collection; IList <UriTemplateTableMatchCandidate> list; if (uri == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("uri"); } if (!uri.IsAbsoluteUri) { return(None()); } this.MakeReadOnly(true); if (!this.FastComputeRelativeSegmentsAndLookup(uri, out collection, out list)) { return(None()); } NameValueCollection query = null; if (!this.noTemplateHasQueryPart && AtLeastOneCandidateHasQueryPart(list)) { Collection <UriTemplateTableMatchCandidate> collection2 = new Collection <UriTemplateTableMatchCandidate>(); query = UriTemplateHelpers.ParseQueryString(uri.Query); bool mustBeEspeciallyInteresting = NoCandidateHasQueryLiteralRequirementsAndThereIsAnEmptyFallback(list); for (int j = 0; j < list.Count; j++) { UriTemplateTableMatchCandidate candidate3 = list[j]; if (UriTemplateHelpers.CanMatchQueryInterestingly(candidate3.Template, query, mustBeEspeciallyInteresting)) { collection2.Add(list[j]); } } int count = collection2.Count; if (collection2.Count == 0) { for (int k = 0; k < list.Count; k++) { UriTemplateTableMatchCandidate candidate4 = list[k]; if (UriTemplateHelpers.CanMatchQueryTrivially(candidate4.Template)) { collection2.Add(list[k]); } } } if (collection2.Count == 0) { return(None()); } int num6 = collection2.Count; list = collection2; } if (NotAllCandidatesArePathFullyEquivalent(list)) { Collection <UriTemplateTableMatchCandidate> collection3 = new Collection <UriTemplateTableMatchCandidate>(); int num3 = -1; for (int m = 0; m < list.Count; m++) { UriTemplateTableMatchCandidate item = list[m]; if (num3 == -1) { num3 = item.Template.segments.Count; collection3.Add(item); } else if (item.Template.segments.Count < num3) { num3 = item.Template.segments.Count; collection3.Clear(); collection3.Add(item); } else if (item.Template.segments.Count == num3) { collection3.Add(item); } } list = collection3; } Collection <UriTemplateMatch> collection4 = new Collection <UriTemplateMatch>(); for (int i = 0; i < list.Count; i++) { UriTemplateTableMatchCandidate candidate2 = list[i]; UriTemplateMatch match = candidate2.Template.CreateUriTemplateMatch(this.originalUncanonicalizedBaseAddress, uri, candidate2.Data, candidate2.SegmentsCount, collection, query); collection4.Add(match); } return(collection4); }