-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This adds an HttpHeaders.NonValidated property, which returns a type that provides a non-validating / non-parsing / non-allocating view of headers in the collection. Querying the resulting collection does not force parsing or validation on the contents of the headers, handing back exactly the raw data that it contains; if a header doesn't contain a raw value but instead contains an already parsed value, a string representation of that header value(s) is returned. When using the strongly-typed members, querying and enumeration is allocation-free, unless strings need to be created to represent already parsed values.
- Loading branch information
1 parent
3188dcd
commit b2eb92d
Showing
15 changed files
with
616 additions
and
148 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
130 changes: 130 additions & 0 deletions
130
src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderStringValues.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
// 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; | ||
using System.Collections.Generic; | ||
|
||
namespace System.Net.Http.Headers | ||
{ | ||
/// <summary>Provides a collection of header string values.</summary> | ||
public readonly struct HeaderStringValues : IReadOnlyCollection<string> | ||
{ | ||
/// <summary>The associated header. This is used only for producing a string from <see cref="_value"/> when it's an array.</summary> | ||
private readonly HeaderDescriptor _header; | ||
/// <summary>A string or string array (or null if the instance is default).</summary> | ||
private readonly object _value; | ||
|
||
/// <summary>Initializes the instance.</summary> | ||
/// <param name="descriptor">The header descriptor associated with the header value.</param> | ||
/// <param name="value">The header value.</param> | ||
internal HeaderStringValues(HeaderDescriptor descriptor, string value) | ||
{ | ||
_header = descriptor; | ||
_value = value; | ||
} | ||
|
||
/// <summary>Initializes the instance.</summary> | ||
/// <param name="descriptor">The header descriptor associated with the header values.</param> | ||
/// <param name="values">The header values.</param> | ||
internal HeaderStringValues(HeaderDescriptor descriptor, string[] values) | ||
{ | ||
_header = descriptor; | ||
_value = values; | ||
} | ||
|
||
/// <summary>Gets the number of header values in the collection.</summary> | ||
public int Count => _value switch | ||
{ | ||
string => 1, | ||
string[] values => values.Length, | ||
_ => 0 | ||
}; | ||
|
||
/// <summary>Gets a string containing all the headers in the collection.</summary> | ||
/// <returns></returns> | ||
public override string ToString() => _value switch | ||
{ | ||
string value => value, | ||
string[] values => string.Join(_header.Parser is HttpHeaderParser parser && parser.SupportsMultipleValues ? parser.Separator : HttpHeaderParser.DefaultSeparator, values), | ||
_ => string.Empty, | ||
}; | ||
|
||
/// <summary>Gets an enumerator for all of the strings in the collection.</summary> | ||
/// <returns></returns> | ||
public Enumerator GetEnumerator() => new Enumerator(_value); | ||
|
||
/// <inheritdoc/> | ||
IEnumerator<string> IEnumerable<string>.GetEnumerator() => GetEnumerator(); | ||
|
||
/// <inheritdoc/> | ||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); | ||
|
||
/// <summary>Enumerates the elements of a <see cref="HeaderStringValues"/>.</summary> | ||
public struct Enumerator : IEnumerator<string> | ||
{ | ||
/// <summary>If this wraps a string[], that array. Otherwise, null.</summary> | ||
private readonly string[]? _values; | ||
/// <summary>The current string header value. If this wraps a single string, that string.</summary> | ||
private string? _current; | ||
/// <summary>Current state of the iteration.</summary> | ||
private int _index; | ||
|
||
/// <summary>Initializes the enumerator with a string or string[].</summary> | ||
/// <param name="value">The string or string[] value, or null if this collection is empty.</param> | ||
internal Enumerator(object value) | ||
{ | ||
if (value is string s) | ||
{ | ||
_values = null; | ||
_current = s; | ||
} | ||
else | ||
{ | ||
_values = value as string[]; | ||
_current = null; | ||
} | ||
|
||
_index = 0; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public bool MoveNext() | ||
{ | ||
int index = _index; | ||
if (index < 0) | ||
{ | ||
return false; | ||
} | ||
|
||
string[]? values = _values; | ||
if (values != null) | ||
{ | ||
if ((uint)index < (uint)values.Length) | ||
{ | ||
_index = index + 1; | ||
_current = values[index]; | ||
return true; | ||
} | ||
|
||
_index = -1; | ||
return false; | ||
} | ||
|
||
_index = -1; | ||
return _current != null; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public string Current => _current!; | ||
|
||
/// <inheritdoc/> | ||
object IEnumerator.Current => Current; | ||
|
||
/// <inheritdoc/> | ||
public void Dispose() { } | ||
|
||
/// <inheritdoc/> | ||
void IEnumerator.Reset() => throw new NotSupportedException(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.