|
|
|
@ -4,8 +4,6 @@ |
|
|
|
* the license and the contributors participating to this project. |
|
|
|
*/ |
|
|
|
|
|
|
|
using System.Diagnostics; |
|
|
|
using System.Runtime.CompilerServices; |
|
|
|
using System.Runtime.InteropServices; |
|
|
|
using System.Runtime.Versioning; |
|
|
|
using System.Security.Cryptography.X509Certificates; |
|
|
|
@ -17,58 +15,6 @@ namespace OpenIddict.Extensions; |
|
|
|
/// </summary>
|
|
|
|
internal static class OpenIddictPolyfills |
|
|
|
{ |
|
|
|
extension(ArgumentOutOfRangeException) |
|
|
|
{ |
|
|
|
/// <summary>Throws an <see cref="ArgumentOutOfRangeException"/> if <paramref name="value"/> is negative.</summary>
|
|
|
|
/// <param name="value">The argument to validate as non-negative.</param>
|
|
|
|
/// <param name="paramName">The name of the parameter with which <paramref name="value"/> corresponds.</param>
|
|
|
|
public static void ThrowIfNegative<T>(T value, [CallerArgumentExpression(nameof(value))] string? paramName = null) |
|
|
|
where T : struct, IComparable<T> |
|
|
|
{ |
|
|
|
switch (value) |
|
|
|
{ |
|
|
|
case byte or ushort or uint or ulong or char: |
|
|
|
return; |
|
|
|
case sbyte n: |
|
|
|
if (n < 0) |
|
|
|
ThrowArgumentOutOfRangeException(paramName, value); |
|
|
|
return; |
|
|
|
case short n: |
|
|
|
if (n < 0) |
|
|
|
ThrowArgumentOutOfRangeException(paramName, value); |
|
|
|
return; |
|
|
|
case int n: |
|
|
|
if (n < 0) |
|
|
|
ThrowArgumentOutOfRangeException(paramName, value); |
|
|
|
return; |
|
|
|
case long n: |
|
|
|
if (n < 0L) |
|
|
|
ThrowArgumentOutOfRangeException(paramName, value); |
|
|
|
return; |
|
|
|
|
|
|
|
case float n: |
|
|
|
if (n < 0F) |
|
|
|
ThrowArgumentOutOfRangeException(paramName, value); |
|
|
|
return; |
|
|
|
case double n: |
|
|
|
if (n < 0D) |
|
|
|
ThrowArgumentOutOfRangeException(paramName, value); |
|
|
|
return; |
|
|
|
case decimal n: |
|
|
|
if (n < 0M) |
|
|
|
ThrowArgumentOutOfRangeException(paramName, value); |
|
|
|
return; |
|
|
|
default: |
|
|
|
throw new InvalidOperationException($"Invalid type '{typeof(T).AssemblyQualifiedName}' for {paramName}."); |
|
|
|
} |
|
|
|
|
|
|
|
static void ThrowArgumentOutOfRangeException(string? paramName, object value) |
|
|
|
{ |
|
|
|
throw new ArgumentOutOfRangeException(paramName, value, $"{paramName} ('{value}') must not be negative."); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
extension(Convert) |
|
|
|
{ |
|
|
|
#if !SUPPORTS_HEXADECIMAL_STRING_CONVERSION
|
|
|
|
@ -98,78 +44,6 @@ internal static class OpenIddictPolyfills |
|
|
|
#endif
|
|
|
|
} |
|
|
|
|
|
|
|
extension<TSource>(IEnumerable<TSource> source) |
|
|
|
{ |
|
|
|
#if !SUPPORTS_CHUNK_LINQ_EXTENSION
|
|
|
|
/// <summary>
|
|
|
|
/// Split the elements of a sequence into chunks of size at most <paramref name="size"/>.
|
|
|
|
/// </summary>
|
|
|
|
/// <remarks>
|
|
|
|
/// Every chunk except the last will be of size <paramref name="size"/>.
|
|
|
|
/// The last chunk will contain the remaining elements and may be of a smaller size.
|
|
|
|
/// </remarks>
|
|
|
|
/// <param name="size">Maximum size of each chunk.</param>
|
|
|
|
/// <returns>
|
|
|
|
/// An <see cref="IEnumerable{T}"/> that contains the elements of the input
|
|
|
|
/// sequence split into chunks of size <paramref name="size"/>.
|
|
|
|
/// </returns>
|
|
|
|
public IEnumerable<TSource[]> Chunk(int size) |
|
|
|
{ |
|
|
|
// Note: this polyfill was directly copied from .NET's source code:
|
|
|
|
// https://github.com/dotnet/runtime/blob/main/src/libraries/System.Linq/src/System/Linq/Chunk.cs.
|
|
|
|
|
|
|
|
using IEnumerator<TSource> enumerator = source.GetEnumerator(); |
|
|
|
|
|
|
|
if (enumerator.MoveNext()) |
|
|
|
{ |
|
|
|
var count = Math.Min(size, 4); |
|
|
|
int index; |
|
|
|
|
|
|
|
do |
|
|
|
{ |
|
|
|
var array = new TSource[count]; |
|
|
|
|
|
|
|
array[0] = enumerator.Current; |
|
|
|
index = 1; |
|
|
|
|
|
|
|
if (size != array.Length) |
|
|
|
{ |
|
|
|
for (; index < size && enumerator.MoveNext(); index++) |
|
|
|
{ |
|
|
|
if (index >= array.Length) |
|
|
|
{ |
|
|
|
count = (int) Math.Min((uint) size, 2 * (uint) array.Length); |
|
|
|
Array.Resize(ref array, count); |
|
|
|
} |
|
|
|
|
|
|
|
array[index] = enumerator.Current; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
{ |
|
|
|
var local = array; |
|
|
|
Debug.Assert(local.Length == size); |
|
|
|
for (; (uint) index < (uint) local.Length && enumerator.MoveNext(); index++) |
|
|
|
{ |
|
|
|
local[index] = enumerator.Current; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (index != array.Length) |
|
|
|
{ |
|
|
|
Array.Resize(ref array, index); |
|
|
|
} |
|
|
|
|
|
|
|
yield return array; |
|
|
|
} |
|
|
|
|
|
|
|
while (index >= size && enumerator.MoveNext()); |
|
|
|
} |
|
|
|
} |
|
|
|
#endif
|
|
|
|
} |
|
|
|
|
|
|
|
extension(OperatingSystem) |
|
|
|
{ |
|
|
|
#if !SUPPORTS_OPERATING_SYSTEM_VERSIONS_COMPARISON
|
|
|
|
|