internal static int GetEntityTagLength(StringSegment input, int startIndex, out EntityTagHeaderValue parsedValue) { Contract.Requires(startIndex >= 0); parsedValue = null; if (StringSegment.IsNullOrEmpty(input) || (startIndex >= input.Length)) { return(0); } // Caller must remove leading whitespaces. If not, we'll return 0. var isWeak = false; var current = startIndex; var firstChar = input[startIndex]; if (firstChar == '*') { // We have '*' value, indicating "any" ETag. parsedValue = Any; current++; } else { // The RFC defines 'W/' as prefix, but we'll be flexible and also accept lower-case 'w'. if ((firstChar == 'W') || (firstChar == 'w')) { current++; // We need at least 3 more chars: the '/' character followed by two quotes. if ((current + 2 >= input.Length) || (input[current] != '/')) { return(0); } isWeak = true; current++; // we have a weak-entity tag. current = current + ProtoRuleParser.GetWhitespaceLength(input, current); } var tagStartIndex = current; var tagLength = 0; if (ProtoRuleParser.GetQuotedStringLength(input, current, out tagLength) != ProtoParseResult.Parsed) { return(0); } parsedValue = new EntityTagHeaderValue(); if (tagLength == input.Length) { // Most of the time we'll have strong ETags without leading/trailing whitespaces. Contract.Assert(startIndex == 0); Contract.Assert(!isWeak); parsedValue._tag = input; parsedValue._isWeak = false; } else { parsedValue._tag = input.Subsegment(tagStartIndex, tagLength); parsedValue._isWeak = isWeak; } current = current + tagLength; } current = current + ProtoRuleParser.GetWhitespaceLength(input, current); return(current - startIndex); }
public static bool TryParse(StringSegment input, out EntityTagHeaderValue parsedValue) { var index = 0; return(SingleValueParser.TryParseValue(input, ref index, out parsedValue)); }