| File: System\Net\Http\Headers\NameValueWithParametersHeaderValue.cs | Web Access |
| Project: src\runtime\src\libraries\System.Net.Http\src\System.Net.Http.csproj (System.Net.Http) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; namespace System.Net.Http.Headers { // According to the RFC, in places where a "parameter" is required, the value is mandatory // (e.g. Media-Type, Accept). However, we don't introduce a dedicated type for this. public class NameValueWithParametersHeaderValue : NameValueHeaderValue, ICloneable { private static readonly Func<NameValueHeaderValue> s_nameValueCreator = CreateNameValue; private UnvalidatedObjectCollection<NameValueHeaderValue>? _parameters; public ICollection<NameValueHeaderValue> Parameters => _parameters ??= new UnvalidatedObjectCollection<NameValueHeaderValue>(); public NameValueWithParametersHeaderValue(string name) : base(name) { } public NameValueWithParametersHeaderValue(string name, string? value) : base(name, value) { } internal NameValueWithParametersHeaderValue() { } protected NameValueWithParametersHeaderValue(NameValueWithParametersHeaderValue source) : base(source) { _parameters = source._parameters.Clone(); } public override bool Equals([NotNullWhen(true)] object? obj) { bool result = base.Equals(obj); if (result) { NameValueWithParametersHeaderValue? other = obj as NameValueWithParametersHeaderValue; if (other == null) { return false; } return HeaderUtilities.AreEqualCollections(_parameters, other._parameters); } return false; } public override int GetHashCode() { return base.GetHashCode() ^ NameValueHeaderValue.GetHashCode(_parameters); } public override string ToString() { string baseString = base.ToString(); StringBuilder sb = StringBuilderCache.Acquire(); sb.Append(baseString); NameValueHeaderValue.ToString(_parameters, ';', true, sb); return StringBuilderCache.GetStringAndRelease(sb); } public static new NameValueWithParametersHeaderValue Parse(string input) { int index = 0; return (NameValueWithParametersHeaderValue)GenericHeaderParser.SingleValueNameValueWithParametersParser .ParseValue(input, null, ref index); } public static bool TryParse([NotNullWhen(true)] string? input, [NotNullWhen(true)] out NameValueWithParametersHeaderValue? parsedValue) { int index = 0; parsedValue = null; if (GenericHeaderParser.SingleValueNameValueWithParametersParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (NameValueWithParametersHeaderValue)output!; return true; } return false; } internal static int GetNameValueWithParametersLength(string? input, int startIndex, out object? parsedValue) { Debug.Assert(input != null); Debug.Assert(startIndex >= 0); parsedValue = null; if (string.IsNullOrEmpty(input) || (startIndex >= input.Length)) { return 0; } int nameValueLength = NameValueHeaderValue.GetNameValueLength(input, startIndex, s_nameValueCreator, out NameValueHeaderValue? nameValue); if (nameValueLength == 0) { return 0; } int current = startIndex + nameValueLength; current += HttpRuleParser.GetWhitespaceLength(input, current); NameValueWithParametersHeaderValue? nameValueWithParameters = nameValue as NameValueWithParametersHeaderValue; Debug.Assert(nameValueWithParameters != null); // So far we have a valid name/value pair. Check if we have also parameters for the name/value pair. If // yes, parse parameters. E.g. something like "name=value; param1=value1; param2=value2". if ((current < input.Length) && (input[current] == ';')) { current++; // skip delimiter. int parameterLength = NameValueHeaderValue.GetNameValueListLength(input, current, ';', (UnvalidatedObjectCollection<NameValueHeaderValue>)nameValueWithParameters.Parameters); if (parameterLength == 0) { return 0; } parsedValue = nameValueWithParameters; return current + parameterLength - startIndex; } // We have a name/value pair without parameters. parsedValue = nameValueWithParameters; return current - startIndex; } private static NameValueHeaderValue CreateNameValue() { return new NameValueWithParametersHeaderValue(); } object ICloneable.Clone() { return new NameValueWithParametersHeaderValue(this); } } }