| File: System\Net\Http\Headers\TransferCodingHeaderValue.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 { public class TransferCodingHeaderValue : ICloneable { // Use UnvalidatedObjectCollection<T> since we may have multiple parameters with the same name. private UnvalidatedObjectCollection<NameValueHeaderValue>? _parameters; private string _value = null!; // empty constructor only used internally and value set with non null public string Value => _value; public ICollection<NameValueHeaderValue> Parameters => _parameters ??= new UnvalidatedObjectCollection<NameValueHeaderValue>(); internal TransferCodingHeaderValue() { } protected TransferCodingHeaderValue(TransferCodingHeaderValue source) { Debug.Assert(source != null); _value = source._value; _parameters = source._parameters.Clone(); } public TransferCodingHeaderValue(string value) { HeaderUtilities.CheckValidToken(value); _value = value; } public static TransferCodingHeaderValue Parse(string input) { int index = 0; return (TransferCodingHeaderValue)TransferCodingHeaderParser.SingleValueParser.ParseValue( input, null, ref index); } public static bool TryParse([NotNullWhen(true)] string? input, [NotNullWhen(true)] out TransferCodingHeaderValue? parsedValue) { int index = 0; parsedValue = null; if (TransferCodingHeaderParser.SingleValueParser.TryParseValue(input, null, ref index, out object? output)) { parsedValue = (TransferCodingHeaderValue)output!; return true; } return false; } internal static int GetTransferCodingLength(string input, int startIndex, Func<TransferCodingHeaderValue> transferCodingCreator, out TransferCodingHeaderValue? parsedValue) { Debug.Assert(transferCodingCreator != null); Debug.Assert(startIndex >= 0); parsedValue = null; if (string.IsNullOrEmpty(input) || (startIndex >= input.Length)) { return 0; } // Caller must remove leading whitespace. If not, we'll return 0. int valueLength = HttpRuleParser.GetTokenLength(input, startIndex); if (valueLength == 0) { return 0; } string value = input.Substring(startIndex, valueLength); int current = startIndex + valueLength; current += HttpRuleParser.GetWhitespaceLength(input, current); TransferCodingHeaderValue transferCodingHeader; // If we're not done and we have a parameter delimiter, then we have a list of parameters. if ((current < input.Length) && (input[current] == ';')) { transferCodingHeader = transferCodingCreator(); transferCodingHeader._value = value; current++; // skip delimiter. int parameterLength = NameValueHeaderValue.GetNameValueListLength(input, current, ';', (UnvalidatedObjectCollection<NameValueHeaderValue>)transferCodingHeader.Parameters); if (parameterLength == 0) { return 0; } parsedValue = transferCodingHeader; return current + parameterLength - startIndex; } // We have a transfer coding without parameters. transferCodingHeader = transferCodingCreator(); transferCodingHeader._value = value; parsedValue = transferCodingHeader; return current - startIndex; } public override string ToString() { StringBuilder sb = StringBuilderCache.Acquire(); sb.Append(_value); NameValueHeaderValue.ToString(_parameters, ';', true, sb); return StringBuilderCache.GetStringAndRelease(sb); } public override bool Equals([NotNullWhen(true)] object? obj) { TransferCodingHeaderValue? other = obj as TransferCodingHeaderValue; if (other == null) { return false; } return string.Equals(_value, other._value, StringComparison.OrdinalIgnoreCase) && HeaderUtilities.AreEqualCollections(_parameters, other._parameters); } public override int GetHashCode() { // The value string is case-insensitive. return StringComparer.OrdinalIgnoreCase.GetHashCode(_value) ^ NameValueHeaderValue.GetHashCode(_parameters); } // Implement ICloneable explicitly to allow derived types to "override" the implementation. object ICloneable.Clone() { return new TransferCodingHeaderValue(this); } } }