Use spans for complex segments (#9817)
This commit is contained in:
parent
f08da14f1b
commit
8af14399b6
|
|
@ -228,13 +228,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
|
|||
{
|
||||
for (var i = 0; i < captures.Length; i++)
|
||||
{
|
||||
var parameterName = captures[i].parameterName;
|
||||
if (segments.Length > captures[i].segmentIndex)
|
||||
(var parameterName, var segmentIndex, var slotIndex) = captures[i];
|
||||
|
||||
if ((uint)segmentIndex < (uint)segments.Length)
|
||||
{
|
||||
var segment = segments[captures[i].segmentIndex];
|
||||
var segment = segments[segmentIndex];
|
||||
if (parameterName != null && segment.Length > 0)
|
||||
{
|
||||
slots[captures[i].slotIndex] = new KeyValuePair<string, object>(
|
||||
slots[slotIndex] = new KeyValuePair<string, object>(
|
||||
parameterName,
|
||||
path.Substring(segment.Start, segment.Length));
|
||||
}
|
||||
|
|
@ -249,7 +250,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
|
|||
ReadOnlySpan<PathSegment> segments)
|
||||
{
|
||||
// Read segmentIndex to local both to skip double read from stack value
|
||||
// and to use the same in-bounds validated varaible to access the array.
|
||||
// and to use the same in-bounds validated variable to access the array.
|
||||
var segmentIndex = catchAll.segmentIndex;
|
||||
if ((uint)segmentIndex < (uint)segments.Length)
|
||||
{
|
||||
|
|
@ -271,7 +272,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
|
|||
{
|
||||
(var complexSegment, var segmentIndex) = complexSegments[i];
|
||||
var segment = segments[segmentIndex];
|
||||
var text = path.Substring(segment.Start, segment.Length);
|
||||
var text = path.AsSpan(segment.Start, segment.Length);
|
||||
if (!RoutePatternMatcher.MatchComplexSegment(complexSegment, text, values))
|
||||
{
|
||||
Logger.CandidateRejectedByComplexSegment(_logger, path, endpoint, complexSegment);
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ namespace Microsoft.AspNetCore.Routing
|
|||
}
|
||||
if (!pathSegment.IsSimple)
|
||||
{
|
||||
if (!MatchComplexSegment(pathSegment, requestSegment.ToString(), values))
|
||||
if (!MatchComplexSegment(pathSegment, requestSegment.AsSpan(), values))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -292,7 +292,7 @@ namespace Microsoft.AspNetCore.Routing
|
|||
|
||||
internal static bool MatchComplexSegment(
|
||||
RoutePatternPathSegment routeSegment,
|
||||
string requestSegment,
|
||||
ReadOnlySpan<char> requestSegment,
|
||||
RouteValueDictionary values)
|
||||
{
|
||||
var indexOfLastSegment = routeSegment.Parts.Count - 1;
|
||||
|
|
@ -336,7 +336,7 @@ namespace Microsoft.AspNetCore.Routing
|
|||
|
||||
private static bool MatchComplexSegmentCore(
|
||||
RoutePatternPathSegment routeSegment,
|
||||
string requestSegment,
|
||||
ReadOnlySpan<char> requestSegment,
|
||||
RouteValueDictionary values,
|
||||
int indexOfLastSegmentUsed)
|
||||
{
|
||||
|
|
@ -366,14 +366,14 @@ namespace Microsoft.AspNetCore.Routing
|
|||
Debug.Assert(part.IsLiteral || part.IsSeparator);
|
||||
lastLiteral = part;
|
||||
|
||||
var startIndex = lastIndex - 1;
|
||||
var startIndex = lastIndex;
|
||||
// If we have a pending parameter subsegment, we must leave at least one character for that
|
||||
if (parameterNeedsValue != null)
|
||||
{
|
||||
startIndex--;
|
||||
}
|
||||
|
||||
if (startIndex < 0)
|
||||
if (startIndex == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -382,17 +382,15 @@ namespace Microsoft.AspNetCore.Routing
|
|||
if (part.IsLiteral)
|
||||
{
|
||||
var literal = (RoutePatternLiteralPart)part;
|
||||
indexOfLiteral = requestSegment.LastIndexOf(
|
||||
indexOfLiteral = requestSegment.Slice(0, startIndex).LastIndexOf(
|
||||
literal.Content,
|
||||
startIndex,
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
else
|
||||
{
|
||||
var literal = (RoutePatternSeparatorPart)part;
|
||||
indexOfLiteral = requestSegment.LastIndexOf(
|
||||
indexOfLiteral = requestSegment.Slice(0, startIndex).LastIndexOf(
|
||||
literal.Content,
|
||||
startIndex,
|
||||
StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
|
|
@ -465,9 +463,9 @@ namespace Microsoft.AspNetCore.Routing
|
|||
}
|
||||
}
|
||||
|
||||
var parameterValueString = requestSegment.Substring(parameterStartIndex, parameterTextLength);
|
||||
var parameterValueSpan = requestSegment.Slice(parameterStartIndex, parameterTextLength);
|
||||
|
||||
if (string.IsNullOrEmpty(parameterValueString))
|
||||
if (parameterValueSpan.Length == 0)
|
||||
{
|
||||
// If we're here that means we have a segment that contains multiple sub-segments.
|
||||
// For these segments all parameters must have non-empty values. If the parameter
|
||||
|
|
@ -478,7 +476,7 @@ namespace Microsoft.AspNetCore.Routing
|
|||
else
|
||||
{
|
||||
// If there's a value in the segment for this parameter, use the subsegment value
|
||||
outValues.Add(parameterNeedsValue.Name, parameterValueString);
|
||||
outValues.Add(parameterNeedsValue.Name, new string(parameterValueSpan));
|
||||
}
|
||||
|
||||
parameterNeedsValue = null;
|
||||
|
|
|
|||
Loading…
Reference in New Issue