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);
 }
Exemple #5
0
        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);
        }