Example #1
0
        static bool TryMatch(UriTemplateLiteralPathSegment[] wireUriSegments, UriTemplateTrieLocation currentLocation,
                             out UriTemplatePathPartiallyEquivalentSet success, out SingleLocationOrLocationsSet nextStep)
        {
            // if returns true, success is set to answer
            // if returns false, nextStep is set to next place to look
            success  = null;
            nextStep = new SingleLocationOrLocationsSet();

            if (wireUriSegments.Length <= currentLocation.node.depth)
            {
                Fx.Assert(wireUriSegments.Length == 0 || wireUriSegments[wireUriSegments.Length - 1].EndsWithSlash,
                          "we should not have traversed this deep into the trie unless the wire path ended in a slash");

                if (currentLocation.node.endOfPath.Items.Count != 0)
                {
                    // exact match of e.g. "path1/path2/"
                    success = currentLocation.node.endOfPath;
                    return(true);
                }
                else if (currentLocation.node.star.Items.Count != 0)
                {
                    // inexact match of e.g. WIRE("path1/path2/") against TEMPLATE("path1/path2/*")
                    success = currentLocation.node.star;
                    return(true);
                }
                else
                {
                    nextStep = new SingleLocationOrLocationsSet(currentLocation.node.onFailure);
                    return(false);
                }
            }
            else
            {
                UriTemplateLiteralPathSegment curWireSeg = wireUriSegments[currentLocation.node.depth];
                bool considerLiteral  = false;
                bool considerCompound = false;
                bool considerVariable = false;
                bool considerStar     = false;
                switch (currentLocation.locationWithin)
                {
                case UriTemplateTrieIntraNodeLocation.BeforeLiteral:
                    considerLiteral  = true;
                    considerCompound = true;
                    considerVariable = true;
                    considerStar     = true;
                    break;

                case UriTemplateTrieIntraNodeLocation.AfterLiteral:
                    considerLiteral  = false;
                    considerCompound = true;
                    considerVariable = true;
                    considerStar     = true;
                    break;

                case UriTemplateTrieIntraNodeLocation.AfterCompound:
                    considerLiteral  = false;
                    considerCompound = false;
                    considerVariable = true;
                    considerStar     = true;
                    break;

                case UriTemplateTrieIntraNodeLocation.AfterVariable:
                    considerLiteral  = false;
                    considerCompound = false;
                    considerVariable = false;
                    considerStar     = true;
                    break;

                default:
                    Fx.Assert("bad kind");
                    break;
                }
                if (curWireSeg.EndsWithSlash)
                {
                    IList <IList <UriTemplateTrieLocation> > compoundLocationsSet;

                    if (considerLiteral && currentLocation.node.nextLiteralSegment != null &&
                        currentLocation.node.nextLiteralSegment.ContainsKey(curWireSeg))
                    {
                        nextStep = new SingleLocationOrLocationsSet(currentLocation.node.nextLiteralSegment[curWireSeg]);
                        return(false);
                    }
                    else if (considerCompound && currentLocation.node.nextCompoundSegment != null &&
                             AscendingSortedCompoundSegmentsCollection <UriTemplateTrieLocation> .Lookup(currentLocation.node.nextCompoundSegment, curWireSeg, out compoundLocationsSet))
                    {
                        nextStep = new SingleLocationOrLocationsSet(compoundLocationsSet);
                        return(false);
                    }
                    else if (considerVariable && currentLocation.node.nextVariableSegment != null &&
                             !curWireSeg.IsNullOrEmpty())
                    {
                        nextStep = new SingleLocationOrLocationsSet(currentLocation.node.nextVariableSegment);
                        return(false);
                    }
                    else if (considerStar && currentLocation.node.star.Items.Count != 0)
                    {
                        // matches e.g. WIRE("path1/path2/path3") and TEMPLATE("path1/*")
                        success = currentLocation.node.star;
                        return(true);
                    }
                    else
                    {
                        nextStep = new SingleLocationOrLocationsSet(currentLocation.node.onFailure);
                        return(false);
                    }
                }
                else
                {
                    IList <IList <UriTemplatePathPartiallyEquivalentSet> > compoundPathEquivalentSets;

                    Fx.Assert(!curWireSeg.EndsWithSlash, "!curWireSeg.EndsWithSlash");
                    Fx.Assert(!curWireSeg.IsNullOrEmpty(), "!curWireSeg.IsNullOrEmpty()");
                    if (considerLiteral && currentLocation.node.finalLiteralSegment != null &&
                        currentLocation.node.finalLiteralSegment.ContainsKey(curWireSeg))
                    {
                        // matches e.g. WIRE("path1/path2") and TEMPLATE("path1/path2")
                        success = currentLocation.node.finalLiteralSegment[curWireSeg];
                        return(true);
                    }
                    else if (considerCompound && currentLocation.node.finalCompoundSegment != null &&
                             AscendingSortedCompoundSegmentsCollection <UriTemplatePathPartiallyEquivalentSet> .Lookup(currentLocation.node.finalCompoundSegment, curWireSeg, out compoundPathEquivalentSets))
                    {
                        // matches e.g. WIRE("path1/path2") and TEMPLATE("path1/p{var}th2")
                        // we should take only the highest order match!
                        Fx.Assert(compoundPathEquivalentSets.Count >= 1, "Lookup is expected to return false otherwise");
                        Fx.Assert(compoundPathEquivalentSets[0].Count > 0, "Find shouldn't return empty sublists");
                        if (compoundPathEquivalentSets[0].Count == 1)
                        {
                            success = compoundPathEquivalentSets[0][0];
                        }
                        else
                        {
                            success = new UriTemplatePathPartiallyEquivalentSet(currentLocation.node.depth + 1);
                            for (int i = 0; i < compoundPathEquivalentSets[0].Count; i++)
                            {
                                success.Items.AddRange(compoundPathEquivalentSets[0][i].Items);
                            }
                        }
                        return(true);
                    }
                    else if (considerVariable && currentLocation.node.finalVariableSegment.Items.Count != 0)
                    {
                        // matches e.g. WIRE("path1/path2") and TEMPLATE("path1/{var}")
                        success = currentLocation.node.finalVariableSegment;
                        return(true);
                    }
                    else if (considerStar && currentLocation.node.star.Items.Count != 0)
                    {
                        // matches e.g. WIRE("path1/path2") and TEMPLATE("path1/*")
                        success = currentLocation.node.star;
                        return(true);
                    }
                    else
                    {
                        nextStep = new SingleLocationOrLocationsSet(currentLocation.node.onFailure);
                        return(false);
                    }
                }
            }
        }
        private static bool TryMatch(UriTemplateLiteralPathSegment[] wireUriSegments, UriTemplateTrieLocation currentLocation, out UriTemplatePathPartiallyEquivalentSet success, out SingleLocationOrLocationsSet nextStep)
        {
            IList <IList <UriTemplatePathPartiallyEquivalentSet> > list2;

            success  = null;
            nextStep = new SingleLocationOrLocationsSet();
            if (wireUriSegments.Length <= currentLocation.node.depth)
            {
                if (currentLocation.node.endOfPath.Items.Count != 0)
                {
                    success = currentLocation.node.endOfPath;
                    return(true);
                }
                if (currentLocation.node.star.Items.Count != 0)
                {
                    success = currentLocation.node.star;
                    return(true);
                }
                nextStep = new SingleLocationOrLocationsSet(currentLocation.node.onFailure);
                return(false);
            }
            UriTemplateLiteralPathSegment key = wireUriSegments[currentLocation.node.depth];
            bool flag  = false;
            bool flag2 = false;
            bool flag3 = false;
            bool flag4 = false;

            switch (currentLocation.locationWithin)
            {
            case UriTemplateTrieIntraNodeLocation.BeforeLiteral:
                flag  = true;
                flag2 = true;
                flag3 = true;
                flag4 = true;
                break;

            case UriTemplateTrieIntraNodeLocation.AfterLiteral:
                flag  = false;
                flag2 = true;
                flag3 = true;
                flag4 = true;
                break;

            case UriTemplateTrieIntraNodeLocation.AfterCompound:
                flag  = false;
                flag2 = false;
                flag3 = true;
                flag4 = true;
                break;

            case UriTemplateTrieIntraNodeLocation.AfterVariable:
                flag  = false;
                flag2 = false;
                flag3 = false;
                flag4 = true;
                break;
            }
            if (key.EndsWithSlash)
            {
                IList <IList <UriTemplateTrieLocation> > list;
                if ((flag && (currentLocation.node.nextLiteralSegment != null)) && currentLocation.node.nextLiteralSegment.ContainsKey(key))
                {
                    nextStep = new SingleLocationOrLocationsSet(currentLocation.node.nextLiteralSegment[key]);
                    return(false);
                }
                if ((flag2 && (currentLocation.node.nextCompoundSegment != null)) && AscendingSortedCompoundSegmentsCollection <UriTemplateTrieLocation> .Lookup(currentLocation.node.nextCompoundSegment, key, out list))
                {
                    nextStep = new SingleLocationOrLocationsSet(list);
                    return(false);
                }
                if ((flag3 && (currentLocation.node.nextVariableSegment != null)) && !key.IsNullOrEmpty())
                {
                    nextStep = new SingleLocationOrLocationsSet(currentLocation.node.nextVariableSegment);
                    return(false);
                }
                if (flag4 && (currentLocation.node.star.Items.Count != 0))
                {
                    success = currentLocation.node.star;
                    return(true);
                }
                nextStep = new SingleLocationOrLocationsSet(currentLocation.node.onFailure);
                return(false);
            }
            if ((flag && (currentLocation.node.finalLiteralSegment != null)) && currentLocation.node.finalLiteralSegment.ContainsKey(key))
            {
                success = currentLocation.node.finalLiteralSegment[key];
                return(true);
            }
            if ((flag2 && (currentLocation.node.finalCompoundSegment != null)) && AscendingSortedCompoundSegmentsCollection <UriTemplatePathPartiallyEquivalentSet> .Lookup(currentLocation.node.finalCompoundSegment, key, out list2))
            {
                if (list2[0].Count == 1)
                {
                    success = list2[0][0];
                }
                else
                {
                    success = new UriTemplatePathPartiallyEquivalentSet(currentLocation.node.depth + 1);
                    for (int i = 0; i < list2[0].Count; i++)
                    {
                        success.Items.AddRange(list2[0][i].Items);
                    }
                }
                return(true);
            }
            if (flag3 && (currentLocation.node.finalVariableSegment.Items.Count != 0))
            {
                success = currentLocation.node.finalVariableSegment;
                return(true);
            }
            if (flag4 && (currentLocation.node.star.Items.Count != 0))
            {
                success = currentLocation.node.star;
                return(true);
            }
            nextStep = new SingleLocationOrLocationsSet(currentLocation.node.onFailure);
            return(false);
        }