internal static int GetHashCode(ObjectCollection <NameValueHeaderValue> values) { if ((values == null) || (values.Count == 0)) { return(0); } int result = 0; foreach (var value in values) { result = result ^ value.GetHashCode(); } return(result); }
private static void AppendValues(StringBuilder sb, ObjectCollection <string> values) { bool first = true; foreach (string value in values) { if (first) { first = false; } else { sb.Append(", "); } sb.Append(value); } }
internal static NameValueHeaderValue Find(ObjectCollection <NameValueHeaderValue> values, string name) { Contract.Requires((name != null) && (name.Length > 0)); if ((values == null) || (values.Count == 0)) { return(null); } foreach (var value in values) { if (string.Equals(value.Name, name, StringComparison.OrdinalIgnoreCase)) { return(value); } } return(null); }
internal static void ToString(ObjectCollection <NameValueHeaderValue> values, char separator, bool leadingSeparator, StringBuilder destination) { Debug.Assert(destination != null); if ((values == null) || (values.Count == 0)) { return; } foreach (var value in values) { if (leadingSeparator || (destination.Length > 0)) { destination.Append(separator); destination.Append(' '); } destination.Append(value.ToString()); } }
internal static double?GetQuality(ObjectCollection <NameValueHeaderValue> parameters) { Contract.Requires(parameters != null); NameValueHeaderValue qualityParameter = NameValueHeaderValue.Find(parameters, qualityName); if (qualityParameter != null) { // Note that the RFC requires decimal '.' regardless of the culture. I.e. using ',' as decimal // separator is considered invalid (even if the current culture would allow it). double qualityValue = 0; if (double.TryParse(qualityParameter.Value, NumberStyles.AllowDecimalPoint, NumberFormatInfo.InvariantInfo, out qualityValue)) { return(qualityValue); } // If the stored value is an invalid quality value, just return null and log a warning. UnityEngine.Debug.LogError(string.Format(System.Globalization.CultureInfo.InvariantCulture, "net_http_log_headers_invalid_quality: {0}", qualityParameter.Value)); } return(null); }
// Returns the length of a name/value list, separated by 'delimiter'. E.g. "a=b, c=d, e=f" adds 3 // name/value pairs to 'nameValueCollection' if 'delimiter' equals ','. internal static int GetNameValueListLength(string input, int startIndex, char delimiter, ObjectCollection <NameValueHeaderValue> nameValueCollection) { Contract.Requires(nameValueCollection != null); Contract.Requires(startIndex >= 0); if ((string.IsNullOrEmpty(input)) || (startIndex >= input.Length)) { return(0); } int current = startIndex + HttpRuleParser.GetWhitespaceLength(input, startIndex); while (true) { NameValueHeaderValue parameter = null; int nameValueLength = NameValueHeaderValue.GetNameValueLength(input, current, s_defaultNameValueCreator, out parameter); if (nameValueLength == 0) { return(0); } nameValueCollection.Add(parameter); current = current + nameValueLength; current = current + HttpRuleParser.GetWhitespaceLength(input, current); if ((current == input.Length) || (input[current] != delimiter)) { // We're done and we have at least one valid name/value pair. return(current - startIndex); } // input[current] is 'delimiter'. Skip the delimiter and whitespace and try to parse again. current++; // skip delimiter. current = current + HttpRuleParser.GetWhitespaceLength(input, current); } }
internal static void SetQuality(ObjectCollection <NameValueHeaderValue> parameters, double?value) { Contract.Requires(parameters != null); NameValueHeaderValue qualityParameter = NameValueHeaderValue.Find(parameters, qualityName); if (value.HasValue) { // Note that even if we check the value here, we can't prevent a user from adding an invalid quality // value using Parameters.Add(). Even if we would prevent the user from adding an invalid value // using Parameters.Add() he could always add invalid values using HttpHeaders.AddWithoutValidation(). // So this check is really for convenience to show users that they're trying to add an invalid // value. if ((value < 0) || (value > 1)) { throw new ArgumentOutOfRangeException(nameof(value)); } string qualityString = ((double)value).ToString("0.0##", NumberFormatInfo.InvariantInfo); if (qualityParameter != null) { qualityParameter.Value = qualityString; } else { parameters.Add(new NameValueHeaderValue(qualityName, qualityString)); } } else { // Remove quality parameter if (qualityParameter != null) { parameters.Remove(qualityParameter); } } }
private static bool TrySetOptionalTokenList(NameValueHeaderValue nameValue, ref bool boolField, ref ObjectCollection <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 whitespace. string 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 ','. int current = 1; // skip the initial '"' character. int maxLength = valueString.Length - 1; // -1 because we don't want to parse the final '"'. bool separatorFound = false; int originalValueCount = destination == null ? 0 : destination.Count; while (current < maxLength) { current = HeaderUtilities.GetNextNonEmptyOrWhitespaceIndex(valueString, current, true, out separatorFound); if (current == maxLength) { break; } int tokenLength = HttpRuleParser.GetTokenLength(valueString, current); if (tokenLength == 0) { // We already skipped whitespace and separators. If we don't have a token it must be an invalid // character. return(false); } if (destination == null) { destination = new ObjectCollection <string>(s_checkIsValidToken); } 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); }
internal static bool AreEqualCollections <T>(ObjectCollection <T> x, ObjectCollection <T> y, IEqualityComparer <T> comparer) where T : class { if (x == null) { return((y == null) || (y.Count == 0)); } if (y == null) { return(x.Count == 0); } if (x.Count != y.Count) { return(false); } if (x.Count == 0) { return(true); } // We have two unordered lists. So comparison is an O(n*m) operation which is expensive. Usually // headers have 1-2 parameters (if any), so this comparison shouldn't be too expensive. bool[] alreadyFound = new bool[x.Count]; int i = 0; foreach (var xItem in x) { Debug.Assert(xItem != null); i = 0; bool found = false; foreach (var yItem in y) { if (!alreadyFound[i]) { if (((comparer == null) && xItem.Equals(yItem)) || ((comparer != null) && comparer.Equals(xItem, yItem))) { alreadyFound[i] = true; found = true; break; } } i++; } if (!found) { return(false); } } // Since we never re-use a "found" value in 'y', we expect 'alreadyFound' to have all fields set to 'true'. // Otherwise the two collections can't be equal and we should not get here. Debug.Assert(Contract.ForAll(alreadyFound, value => { return(value); }), "Expected all values in 'alreadyFound' to be true since collections are considered equal."); return(true); }
internal static bool AreEqualCollections <T>(ObjectCollection <T> x, ObjectCollection <T> y) where T : class { return(AreEqualCollections(x, y, null)); }