// Returns the length of a range list. E.g. "1-2, 3-4, 5-6" adds 3 ranges to 'rangeCollection'. Note that empty // list segments are allowed, e.g. ",1-2, , 3-4,,". internal static int GetRangeItemListLength( string input, int startIndex, ICollection <RangeItemHeaderValue> rangeCollection) { Contract.Requires(rangeCollection != null); Contract.Requires(startIndex >= 0); Contract.Ensures((Contract.Result <int>() == 0) || (rangeCollection.Count > 0), "If we can parse the string, then we expect to have at least one range item."); if ((string.IsNullOrEmpty(input)) || (startIndex >= input.Length)) { return(0); } // Empty segments are allowed, so skip all delimiter-only segments (e.g. ", ,"). var separatorFound = false; var current = HeaderUtilities.GetNextNonEmptyOrWhitespaceIndex(input, startIndex, true, out separatorFound); // It's OK if we didn't find leading separator characters. Ignore 'separatorFound'. if (current == input.Length) { return(0); } RangeItemHeaderValue range = null; while (true) { var rangeLength = GetRangeItemLength(input, current, out range); if (rangeLength == 0) { return(0); } rangeCollection.Add(range); current = current + rangeLength; current = HeaderUtilities.GetNextNonEmptyOrWhitespaceIndex(input, current, true, out separatorFound); // If the string is not consumed, we must have a delimiter, otherwise the string is not a valid // range list. if ((current < input.Length) && !separatorFound) { return(0); } if (current == input.Length) { return(current - startIndex); } } }
private static bool TrySetOptionalTokenList( NameValueHeaderValue nameValue, ref bool boolField, ref ICollection <string> destination) { Contract.Requires(nameValue != null); if (nameValue.Value == null) { boolField = true; return(true); } // We need the string to be at least 3 chars long: 2x quotes and at least 1 character. Also make sure we // have a quoted string. Note that NameValueHeaderValue will never have leading/trailing whitespaces. var valueString = nameValue.Value; if ((valueString.Length < 3) || (valueString[0] != '\"') || (valueString[valueString.Length - 1] != '\"')) { return(false); } // We have a quoted string. Now verify that the string contains a list of valid tokens separated by ','. var current = 1; // skip the initial '"' character. var maxLength = valueString.Length - 1; // -1 because we don't want to parse the final '"'. var separatorFound = false; var originalValueCount = destination == null ? 0 : destination.Count; while (current < maxLength) { current = HeaderUtilities.GetNextNonEmptyOrWhitespaceIndex(valueString, current, true, out separatorFound); if (current == maxLength) { break; } var tokenLength = HttpRuleParser.GetTokenLength(valueString, current); if (tokenLength == 0) { // We already skipped whitespaces and separators. If we don't have a token it must be an invalid // character. return(false); } if (destination == null) { destination = new ObjectCollection <string>(CheckIsValidTokenAction); } destination.Add(valueString.Substring(current, tokenLength)); current = current + tokenLength; } // After parsing a valid token list, we expect to have at least one value if ((destination != null) && (destination.Count > originalValueCount)) { boolField = true; return(true); } return(false); }