bool MatchSegment (int segIndex, int argsCount, string[] argSegs, List <PatternToken> tokens, RouteValueDictionary ret)
{
string pathSegment = argSegs [segIndex];
int pathSegmentLength = pathSegment != null ? pathSegment.Length : -1;
int startIndex = pathSegmentLength - 1;
PatternTokenType tokenType;
int tokensCount = tokens.Count;
PatternToken token;
string tokenName;
for (int tokenIndex = tokensCount - 1; tokenIndex > -1; tokenIndex--) {
token = tokens [tokenIndex];
if (startIndex < 0)
return false;
tokenType = token.Type;
tokenName = token.Name;
if (segIndex > segmentCount - 1 || tokenType == PatternTokenType.CatchAll) {
var sb = new StringBuilder ();
for (int j = segIndex; j < argsCount; j++) {
if (j > segIndex)
sb.Append ('/');
sb.Append (argSegs [j]);
}
ret.Add (tokenName, sb.ToString ());
break;
}
int scanIndex;
if (token.Type == PatternTokenType.Literal) {
int nameLen = tokenName.Length;
if (startIndex + 1 < nameLen)
return false;
scanIndex = startIndex - nameLen + 1;
if (String.Compare (pathSegment, scanIndex, tokenName, 0, nameLen, StringComparison.OrdinalIgnoreCase) != 0)
return false;
startIndex = scanIndex - 1;
continue;
}
// Standard token
int nextTokenIndex = tokenIndex - 1;
if (nextTokenIndex < 0) {
// First token
ret.Add (tokenName, pathSegment.Substring (0, startIndex + 1));
continue;
}
if (startIndex == 0)
return false;
var nextToken = tokens [nextTokenIndex];
string nextTokenName = nextToken.Name;
// Skip one char, since there can be no empty segments and if the
// current token's value happens to be the same as preceeding
// literal text, we'll save some time and complexity.
scanIndex = startIndex - 1;
int lastIndex = pathSegment.LastIndexOf (nextTokenName, scanIndex, StringComparison.OrdinalIgnoreCase);
if (lastIndex == -1)
return false;
lastIndex += nextTokenName.Length - 1;
string sectionValue = pathSegment.Substring (lastIndex + 1, startIndex - lastIndex);
if (String.IsNullOrEmpty (sectionValue))
return false;
ret.Add (tokenName, sectionValue);
startIndex = lastIndex;
}
return true;
}