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); }
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)); }
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); }