Пример #1
0
        public static IList <PathSubsegment> Compose(IList <PathSubsegment> collection)
        {
            if (collection.Count < 2)
            {
                return(collection);
            }

            List <PathSubsegment> segments  = new List <PathSubsegment>();
            CompositeSubsegment   composite = null;

            foreach (PathSubsegment segment in collection)
            {
                LiteralSubsegment literal = (segment as LiteralSubsegment);
                if (literal != null)
                {
                    (composite = composite ?? new CompositeSubsegment())
                    .Segments.Add(literal);
                }
                else
                {
                    if (composite != null)
                    {
                        segments.Add(composite);
                    }

                    composite = null;
                    segments.Add(segment);
                }
            }
            if (composite != null)
            {
                segments.Add(composite);
            }

            return(segments);
        }
Пример #2
0
        private BoundUrl BuildUrl(ValueDictionary defaults,
                                  ValueDictionary acceptedValues, HashSet <string> unusedValues)
        {
            StringBuilder pathBuilder    = new StringBuilder();
            StringBuilder segmentBuilder = new StringBuilder();
            bool          flush          = false;

            foreach (PathSegment segment in _segments)
            {
                SeparatorSegment separator = (segment as SeparatorSegment);
                ContentSegment   content   = (segment as ContentSegment);

                if (separator != null)
                {
                    if (flush && segmentBuilder.Length > 0)
                    {
                        pathBuilder.Append(segmentBuilder.ToString());
                        segmentBuilder.Length = 0;
                    }

                    flush = false;
                    segmentBuilder.Append(RouteParser.PathSeparator);
                }

                if (content != null)
                {
                    bool segmentEnd = false;

                    foreach (PathSubsegment subsegment in content.Segments)
                    {
                        LiteralSubsegment   literal   = (subsegment as LiteralSubsegment);
                        ParameterSubsegment parameter = (subsegment as ParameterSubsegment);

                        if (literal != null)
                        {
                            flush = true;
                            segmentBuilder.Append(Uri.EscapeUriString(literal.Literal));
                        }

                        if (parameter != null)
                        {
                            object acceptedValue;
                            object defaultValue;

                            if (flush && segmentBuilder.Length > 0)
                            {
                                pathBuilder.Append(segmentBuilder.ToString());
                                segmentBuilder.Length = 0;

                                segmentEnd = true;
                            }

                            flush = false;

                            if (acceptedValues.TryGetValue(parameter.ParameterName, out acceptedValue))
                            {
                                unusedValues.Remove(parameter.ParameterName);
                            }

                            defaults.TryGetValue(parameter.ParameterName, out defaultValue);
                            if (RoutePartsEqual(acceptedValue, defaultValue))
                            {
                                segmentBuilder.Append(Uri.EscapeUriString(
                                                          Convert.ToString(acceptedValue, CultureInfo.InvariantCulture)));
                                continue;
                            }

                            if (segmentBuilder.Length > 0)
                            {
                                pathBuilder.Append(segmentBuilder.ToString());
                                segmentBuilder.Length = 0;
                            }

                            pathBuilder.Append(Uri.EscapeUriString(Convert.ToString(acceptedValue, CultureInfo.InvariantCulture)));
                            segmentEnd = true;
                        }
                    }

                    if (segmentEnd && segmentBuilder.Length > 0)
                    {
                        pathBuilder.Append(segmentBuilder.ToString());
                        segmentBuilder.Length = 0;
                    }
                }
            }

            if (flush && segmentBuilder.Length > 0)
            {
                pathBuilder.Append(segmentBuilder.ToString());
            }

            if (unusedValues.Count > 0)
            {
                bool isFirst = true;
                foreach (string key in unusedValues)
                {
                    object value;
                    if (acceptedValues.TryGetValue(key, out value))
                    {
                        pathBuilder.Append(isFirst ? '?' : '&');
                        isFirst = false;

                        pathBuilder.Append(Uri.EscapeDataString(key.ToLowerInvariant()));
                        pathBuilder.Append('=');
                        pathBuilder.Append(Uri.EscapeDataString(
                                               Convert.ToString(value, CultureInfo.InvariantCulture)));
                    }
                }
            }
            return(new BoundUrl(pathBuilder.ToString(), acceptedValues));
        }
Пример #3
0
        private bool MatchContent(ContentSegment segment, string pathSegment,
                                  ValueDictionary defaults, ValueDictionary matchedValues)
        {
            if (String.IsNullOrEmpty(pathSegment))
            {
                if (segment.Segments.Count > 0)
                {
                    object value;
                    ParameterSubsegment ps = (segment.Segments.FirstOrDefault(
                                                  s => (s is ParameterSubsegment)) as ParameterSubsegment);

                    if (ps == null)
                    {
                        return(false);
                    }

                    if (defaults.TryGetValue(ps.ParameterName, out value))
                    {
                        matchedValues.Add(ps.ParameterName, value);
                        return(true);
                    }
                }
                return(false);
            }

            int segmentLength = pathSegment.Length;
            int segmentIndex  = (segment.Segments.Count - 1);

            ParameterSubsegment lastParameter = null;
            LiteralSubsegment   lastLiteral   = null;

            while (segmentIndex >= 0)
            {
                int index = segmentLength;
                ParameterSubsegment parameter = (segment.Segments[segmentIndex] as ParameterSubsegment);
                LiteralSubsegment   literal   = (segment.Segments[segmentIndex] as LiteralSubsegment);

                if (parameter != null)
                {
                    lastParameter = parameter;
                }

                if (literal != null)
                {
                    lastLiteral = literal;

                    int literalIndex = pathSegment.LastIndexOf(literal.Literal,
                                                               segmentLength - 1, StringComparison.OrdinalIgnoreCase);

                    if (literalIndex == -1)
                    {
                        return(false);
                    }

                    if ((segmentIndex == segment.Segments.Count - 1) &&
                        ((literalIndex + literal.Literal.Length) != pathSegment.Length))
                    {
                        return(false);
                    }

                    index = literalIndex;
                }

                if (lastParameter != null && ((lastLiteral != null &&
                                               parameter == null) || segmentIndex == 0))
                {
                    int startIndex;
                    int lastIndex;

                    if (lastLiteral == null)
                    {
                        startIndex = (segmentIndex == 0) ? 0 : index + lastLiteral.Literal.Length;
                        lastIndex  = segmentLength;
                    }
                    else if (segmentIndex == 0 && parameter != null)
                    {
                        startIndex = 0;
                        lastIndex  = segmentLength;
                    }
                    else
                    {
                        startIndex = index + lastLiteral.Literal.Length;
                        lastIndex  = segmentLength - startIndex;
                    }

                    string part = pathSegment.Substring(startIndex, lastIndex);

                    if (String.IsNullOrEmpty(part))
                    {
                        return(false);
                    }

                    matchedValues.Add(lastParameter.ParameterName, part);

                    lastParameter = null;
                    lastLiteral   = null;
                }
                segmentLength = index;
                segmentIndex--;
            }

            if (segmentLength != 0)
            {
                return(segment.Segments[0] is ParameterSubsegment);
            }

            return(true);
        }