initial commit
This commit is contained in:
BIN
Binary file not shown.
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype"><value>text/microsoft-resx</value></resheader><resheader name="version"><value>1.3</value></resheader><resheader name="reader"><value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader><resheader name="writer"><value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value></resheader><data name="Argument_CannotParsePrecision" xml:space="preserve"><value>Characters following the format symbol must be a number of {0} or less.</value></data>
|
||||
<data name="UnexpectedSegmentType" xml:space="preserve"><value>Unexpected segment type.</value></data>
|
||||
<data name="Argument_GWithPrecisionNotSupported" xml:space="preserve"><value>The 'G' format combined with a precision is not supported.</value></data>
|
||||
<data name="OutstandingReferences" xml:space="preserve"><value>Release all references before disposing this instance.</value></data>
|
||||
<data name="Argument_PrecisionTooLarge" xml:space="preserve"><value>Precision cannot be larger than {0}.</value></data>
|
||||
<data name="MemoryDisposed" xml:space="preserve"><value>Memory<T> has been disposed.</value></data>
|
||||
<data name="Argument_BadFormatSpecifier" xml:space="preserve"><value>Format specifier was invalid.</value></data>
|
||||
<data name="Argument_OverlapAlignmentMismatch" xml:space="preserve"><value>Overlapping spans have mismatching alignment.</value></data>
|
||||
<data name="Argument_DestinationTooShort" xml:space="preserve"><value>Destination is too short.</value></data>
|
||||
<data name="NotSupported_CannotCallGetHashCodeOnSpan" xml:space="preserve"><value>GetHashCode() on Span and ReadOnlySpan is not supported.</value></data>
|
||||
<data name="EndPositionNotReached" xml:space="preserve"><value>End position was not reached during enumeration.</value></data>
|
||||
<data name="NotSupported_CannotCallEqualsOnSpan" xml:space="preserve"><value>Equals() on Span and ReadOnlySpan is not supported. Use operator== instead.</value></data>
|
||||
<data name="Argument_InvalidTypeWithPointersNotSupported" xml:space="preserve"><value>Cannot use type '{0}'. Only value types without pointers or references are supported.</value></data>
|
||||
</root>
|
||||
@@ -0,0 +1,5 @@
|
||||
namespace FxResources.System.Memory;
|
||||
|
||||
internal static class SR
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
|
||||
[assembly: NeutralResourcesLanguage("en-US")]
|
||||
[assembly: AssemblyTitle("System.Memory")]
|
||||
[assembly: AssemblyDescription("System.Memory")]
|
||||
[assembly: AssemblyDefaultAlias("System.Memory")]
|
||||
[assembly: AssemblyCompany("Microsoft Corporation")]
|
||||
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
|
||||
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
|
||||
[assembly: AssemblyFileVersion("4.6.31308.01")]
|
||||
[assembly: AssemblyInformationalVersion("4.6.31308.01 @BuiltBy: cloudtest-841353dfc000000 @Branch: release/2.1-MSRC @SrcCode: https://github.com/dotnet/corefx/tree/32b491939fbd125f304031c35038b1e14b4e3958")]
|
||||
[assembly: CLSCompliant(true)]
|
||||
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
|
||||
[assembly: AssemblyMetadata("Serviceable", "True")]
|
||||
[assembly: AssemblyMetadata("PreferInbox", "True")]
|
||||
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
|
||||
[assembly: AssemblyVersion("4.0.1.2")]
|
||||
@@ -0,0 +1,589 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System.Buffers.Binary;
|
||||
|
||||
public static class BinaryPrimitives
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static sbyte ReverseEndianness(sbyte value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static short ReverseEndianness(short value)
|
||||
{
|
||||
return (short)(((value & 0xFF) << 8) | ((value & 0xFF00) >> 8));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int ReverseEndianness(int value)
|
||||
{
|
||||
return (int)ReverseEndianness((uint)value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long ReverseEndianness(long value)
|
||||
{
|
||||
return (long)ReverseEndianness((ulong)value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte ReverseEndianness(byte value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static ushort ReverseEndianness(ushort value)
|
||||
{
|
||||
return (ushort)((value >> 8) + (value << 8));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static uint ReverseEndianness(uint value)
|
||||
{
|
||||
uint num = value & 0xFF00FF;
|
||||
uint num2 = value & 0xFF00FF00u;
|
||||
return ((num >> 8) | (num << 24)) + ((num2 << 8) | (num2 >> 24));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static ulong ReverseEndianness(ulong value)
|
||||
{
|
||||
return ((ulong)ReverseEndianness((uint)value) << 32) + ReverseEndianness((uint)(value >> 32));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static short ReadInt16BigEndian(ReadOnlySpan<byte> source)
|
||||
{
|
||||
short num = MemoryMarshal.Read<short>(source);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
num = ReverseEndianness(num);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int ReadInt32BigEndian(ReadOnlySpan<byte> source)
|
||||
{
|
||||
int num = MemoryMarshal.Read<int>(source);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
num = ReverseEndianness(num);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long ReadInt64BigEndian(ReadOnlySpan<byte> source)
|
||||
{
|
||||
long num = MemoryMarshal.Read<long>(source);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
num = ReverseEndianness(num);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static ushort ReadUInt16BigEndian(ReadOnlySpan<byte> source)
|
||||
{
|
||||
ushort num = MemoryMarshal.Read<ushort>(source);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
num = ReverseEndianness(num);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static uint ReadUInt32BigEndian(ReadOnlySpan<byte> source)
|
||||
{
|
||||
uint num = MemoryMarshal.Read<uint>(source);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
num = ReverseEndianness(num);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static ulong ReadUInt64BigEndian(ReadOnlySpan<byte> source)
|
||||
{
|
||||
ulong num = MemoryMarshal.Read<ulong>(source);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
num = ReverseEndianness(num);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryReadInt16BigEndian(ReadOnlySpan<byte> source, out short value)
|
||||
{
|
||||
bool result = MemoryMarshal.TryRead<short>(source, out value);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryReadInt32BigEndian(ReadOnlySpan<byte> source, out int value)
|
||||
{
|
||||
bool result = MemoryMarshal.TryRead<int>(source, out value);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryReadInt64BigEndian(ReadOnlySpan<byte> source, out long value)
|
||||
{
|
||||
bool result = MemoryMarshal.TryRead<long>(source, out value);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static bool TryReadUInt16BigEndian(ReadOnlySpan<byte> source, out ushort value)
|
||||
{
|
||||
bool result = MemoryMarshal.TryRead<ushort>(source, out value);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static bool TryReadUInt32BigEndian(ReadOnlySpan<byte> source, out uint value)
|
||||
{
|
||||
bool result = MemoryMarshal.TryRead<uint>(source, out value);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static bool TryReadUInt64BigEndian(ReadOnlySpan<byte> source, out ulong value)
|
||||
{
|
||||
bool result = MemoryMarshal.TryRead<ulong>(source, out value);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static short ReadInt16LittleEndian(ReadOnlySpan<byte> source)
|
||||
{
|
||||
short num = MemoryMarshal.Read<short>(source);
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
num = ReverseEndianness(num);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int ReadInt32LittleEndian(ReadOnlySpan<byte> source)
|
||||
{
|
||||
int num = MemoryMarshal.Read<int>(source);
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
num = ReverseEndianness(num);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long ReadInt64LittleEndian(ReadOnlySpan<byte> source)
|
||||
{
|
||||
long num = MemoryMarshal.Read<long>(source);
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
num = ReverseEndianness(num);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static ushort ReadUInt16LittleEndian(ReadOnlySpan<byte> source)
|
||||
{
|
||||
ushort num = MemoryMarshal.Read<ushort>(source);
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
num = ReverseEndianness(num);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static uint ReadUInt32LittleEndian(ReadOnlySpan<byte> source)
|
||||
{
|
||||
uint num = MemoryMarshal.Read<uint>(source);
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
num = ReverseEndianness(num);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static ulong ReadUInt64LittleEndian(ReadOnlySpan<byte> source)
|
||||
{
|
||||
ulong num = MemoryMarshal.Read<ulong>(source);
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
num = ReverseEndianness(num);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryReadInt16LittleEndian(ReadOnlySpan<byte> source, out short value)
|
||||
{
|
||||
bool result = MemoryMarshal.TryRead<short>(source, out value);
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryReadInt32LittleEndian(ReadOnlySpan<byte> source, out int value)
|
||||
{
|
||||
bool result = MemoryMarshal.TryRead<int>(source, out value);
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryReadInt64LittleEndian(ReadOnlySpan<byte> source, out long value)
|
||||
{
|
||||
bool result = MemoryMarshal.TryRead<long>(source, out value);
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static bool TryReadUInt16LittleEndian(ReadOnlySpan<byte> source, out ushort value)
|
||||
{
|
||||
bool result = MemoryMarshal.TryRead<ushort>(source, out value);
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static bool TryReadUInt32LittleEndian(ReadOnlySpan<byte> source, out uint value)
|
||||
{
|
||||
bool result = MemoryMarshal.TryRead<uint>(source, out value);
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static bool TryReadUInt64LittleEndian(ReadOnlySpan<byte> source, out ulong value)
|
||||
{
|
||||
bool result = MemoryMarshal.TryRead<ulong>(source, out value);
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteInt16BigEndian(Span<byte> destination, short value)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
MemoryMarshal.Write(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteInt32BigEndian(Span<byte> destination, int value)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
MemoryMarshal.Write(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteInt64BigEndian(Span<byte> destination, long value)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
MemoryMarshal.Write(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static void WriteUInt16BigEndian(Span<byte> destination, ushort value)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
MemoryMarshal.Write(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static void WriteUInt32BigEndian(Span<byte> destination, uint value)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
MemoryMarshal.Write(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static void WriteUInt64BigEndian(Span<byte> destination, ulong value)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
MemoryMarshal.Write(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryWriteInt16BigEndian(Span<byte> destination, short value)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryWriteInt32BigEndian(Span<byte> destination, int value)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryWriteInt64BigEndian(Span<byte> destination, long value)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static bool TryWriteUInt16BigEndian(Span<byte> destination, ushort value)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static bool TryWriteUInt32BigEndian(Span<byte> destination, uint value)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static bool TryWriteUInt64BigEndian(Span<byte> destination, ulong value)
|
||||
{
|
||||
if (BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteInt16LittleEndian(Span<byte> destination, short value)
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
MemoryMarshal.Write(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteInt32LittleEndian(Span<byte> destination, int value)
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
MemoryMarshal.Write(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteInt64LittleEndian(Span<byte> destination, long value)
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
MemoryMarshal.Write(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static void WriteUInt16LittleEndian(Span<byte> destination, ushort value)
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
MemoryMarshal.Write(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static void WriteUInt32LittleEndian(Span<byte> destination, uint value)
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
MemoryMarshal.Write(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static void WriteUInt64LittleEndian(Span<byte> destination, ulong value)
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
MemoryMarshal.Write(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryWriteInt16LittleEndian(Span<byte> destination, short value)
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryWriteInt32LittleEndian(Span<byte> destination, int value)
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryWriteInt64LittleEndian(Span<byte> destination, long value)
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static bool TryWriteUInt16LittleEndian(Span<byte> destination, ushort value)
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static bool TryWriteUInt32LittleEndian(Span<byte> destination, uint value)
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public static bool TryWriteUInt64LittleEndian(Span<byte> destination, ulong value)
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
value = ReverseEndianness(value);
|
||||
}
|
||||
return MemoryMarshal.TryWrite(destination, ref value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,421 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System.Buffers.Text;
|
||||
|
||||
public static class Base64
|
||||
{
|
||||
private static readonly sbyte[] s_decodingMap = new sbyte[256]
|
||||
{
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, 62, -1, -1, -1, 63, 52, 53,
|
||||
54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
|
||||
-1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
|
||||
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
|
||||
29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
|
||||
39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
private static readonly byte[] s_encodingMap = new byte[64]
|
||||
{
|
||||
65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
|
||||
75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
|
||||
85, 86, 87, 88, 89, 90, 97, 98, 99, 100,
|
||||
101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
|
||||
111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
|
||||
121, 122, 48, 49, 50, 51, 52, 53, 54, 55,
|
||||
56, 57, 43, 47
|
||||
};
|
||||
|
||||
private const byte EncodingPad = 61;
|
||||
|
||||
private const int MaximumEncodeLength = 1610612733;
|
||||
|
||||
public static OperationStatus DecodeFromUtf8(ReadOnlySpan<byte> utf8, Span<byte> bytes, out int bytesConsumed, out int bytesWritten, bool isFinalBlock = true)
|
||||
{
|
||||
ref byte reference = ref MemoryMarshal.GetReference(utf8);
|
||||
ref byte reference2 = ref MemoryMarshal.GetReference(bytes);
|
||||
int num = utf8.Length & -4;
|
||||
int length = bytes.Length;
|
||||
int num2 = 0;
|
||||
int num3 = 0;
|
||||
if (utf8.Length != 0)
|
||||
{
|
||||
ref sbyte reference3 = ref s_decodingMap[0];
|
||||
int num4 = (isFinalBlock ? 4 : 0);
|
||||
int num5 = 0;
|
||||
num5 = ((length < GetMaxDecodedFromUtf8Length(num)) ? (length / 3 * 4) : (num - num4));
|
||||
while (true)
|
||||
{
|
||||
if (num2 < num5)
|
||||
{
|
||||
int num6 = Decode(ref Unsafe.Add(ref reference, num2), ref reference3);
|
||||
if (num6 >= 0)
|
||||
{
|
||||
WriteThreeLowOrderBytes(ref Unsafe.Add(ref reference2, num3), num6);
|
||||
num3 += 3;
|
||||
num2 += 4;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (num5 != num - num4)
|
||||
{
|
||||
goto IL_0205;
|
||||
}
|
||||
if (num2 == num)
|
||||
{
|
||||
if (!isFinalBlock)
|
||||
{
|
||||
bytesConsumed = num2;
|
||||
bytesWritten = num3;
|
||||
return OperationStatus.NeedMoreData;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int elementOffset = Unsafe.Add(ref reference, num - 4);
|
||||
int elementOffset2 = Unsafe.Add(ref reference, num - 3);
|
||||
int num7 = Unsafe.Add(ref reference, num - 2);
|
||||
int num8 = Unsafe.Add(ref reference, num - 1);
|
||||
elementOffset = Unsafe.Add(ref reference3, elementOffset);
|
||||
elementOffset2 = Unsafe.Add(ref reference3, elementOffset2);
|
||||
elementOffset <<= 18;
|
||||
elementOffset2 <<= 12;
|
||||
elementOffset |= elementOffset2;
|
||||
if (num8 != 61)
|
||||
{
|
||||
num7 = Unsafe.Add(ref reference3, num7);
|
||||
num8 = Unsafe.Add(ref reference3, num8);
|
||||
num7 <<= 6;
|
||||
elementOffset |= num8;
|
||||
elementOffset |= num7;
|
||||
if (elementOffset >= 0)
|
||||
{
|
||||
if (num3 <= length - 3)
|
||||
{
|
||||
WriteThreeLowOrderBytes(ref Unsafe.Add(ref reference2, num3), elementOffset);
|
||||
num3 += 3;
|
||||
goto IL_01eb;
|
||||
}
|
||||
goto IL_0205;
|
||||
}
|
||||
}
|
||||
else if (num7 != 61)
|
||||
{
|
||||
num7 = Unsafe.Add(ref reference3, num7);
|
||||
num7 <<= 6;
|
||||
elementOffset |= num7;
|
||||
if (elementOffset >= 0)
|
||||
{
|
||||
if (num3 <= length - 2)
|
||||
{
|
||||
Unsafe.Add(ref reference2, num3) = (byte)(elementOffset >> 16);
|
||||
Unsafe.Add(ref reference2, num3 + 1) = (byte)(elementOffset >> 8);
|
||||
num3 += 2;
|
||||
goto IL_01eb;
|
||||
}
|
||||
goto IL_0205;
|
||||
}
|
||||
}
|
||||
else if (elementOffset >= 0)
|
||||
{
|
||||
if (num3 <= length - 1)
|
||||
{
|
||||
Unsafe.Add(ref reference2, num3) = (byte)(elementOffset >> 16);
|
||||
num3++;
|
||||
goto IL_01eb;
|
||||
}
|
||||
goto IL_0205;
|
||||
}
|
||||
}
|
||||
}
|
||||
goto IL_022b;
|
||||
IL_01eb:
|
||||
num2 += 4;
|
||||
if (num == utf8.Length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
goto IL_022b;
|
||||
IL_022b:
|
||||
bytesConsumed = num2;
|
||||
bytesWritten = num3;
|
||||
return OperationStatus.InvalidData;
|
||||
IL_0205:
|
||||
if (!(num != utf8.Length && isFinalBlock))
|
||||
{
|
||||
bytesConsumed = num2;
|
||||
bytesWritten = num3;
|
||||
return OperationStatus.DestinationTooSmall;
|
||||
}
|
||||
goto IL_022b;
|
||||
}
|
||||
}
|
||||
bytesConsumed = num2;
|
||||
bytesWritten = num3;
|
||||
return OperationStatus.Done;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int GetMaxDecodedFromUtf8Length(int length)
|
||||
{
|
||||
if (length < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
|
||||
}
|
||||
return (length >> 2) * 3;
|
||||
}
|
||||
|
||||
public static OperationStatus DecodeFromUtf8InPlace(Span<byte> buffer, out int bytesWritten)
|
||||
{
|
||||
int length = buffer.Length;
|
||||
int num = 0;
|
||||
int num2 = 0;
|
||||
if (length == (length >> 2) * 4)
|
||||
{
|
||||
if (length == 0)
|
||||
{
|
||||
goto IL_016d;
|
||||
}
|
||||
ref byte reference = ref MemoryMarshal.GetReference(buffer);
|
||||
ref sbyte reference2 = ref s_decodingMap[0];
|
||||
while (num < length - 4)
|
||||
{
|
||||
int num3 = Decode(ref Unsafe.Add(ref reference, num), ref reference2);
|
||||
if (num3 >= 0)
|
||||
{
|
||||
WriteThreeLowOrderBytes(ref Unsafe.Add(ref reference, num2), num3);
|
||||
num2 += 3;
|
||||
num += 4;
|
||||
continue;
|
||||
}
|
||||
goto IL_0172;
|
||||
}
|
||||
int elementOffset = Unsafe.Add(ref reference, length - 4);
|
||||
int elementOffset2 = Unsafe.Add(ref reference, length - 3);
|
||||
int num4 = Unsafe.Add(ref reference, length - 2);
|
||||
int num5 = Unsafe.Add(ref reference, length - 1);
|
||||
elementOffset = Unsafe.Add(ref reference2, elementOffset);
|
||||
elementOffset2 = Unsafe.Add(ref reference2, elementOffset2);
|
||||
elementOffset <<= 18;
|
||||
elementOffset2 <<= 12;
|
||||
elementOffset |= elementOffset2;
|
||||
if (num5 != 61)
|
||||
{
|
||||
num4 = Unsafe.Add(ref reference2, num4);
|
||||
num5 = Unsafe.Add(ref reference2, num5);
|
||||
num4 <<= 6;
|
||||
elementOffset |= num5;
|
||||
elementOffset |= num4;
|
||||
if (elementOffset >= 0)
|
||||
{
|
||||
WriteThreeLowOrderBytes(ref Unsafe.Add(ref reference, num2), elementOffset);
|
||||
num2 += 3;
|
||||
goto IL_016d;
|
||||
}
|
||||
}
|
||||
else if (num4 != 61)
|
||||
{
|
||||
num4 = Unsafe.Add(ref reference2, num4);
|
||||
num4 <<= 6;
|
||||
elementOffset |= num4;
|
||||
if (elementOffset >= 0)
|
||||
{
|
||||
Unsafe.Add(ref reference, num2) = (byte)(elementOffset >> 16);
|
||||
Unsafe.Add(ref reference, num2 + 1) = (byte)(elementOffset >> 8);
|
||||
num2 += 2;
|
||||
goto IL_016d;
|
||||
}
|
||||
}
|
||||
else if (elementOffset >= 0)
|
||||
{
|
||||
Unsafe.Add(ref reference, num2) = (byte)(elementOffset >> 16);
|
||||
num2++;
|
||||
goto IL_016d;
|
||||
}
|
||||
}
|
||||
goto IL_0172;
|
||||
IL_0172:
|
||||
bytesWritten = num2;
|
||||
return OperationStatus.InvalidData;
|
||||
IL_016d:
|
||||
bytesWritten = num2;
|
||||
return OperationStatus.Done;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int Decode(ref byte encodedBytes, ref sbyte decodingMap)
|
||||
{
|
||||
int elementOffset = encodedBytes;
|
||||
int elementOffset2 = Unsafe.Add(ref encodedBytes, 1);
|
||||
int elementOffset3 = Unsafe.Add(ref encodedBytes, 2);
|
||||
int elementOffset4 = Unsafe.Add(ref encodedBytes, 3);
|
||||
elementOffset = Unsafe.Add(ref decodingMap, elementOffset);
|
||||
elementOffset2 = Unsafe.Add(ref decodingMap, elementOffset2);
|
||||
elementOffset3 = Unsafe.Add(ref decodingMap, elementOffset3);
|
||||
elementOffset4 = Unsafe.Add(ref decodingMap, elementOffset4);
|
||||
elementOffset <<= 18;
|
||||
elementOffset2 <<= 12;
|
||||
elementOffset3 <<= 6;
|
||||
elementOffset |= elementOffset4;
|
||||
elementOffset2 |= elementOffset3;
|
||||
return elementOffset | elementOffset2;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void WriteThreeLowOrderBytes(ref byte destination, int value)
|
||||
{
|
||||
destination = (byte)(value >> 16);
|
||||
Unsafe.Add(ref destination, 1) = (byte)(value >> 8);
|
||||
Unsafe.Add(ref destination, 2) = (byte)value;
|
||||
}
|
||||
|
||||
public static OperationStatus EncodeToUtf8(ReadOnlySpan<byte> bytes, Span<byte> utf8, out int bytesConsumed, out int bytesWritten, bool isFinalBlock = true)
|
||||
{
|
||||
ref byte reference = ref MemoryMarshal.GetReference(bytes);
|
||||
ref byte reference2 = ref MemoryMarshal.GetReference(utf8);
|
||||
int length = bytes.Length;
|
||||
int length2 = utf8.Length;
|
||||
int num = 0;
|
||||
num = ((length > 1610612733 || length2 < GetMaxEncodedToUtf8Length(length)) ? ((length2 >> 2) * 3 - 2) : (length - 2));
|
||||
int i = 0;
|
||||
int num2 = 0;
|
||||
int num3 = 0;
|
||||
ref byte encodingMap = ref s_encodingMap[0];
|
||||
for (; i < num; i += 3)
|
||||
{
|
||||
num3 = Encode(ref Unsafe.Add(ref reference, i), ref encodingMap);
|
||||
Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference2, num2), num3);
|
||||
num2 += 4;
|
||||
}
|
||||
if (num == length - 2)
|
||||
{
|
||||
if (isFinalBlock)
|
||||
{
|
||||
if (i == length - 1)
|
||||
{
|
||||
num3 = EncodeAndPadTwo(ref Unsafe.Add(ref reference, i), ref encodingMap);
|
||||
Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference2, num2), num3);
|
||||
num2 += 4;
|
||||
i++;
|
||||
}
|
||||
else if (i == length - 2)
|
||||
{
|
||||
num3 = EncodeAndPadOne(ref Unsafe.Add(ref reference, i), ref encodingMap);
|
||||
Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference2, num2), num3);
|
||||
num2 += 4;
|
||||
i += 2;
|
||||
}
|
||||
bytesConsumed = i;
|
||||
bytesWritten = num2;
|
||||
return OperationStatus.Done;
|
||||
}
|
||||
bytesConsumed = i;
|
||||
bytesWritten = num2;
|
||||
return OperationStatus.NeedMoreData;
|
||||
}
|
||||
bytesConsumed = i;
|
||||
bytesWritten = num2;
|
||||
return OperationStatus.DestinationTooSmall;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int GetMaxEncodedToUtf8Length(int length)
|
||||
{
|
||||
if ((uint)length > 1610612733u)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
|
||||
}
|
||||
return (length + 2) / 3 * 4;
|
||||
}
|
||||
|
||||
public static OperationStatus EncodeToUtf8InPlace(Span<byte> buffer, int dataLength, out int bytesWritten)
|
||||
{
|
||||
int maxEncodedToUtf8Length = GetMaxEncodedToUtf8Length(dataLength);
|
||||
if (buffer.Length >= maxEncodedToUtf8Length)
|
||||
{
|
||||
int num = dataLength - dataLength / 3 * 3;
|
||||
int num2 = maxEncodedToUtf8Length - 4;
|
||||
int num3 = dataLength - num;
|
||||
int num4 = 0;
|
||||
ref byte encodingMap = ref s_encodingMap[0];
|
||||
ref byte reference = ref MemoryMarshal.GetReference(buffer);
|
||||
switch (num)
|
||||
{
|
||||
case 1:
|
||||
num4 = EncodeAndPadTwo(ref Unsafe.Add(ref reference, num3), ref encodingMap);
|
||||
Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference, num2), num4);
|
||||
num2 -= 4;
|
||||
break;
|
||||
default:
|
||||
num4 = EncodeAndPadOne(ref Unsafe.Add(ref reference, num3), ref encodingMap);
|
||||
Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference, num2), num4);
|
||||
num2 -= 4;
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
for (num3 -= 3; num3 >= 0; num3 -= 3)
|
||||
{
|
||||
num4 = Encode(ref Unsafe.Add(ref reference, num3), ref encodingMap);
|
||||
Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference, num2), num4);
|
||||
num2 -= 4;
|
||||
}
|
||||
bytesWritten = maxEncodedToUtf8Length;
|
||||
return OperationStatus.Done;
|
||||
}
|
||||
bytesWritten = 0;
|
||||
return OperationStatus.DestinationTooSmall;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int Encode(ref byte threeBytes, ref byte encodingMap)
|
||||
{
|
||||
int num = (threeBytes << 16) | (Unsafe.Add(ref threeBytes, 1) << 8) | Unsafe.Add(ref threeBytes, 2);
|
||||
int num2 = Unsafe.Add(ref encodingMap, num >> 18);
|
||||
int num3 = Unsafe.Add(ref encodingMap, (num >> 12) & 0x3F);
|
||||
int num4 = Unsafe.Add(ref encodingMap, (num >> 6) & 0x3F);
|
||||
int num5 = Unsafe.Add(ref encodingMap, num & 0x3F);
|
||||
return num2 | (num3 << 8) | (num4 << 16) | (num5 << 24);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int EncodeAndPadOne(ref byte twoBytes, ref byte encodingMap)
|
||||
{
|
||||
int num = (twoBytes << 16) | (Unsafe.Add(ref twoBytes, 1) << 8);
|
||||
int num2 = Unsafe.Add(ref encodingMap, num >> 18);
|
||||
int num3 = Unsafe.Add(ref encodingMap, (num >> 12) & 0x3F);
|
||||
int num4 = Unsafe.Add(ref encodingMap, (num >> 6) & 0x3F);
|
||||
return num2 | (num3 << 8) | (num4 << 16) | 0x3D000000;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int EncodeAndPadTwo(ref byte oneByte, ref byte encodingMap)
|
||||
{
|
||||
int num = oneByte << 8;
|
||||
int num2 = Unsafe.Add(ref encodingMap, num >> 10);
|
||||
int num3 = Unsafe.Add(ref encodingMap, (num >> 4) & 0x3F);
|
||||
return num2 | (num3 << 8) | 0x3D0000 | 0x3D000000;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System.Buffers.Text;
|
||||
|
||||
internal static class FormattingHelpers
|
||||
{
|
||||
public enum HexCasing : uint
|
||||
{
|
||||
Uppercase = 0u,
|
||||
Lowercase = 8224u
|
||||
}
|
||||
|
||||
internal const string HexTableLower = "0123456789abcdef";
|
||||
|
||||
internal const string HexTableUpper = "0123456789ABCDEF";
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static char GetSymbolOrDefault(in StandardFormat format, char defaultSymbol)
|
||||
{
|
||||
char c = format.Symbol;
|
||||
if (c == '\0' && format.Precision == 0)
|
||||
{
|
||||
c = defaultSymbol;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void FillWithAsciiZeros(Span<byte> buffer)
|
||||
{
|
||||
for (int i = 0; i < buffer.Length; i++)
|
||||
{
|
||||
buffer[i] = 48;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteHexByte(byte value, Span<byte> buffer, int startingIndex = 0, HexCasing casing = HexCasing.Uppercase)
|
||||
{
|
||||
uint num = (uint)(((value & 0xF0) << 4) + (value & 0xF) - 35209);
|
||||
uint num2 = ((((0 - num) & 0x7070) >> 4) + num + 47545) | (uint)casing;
|
||||
buffer[startingIndex + 1] = (byte)num2;
|
||||
buffer[startingIndex] = (byte)(num2 >> 8);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteDigits(ulong value, Span<byte> buffer)
|
||||
{
|
||||
for (int num = buffer.Length - 1; num >= 1; num--)
|
||||
{
|
||||
ulong num2 = 48 + value;
|
||||
value /= 10;
|
||||
buffer[num] = (byte)(num2 - value * 10);
|
||||
}
|
||||
buffer[0] = (byte)(48 + value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteDigitsWithGroupSeparator(ulong value, Span<byte> buffer)
|
||||
{
|
||||
int num = 0;
|
||||
for (int num2 = buffer.Length - 1; num2 >= 1; num2--)
|
||||
{
|
||||
ulong num3 = 48 + value;
|
||||
value /= 10;
|
||||
buffer[num2] = (byte)(num3 - value * 10);
|
||||
if (num == 2)
|
||||
{
|
||||
buffer[--num2] = 44;
|
||||
num = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
num++;
|
||||
}
|
||||
}
|
||||
buffer[0] = (byte)(48 + value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteDigits(uint value, Span<byte> buffer)
|
||||
{
|
||||
for (int num = buffer.Length - 1; num >= 1; num--)
|
||||
{
|
||||
uint num2 = 48 + value;
|
||||
value /= 10;
|
||||
buffer[num] = (byte)(num2 - value * 10);
|
||||
}
|
||||
buffer[0] = (byte)(48 + value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteFourDecimalDigits(uint value, Span<byte> buffer, int startingIndex = 0)
|
||||
{
|
||||
uint num = 48 + value;
|
||||
value /= 10;
|
||||
buffer[startingIndex + 3] = (byte)(num - value * 10);
|
||||
num = 48 + value;
|
||||
value /= 10;
|
||||
buffer[startingIndex + 2] = (byte)(num - value * 10);
|
||||
num = 48 + value;
|
||||
value /= 10;
|
||||
buffer[startingIndex + 1] = (byte)(num - value * 10);
|
||||
buffer[startingIndex] = (byte)(48 + value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void WriteTwoDecimalDigits(uint value, Span<byte> buffer, int startingIndex = 0)
|
||||
{
|
||||
uint num = 48 + value;
|
||||
value /= 10;
|
||||
buffer[startingIndex + 1] = (byte)(num - value * 10);
|
||||
buffer[startingIndex] = (byte)(48 + value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong DivMod(ulong numerator, ulong denominator, out ulong modulo)
|
||||
{
|
||||
ulong num = numerator / denominator;
|
||||
modulo = numerator - num * denominator;
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint DivMod(uint numerator, uint denominator, out uint modulo)
|
||||
{
|
||||
uint num = numerator / denominator;
|
||||
modulo = numerator - num * denominator;
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int CountDecimalTrailingZeros(uint value, out uint valueWithoutTrailingZeros)
|
||||
{
|
||||
int num = 0;
|
||||
if (value != 0)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
uint modulo;
|
||||
uint num2 = DivMod(value, 10u, out modulo);
|
||||
if (modulo != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
value = num2;
|
||||
num++;
|
||||
}
|
||||
}
|
||||
valueWithoutTrailingZeros = value;
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int CountDigits(ulong value)
|
||||
{
|
||||
int num = 1;
|
||||
uint num2;
|
||||
if (value >= 10000000)
|
||||
{
|
||||
if (value >= 100000000000000L)
|
||||
{
|
||||
num2 = (uint)(value / 100000000000000L);
|
||||
num += 14;
|
||||
}
|
||||
else
|
||||
{
|
||||
num2 = (uint)(value / 10000000);
|
||||
num += 7;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
num2 = (uint)value;
|
||||
}
|
||||
if (num2 >= 10)
|
||||
{
|
||||
num = ((num2 < 100) ? (num + 1) : ((num2 < 1000) ? (num + 2) : ((num2 < 10000) ? (num + 3) : ((num2 < 100000) ? (num + 4) : ((num2 >= 1000000) ? (num + 6) : (num + 5))))));
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int CountDigits(uint value)
|
||||
{
|
||||
int num = 1;
|
||||
if (value >= 100000)
|
||||
{
|
||||
value /= 100000;
|
||||
num += 5;
|
||||
}
|
||||
if (value >= 10)
|
||||
{
|
||||
num = ((value < 100) ? (num + 1) : ((value < 1000) ? (num + 2) : ((value >= 10000) ? (num + 4) : (num + 3))));
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int CountHexDigits(ulong value)
|
||||
{
|
||||
int num = 1;
|
||||
if (value > uint.MaxValue)
|
||||
{
|
||||
num += 8;
|
||||
value >>= 32;
|
||||
}
|
||||
if (value > 65535)
|
||||
{
|
||||
num += 4;
|
||||
value >>= 16;
|
||||
}
|
||||
if (value > 255)
|
||||
{
|
||||
num += 2;
|
||||
value >>= 8;
|
||||
}
|
||||
if (value > 15)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System.Buffers.Text;
|
||||
|
||||
internal static class ParserHelpers
|
||||
{
|
||||
public const int ByteOverflowLength = 3;
|
||||
|
||||
public const int ByteOverflowLengthHex = 2;
|
||||
|
||||
public const int UInt16OverflowLength = 5;
|
||||
|
||||
public const int UInt16OverflowLengthHex = 4;
|
||||
|
||||
public const int UInt32OverflowLength = 10;
|
||||
|
||||
public const int UInt32OverflowLengthHex = 8;
|
||||
|
||||
public const int UInt64OverflowLength = 20;
|
||||
|
||||
public const int UInt64OverflowLengthHex = 16;
|
||||
|
||||
public const int SByteOverflowLength = 3;
|
||||
|
||||
public const int SByteOverflowLengthHex = 2;
|
||||
|
||||
public const int Int16OverflowLength = 5;
|
||||
|
||||
public const int Int16OverflowLengthHex = 4;
|
||||
|
||||
public const int Int32OverflowLength = 10;
|
||||
|
||||
public const int Int32OverflowLengthHex = 8;
|
||||
|
||||
public const int Int64OverflowLength = 19;
|
||||
|
||||
public const int Int64OverflowLengthHex = 16;
|
||||
|
||||
public static readonly byte[] s_hexLookup = new byte[256]
|
||||
{
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 0, 1,
|
||||
2, 3, 4, 5, 6, 7, 8, 9, 255, 255,
|
||||
255, 255, 255, 255, 255, 10, 11, 12, 13, 14,
|
||||
15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 10, 11, 12,
|
||||
13, 14, 15, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255
|
||||
};
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsDigit(int i)
|
||||
{
|
||||
return (uint)(i - 48) <= 9u;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
namespace System.Buffers.Text;
|
||||
|
||||
internal static class Utf8Constants
|
||||
{
|
||||
public const byte Colon = 58;
|
||||
|
||||
public const byte Comma = 44;
|
||||
|
||||
public const byte Minus = 45;
|
||||
|
||||
public const byte Period = 46;
|
||||
|
||||
public const byte Plus = 43;
|
||||
|
||||
public const byte Slash = 47;
|
||||
|
||||
public const byte Space = 32;
|
||||
|
||||
public const byte Hyphen = 45;
|
||||
|
||||
public const byte Separator = 44;
|
||||
|
||||
public const int GroupSize = 3;
|
||||
|
||||
public static readonly TimeSpan s_nullUtcOffset = TimeSpan.MinValue;
|
||||
|
||||
public const int DateTimeMaxUtcOffsetHours = 14;
|
||||
|
||||
public const int DateTimeNumFractionDigits = 7;
|
||||
|
||||
public const int MaxDateTimeFraction = 9999999;
|
||||
|
||||
public const ulong BillionMaxUIntValue = 4294967295000000000uL;
|
||||
|
||||
public const uint Billion = 1000000000u;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,60 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System.Buffers;
|
||||
|
||||
internal sealed class ArrayMemoryPool<T> : MemoryPool<T>
|
||||
{
|
||||
private sealed class ArrayMemoryPoolBuffer : IMemoryOwner<T>, IDisposable
|
||||
{
|
||||
private T[] _array;
|
||||
|
||||
public Memory<T> Memory
|
||||
{
|
||||
get
|
||||
{
|
||||
T[] array = _array;
|
||||
if (array == null)
|
||||
{
|
||||
System.ThrowHelper.ThrowObjectDisposedException_ArrayMemoryPoolBuffer();
|
||||
}
|
||||
return new Memory<T>(array);
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayMemoryPoolBuffer(int size)
|
||||
{
|
||||
_array = ArrayPool<T>.Shared.Rent(size);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
T[] array = _array;
|
||||
if (array != null)
|
||||
{
|
||||
_array = null;
|
||||
ArrayPool<T>.Shared.Return(array);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const int s_maxBufferSize = int.MaxValue;
|
||||
|
||||
public sealed override int MaxBufferSize => int.MaxValue;
|
||||
|
||||
public sealed override IMemoryOwner<T> Rent(int minimumBufferSize = -1)
|
||||
{
|
||||
if (minimumBufferSize == -1)
|
||||
{
|
||||
minimumBufferSize = 1 + 4095 / Unsafe.SizeOf<T>();
|
||||
}
|
||||
else if ((uint)minimumBufferSize > 2147483647u)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.minimumBufferSize);
|
||||
}
|
||||
return new ArrayMemoryPoolBuffer(minimumBufferSize);
|
||||
}
|
||||
|
||||
protected sealed override void Dispose(bool disposing)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System.Buffers;
|
||||
|
||||
public static class BuffersExtensions
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static SequencePosition? PositionOf<T>(this in ReadOnlySequence<T> source, T value) where T : IEquatable<T>
|
||||
{
|
||||
if (source.IsSingleSegment)
|
||||
{
|
||||
int num = source.First.Span.IndexOf(value);
|
||||
if (num != -1)
|
||||
{
|
||||
return source.GetPosition(num);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return PositionOfMultiSegment(in source, value);
|
||||
}
|
||||
|
||||
private static SequencePosition? PositionOfMultiSegment<T>(in ReadOnlySequence<T> source, T value) where T : IEquatable<T>
|
||||
{
|
||||
SequencePosition position = source.Start;
|
||||
SequencePosition origin = position;
|
||||
ReadOnlyMemory<T> memory;
|
||||
while (source.TryGet(ref position, out memory))
|
||||
{
|
||||
int num = memory.Span.IndexOf(value);
|
||||
if (num != -1)
|
||||
{
|
||||
return source.GetPosition(num, origin);
|
||||
}
|
||||
if (position.GetObject() == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
origin = position;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void CopyTo<T>(this in ReadOnlySequence<T> source, Span<T> destination)
|
||||
{
|
||||
if (source.Length > destination.Length)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.destination);
|
||||
}
|
||||
if (source.IsSingleSegment)
|
||||
{
|
||||
source.First.Span.CopyTo(destination);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyToMultiSegment(in source, destination);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CopyToMultiSegment<T>(in ReadOnlySequence<T> sequence, Span<T> destination)
|
||||
{
|
||||
SequencePosition position = sequence.Start;
|
||||
ReadOnlyMemory<T> memory;
|
||||
while (sequence.TryGet(ref position, out memory))
|
||||
{
|
||||
ReadOnlySpan<T> span = memory.Span;
|
||||
span.CopyTo(destination);
|
||||
if (position.GetObject() != null)
|
||||
{
|
||||
destination = destination.Slice(span.Length);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static T[] ToArray<T>(this in ReadOnlySequence<T> sequence)
|
||||
{
|
||||
T[] array = new T[sequence.Length];
|
||||
sequence.CopyTo(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Write<T>(this IBufferWriter<T> writer, ReadOnlySpan<T> value)
|
||||
{
|
||||
Span<T> span = writer.GetSpan();
|
||||
if (value.Length <= span.Length)
|
||||
{
|
||||
value.CopyTo(span);
|
||||
writer.Advance(value.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteMultiSegment(writer, in value, span);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteMultiSegment<T>(IBufferWriter<T> writer, in ReadOnlySpan<T> source, Span<T> destination)
|
||||
{
|
||||
ReadOnlySpan<T> readOnlySpan = source;
|
||||
while (true)
|
||||
{
|
||||
int num = Math.Min(destination.Length, readOnlySpan.Length);
|
||||
readOnlySpan.Slice(0, num).CopyTo(destination);
|
||||
writer.Advance(num);
|
||||
readOnlySpan = readOnlySpan.Slice(num);
|
||||
if (readOnlySpan.Length > 0)
|
||||
{
|
||||
destination = writer.GetSpan(readOnlySpan.Length);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace System.Buffers;
|
||||
|
||||
public interface IBufferWriter<T>
|
||||
{
|
||||
void Advance(int count);
|
||||
|
||||
Memory<T> GetMemory(int sizeHint = 0);
|
||||
|
||||
Span<T> GetSpan(int sizeHint = 0);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace System.Buffers;
|
||||
|
||||
public interface IMemoryOwner<T> : IDisposable
|
||||
{
|
||||
Memory<T> Memory { get; }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace System.Buffers;
|
||||
|
||||
public interface IPinnable
|
||||
{
|
||||
MemoryHandle Pin(int elementIndex);
|
||||
|
||||
void Unpin();
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System.Buffers;
|
||||
|
||||
public unsafe struct MemoryHandle(void* pointer, GCHandle handle = default(GCHandle), IPinnable pinnable = null) : IDisposable
|
||||
{
|
||||
private unsafe void* _pointer = pointer;
|
||||
|
||||
private GCHandle _handle = handle;
|
||||
|
||||
private IPinnable _pinnable = pinnable;
|
||||
|
||||
[CLSCompliant(false)]
|
||||
public unsafe void* Pointer => _pointer;
|
||||
|
||||
public unsafe void Dispose()
|
||||
{
|
||||
if (_handle.IsAllocated)
|
||||
{
|
||||
_handle.Free();
|
||||
}
|
||||
if (_pinnable != null)
|
||||
{
|
||||
_pinnable.Unpin();
|
||||
_pinnable = null;
|
||||
}
|
||||
_pointer = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System.Buffers;
|
||||
|
||||
public abstract class MemoryManager<T> : IMemoryOwner<T>, IDisposable, IPinnable
|
||||
{
|
||||
public virtual Memory<T> Memory => new Memory<T>(this, GetSpan().Length);
|
||||
|
||||
public abstract Span<T> GetSpan();
|
||||
|
||||
public abstract MemoryHandle Pin(int elementIndex = 0);
|
||||
|
||||
public abstract void Unpin();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
protected Memory<T> CreateMemory(int length)
|
||||
{
|
||||
return new Memory<T>(this, length);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
protected Memory<T> CreateMemory(int start, int length)
|
||||
{
|
||||
return new Memory<T>(this, start, length);
|
||||
}
|
||||
|
||||
protected internal virtual bool TryGetArray(out ArraySegment<T> segment)
|
||||
{
|
||||
segment = default(ArraySegment<T>);
|
||||
return false;
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected abstract void Dispose(bool disposing);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace System.Buffers;
|
||||
|
||||
public abstract class MemoryPool<T> : IDisposable
|
||||
{
|
||||
private static readonly MemoryPool<T> s_shared = new System.Buffers.ArrayMemoryPool<T>();
|
||||
|
||||
public static MemoryPool<T> Shared => s_shared;
|
||||
|
||||
public abstract int MaxBufferSize { get; }
|
||||
|
||||
public abstract IMemoryOwner<T> Rent(int minBufferSize = -1);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected abstract void Dispose(bool disposing);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace System.Buffers;
|
||||
|
||||
public enum OperationStatus
|
||||
{
|
||||
Done,
|
||||
DestinationTooSmall,
|
||||
NeedMoreData,
|
||||
InvalidData
|
||||
}
|
||||
@@ -0,0 +1,760 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System.Buffers;
|
||||
|
||||
[DebuggerTypeProxy(typeof(System.Buffers.ReadOnlySequenceDebugView<>))]
|
||||
[DebuggerDisplay("{ToString(),raw}")]
|
||||
public readonly struct ReadOnlySequence<T>
|
||||
{
|
||||
public struct Enumerator(in ReadOnlySequence<T> sequence)
|
||||
{
|
||||
private readonly ReadOnlySequence<T> _sequence = sequence;
|
||||
|
||||
private SequencePosition _next = sequence.Start;
|
||||
|
||||
private ReadOnlyMemory<T> _currentMemory = default(ReadOnlyMemory<T>);
|
||||
|
||||
public ReadOnlyMemory<T> Current => _currentMemory;
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (_next.GetObject() == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return _sequence.TryGet(ref _next, out _currentMemory);
|
||||
}
|
||||
}
|
||||
|
||||
private enum SequenceType
|
||||
{
|
||||
MultiSegment,
|
||||
Array,
|
||||
MemoryManager,
|
||||
String,
|
||||
Empty
|
||||
}
|
||||
|
||||
private readonly SequencePosition _sequenceStart;
|
||||
|
||||
private readonly SequencePosition _sequenceEnd;
|
||||
|
||||
public static readonly ReadOnlySequence<T> Empty;
|
||||
|
||||
public long Length => GetLength();
|
||||
|
||||
public bool IsEmpty => Length == 0;
|
||||
|
||||
public bool IsSingleSegment
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return _sequenceStart.GetObject() == _sequenceEnd.GetObject();
|
||||
}
|
||||
}
|
||||
|
||||
public ReadOnlyMemory<T> First => GetFirstBuffer();
|
||||
|
||||
public SequencePosition Start => _sequenceStart;
|
||||
|
||||
public SequencePosition End => _sequenceEnd;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private ReadOnlySequence(object startSegment, int startIndexAndFlags, object endSegment, int endIndexAndFlags)
|
||||
{
|
||||
_sequenceStart = new SequencePosition(startSegment, startIndexAndFlags);
|
||||
_sequenceEnd = new SequencePosition(endSegment, endIndexAndFlags);
|
||||
}
|
||||
|
||||
public ReadOnlySequence(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment, int endIndex)
|
||||
{
|
||||
if (startSegment == null || endSegment == null || (startSegment != endSegment && startSegment.RunningIndex > endSegment.RunningIndex) || (uint)startSegment.Memory.Length < (uint)startIndex || (uint)endSegment.Memory.Length < (uint)endIndex || (startSegment == endSegment && endIndex < startIndex))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentValidationException(startSegment, startIndex, endSegment);
|
||||
}
|
||||
_sequenceStart = new SequencePosition(startSegment, System.Buffers.ReadOnlySequence.SegmentToSequenceStart(startIndex));
|
||||
_sequenceEnd = new SequencePosition(endSegment, System.Buffers.ReadOnlySequence.SegmentToSequenceEnd(endIndex));
|
||||
}
|
||||
|
||||
public ReadOnlySequence(T[] array)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.array);
|
||||
}
|
||||
_sequenceStart = new SequencePosition(array, System.Buffers.ReadOnlySequence.ArrayToSequenceStart(0));
|
||||
_sequenceEnd = new SequencePosition(array, System.Buffers.ReadOnlySequence.ArrayToSequenceEnd(array.Length));
|
||||
}
|
||||
|
||||
public ReadOnlySequence(T[] array, int start, int length)
|
||||
{
|
||||
if (array == null || (uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentValidationException(array, start);
|
||||
}
|
||||
_sequenceStart = new SequencePosition(array, System.Buffers.ReadOnlySequence.ArrayToSequenceStart(start));
|
||||
_sequenceEnd = new SequencePosition(array, System.Buffers.ReadOnlySequence.ArrayToSequenceEnd(start + length));
|
||||
}
|
||||
|
||||
public ReadOnlySequence(ReadOnlyMemory<T> memory)
|
||||
{
|
||||
ArraySegment<T> segment;
|
||||
if (MemoryMarshal.TryGetMemoryManager<T, MemoryManager<T>>(memory, out var manager, out var start, out var length))
|
||||
{
|
||||
_sequenceStart = new SequencePosition(manager, System.Buffers.ReadOnlySequence.MemoryManagerToSequenceStart(start));
|
||||
_sequenceEnd = new SequencePosition(manager, System.Buffers.ReadOnlySequence.MemoryManagerToSequenceEnd(start + length));
|
||||
}
|
||||
else if (MemoryMarshal.TryGetArray(memory, out segment))
|
||||
{
|
||||
T[] array = segment.Array;
|
||||
int offset = segment.Offset;
|
||||
_sequenceStart = new SequencePosition(array, System.Buffers.ReadOnlySequence.ArrayToSequenceStart(offset));
|
||||
_sequenceEnd = new SequencePosition(array, System.Buffers.ReadOnlySequence.ArrayToSequenceEnd(offset + segment.Count));
|
||||
}
|
||||
else if (typeof(T) == typeof(char))
|
||||
{
|
||||
if (!MemoryMarshal.TryGetString((ReadOnlyMemory<char>)(object)memory, out var text, out var start2, out length))
|
||||
{
|
||||
System.ThrowHelper.ThrowInvalidOperationException();
|
||||
}
|
||||
_sequenceStart = new SequencePosition(text, System.Buffers.ReadOnlySequence.StringToSequenceStart(start2));
|
||||
_sequenceEnd = new SequencePosition(text, System.Buffers.ReadOnlySequence.StringToSequenceEnd(start2 + length));
|
||||
}
|
||||
else
|
||||
{
|
||||
System.ThrowHelper.ThrowInvalidOperationException();
|
||||
_sequenceStart = default(SequencePosition);
|
||||
_sequenceEnd = default(SequencePosition);
|
||||
}
|
||||
}
|
||||
|
||||
public ReadOnlySequence<T> Slice(long start, long length)
|
||||
{
|
||||
if (start < 0 || length < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowStartOrEndArgumentValidationException(start);
|
||||
}
|
||||
int index = GetIndex(in _sequenceStart);
|
||||
int index2 = GetIndex(in _sequenceEnd);
|
||||
object obj = _sequenceStart.GetObject();
|
||||
object obj2 = _sequenceEnd.GetObject();
|
||||
SequencePosition position;
|
||||
SequencePosition end;
|
||||
if (obj != obj2)
|
||||
{
|
||||
ReadOnlySequenceSegment<T> readOnlySequenceSegment = (ReadOnlySequenceSegment<T>)obj;
|
||||
int num = readOnlySequenceSegment.Memory.Length - index;
|
||||
if (num > start)
|
||||
{
|
||||
index += (int)start;
|
||||
position = new SequencePosition(obj, index);
|
||||
end = GetEndPosition(readOnlySequenceSegment, obj, index, obj2, index2, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (num < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
position = SeekMultiSegment(readOnlySequenceSegment.Next, obj2, index2, start - num, System.ExceptionArgument.start);
|
||||
int index3 = GetIndex(in position);
|
||||
object obj3 = position.GetObject();
|
||||
if (obj3 != obj2)
|
||||
{
|
||||
end = GetEndPosition((ReadOnlySequenceSegment<T>)obj3, obj3, index3, obj2, index2, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index2 - index3 < length)
|
||||
{
|
||||
System.ThrowHelper.ThrowStartOrEndArgumentValidationException(0L);
|
||||
}
|
||||
end = new SequencePosition(obj3, index3 + (int)length);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index2 - index < start)
|
||||
{
|
||||
System.ThrowHelper.ThrowStartOrEndArgumentValidationException(-1L);
|
||||
}
|
||||
index += (int)start;
|
||||
position = new SequencePosition(obj, index);
|
||||
if (index2 - index < length)
|
||||
{
|
||||
System.ThrowHelper.ThrowStartOrEndArgumentValidationException(0L);
|
||||
}
|
||||
end = new SequencePosition(obj, index + (int)length);
|
||||
}
|
||||
return SliceImpl(in position, in end);
|
||||
}
|
||||
|
||||
public ReadOnlySequence<T> Slice(long start, SequencePosition end)
|
||||
{
|
||||
if (start < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowStartOrEndArgumentValidationException(start);
|
||||
}
|
||||
uint index = (uint)GetIndex(in end);
|
||||
object obj = end.GetObject();
|
||||
uint index2 = (uint)GetIndex(in _sequenceStart);
|
||||
object obj2 = _sequenceStart.GetObject();
|
||||
uint index3 = (uint)GetIndex(in _sequenceEnd);
|
||||
object obj3 = _sequenceEnd.GetObject();
|
||||
if (obj2 == obj3)
|
||||
{
|
||||
if (!InRange(index, index2, index3))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
if (index - index2 < start)
|
||||
{
|
||||
System.ThrowHelper.ThrowStartOrEndArgumentValidationException(-1L);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadOnlySequenceSegment<T> readOnlySequenceSegment = (ReadOnlySequenceSegment<T>)obj2;
|
||||
ulong num = (ulong)(readOnlySequenceSegment.RunningIndex + index2);
|
||||
ulong num2 = (ulong)(((ReadOnlySequenceSegment<T>)obj).RunningIndex + index);
|
||||
if (!InRange(num2, num, (ulong)(((ReadOnlySequenceSegment<T>)obj3).RunningIndex + index3)))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
if ((ulong)((long)num + start) > num2)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
int num3 = readOnlySequenceSegment.Memory.Length - (int)index2;
|
||||
if (num3 <= start)
|
||||
{
|
||||
if (num3 < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
return SliceImpl(SeekMultiSegment(readOnlySequenceSegment.Next, obj, (int)index, start - num3, System.ExceptionArgument.start), in end);
|
||||
}
|
||||
}
|
||||
return SliceImpl(new SequencePosition(obj2, (int)index2 + (int)start), in end);
|
||||
}
|
||||
|
||||
public ReadOnlySequence<T> Slice(SequencePosition start, long length)
|
||||
{
|
||||
uint index = (uint)GetIndex(in start);
|
||||
object obj = start.GetObject();
|
||||
uint index2 = (uint)GetIndex(in _sequenceStart);
|
||||
object obj2 = _sequenceStart.GetObject();
|
||||
uint index3 = (uint)GetIndex(in _sequenceEnd);
|
||||
object obj3 = _sequenceEnd.GetObject();
|
||||
if (obj2 == obj3)
|
||||
{
|
||||
if (!InRange(index, index2, index3))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
if (length < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowStartOrEndArgumentValidationException(0L);
|
||||
}
|
||||
if (index3 - index < length)
|
||||
{
|
||||
System.ThrowHelper.ThrowStartOrEndArgumentValidationException(0L);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadOnlySequenceSegment<T> readOnlySequenceSegment = (ReadOnlySequenceSegment<T>)obj;
|
||||
ulong num = (ulong)(readOnlySequenceSegment.RunningIndex + index);
|
||||
ulong start2 = (ulong)(((ReadOnlySequenceSegment<T>)obj2).RunningIndex + index2);
|
||||
ulong num2 = (ulong)(((ReadOnlySequenceSegment<T>)obj3).RunningIndex + index3);
|
||||
if (!InRange(num, start2, num2))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
if (length < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowStartOrEndArgumentValidationException(0L);
|
||||
}
|
||||
if ((ulong)((long)num + length) > num2)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
|
||||
}
|
||||
int num3 = readOnlySequenceSegment.Memory.Length - (int)index;
|
||||
if (num3 < length)
|
||||
{
|
||||
if (num3 < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
return SliceImpl(in start, SeekMultiSegment(readOnlySequenceSegment.Next, obj3, (int)index3, length - num3, System.ExceptionArgument.length));
|
||||
}
|
||||
}
|
||||
return SliceImpl(in start, new SequencePosition(obj, (int)index + (int)length));
|
||||
}
|
||||
|
||||
public ReadOnlySequence<T> Slice(int start, int length)
|
||||
{
|
||||
return Slice((long)start, (long)length);
|
||||
}
|
||||
|
||||
public ReadOnlySequence<T> Slice(int start, SequencePosition end)
|
||||
{
|
||||
return Slice((long)start, end);
|
||||
}
|
||||
|
||||
public ReadOnlySequence<T> Slice(SequencePosition start, int length)
|
||||
{
|
||||
return Slice(start, (long)length);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ReadOnlySequence<T> Slice(SequencePosition start, SequencePosition end)
|
||||
{
|
||||
BoundsCheck((uint)GetIndex(in start), start.GetObject(), (uint)GetIndex(in end), end.GetObject());
|
||||
return SliceImpl(in start, in end);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ReadOnlySequence<T> Slice(SequencePosition start)
|
||||
{
|
||||
BoundsCheck(in start);
|
||||
return SliceImpl(in start, in _sequenceEnd);
|
||||
}
|
||||
|
||||
public ReadOnlySequence<T> Slice(long start)
|
||||
{
|
||||
if (start < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowStartOrEndArgumentValidationException(start);
|
||||
}
|
||||
if (start == 0L)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
return SliceImpl(Seek(in _sequenceStart, in _sequenceEnd, start, System.ExceptionArgument.start), in _sequenceEnd);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (typeof(T) == typeof(char))
|
||||
{
|
||||
ReadOnlySequence<T> source = this;
|
||||
ReadOnlySequence<char> sequence = Unsafe.As<ReadOnlySequence<T>, ReadOnlySequence<char>>(ref source);
|
||||
if (SequenceMarshal.TryGetString(sequence, out var text, out var start, out var length))
|
||||
{
|
||||
return text.Substring(start, length);
|
||||
}
|
||||
if (Length < int.MaxValue)
|
||||
{
|
||||
return new string(BuffersExtensions.ToArray(in sequence));
|
||||
}
|
||||
}
|
||||
return $"System.Buffers.ReadOnlySequence<{typeof(T).Name}>[{Length}]";
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
public SequencePosition GetPosition(long offset)
|
||||
{
|
||||
return GetPosition(offset, _sequenceStart);
|
||||
}
|
||||
|
||||
public SequencePosition GetPosition(long offset, SequencePosition origin)
|
||||
{
|
||||
if (offset < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_OffsetOutOfRange();
|
||||
}
|
||||
return Seek(in origin, in _sequenceEnd, offset, System.ExceptionArgument.offset);
|
||||
}
|
||||
|
||||
public bool TryGet(ref SequencePosition position, out ReadOnlyMemory<T> memory, bool advance = true)
|
||||
{
|
||||
SequencePosition next;
|
||||
bool result = TryGetBuffer(in position, out memory, out next);
|
||||
if (advance)
|
||||
{
|
||||
position = next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal bool TryGetBuffer(in SequencePosition position, out ReadOnlyMemory<T> memory, out SequencePosition next)
|
||||
{
|
||||
object obj = position.GetObject();
|
||||
next = default(SequencePosition);
|
||||
if (obj == null)
|
||||
{
|
||||
memory = default(ReadOnlyMemory<T>);
|
||||
return false;
|
||||
}
|
||||
SequenceType sequenceType = GetSequenceType();
|
||||
object obj2 = _sequenceEnd.GetObject();
|
||||
int index = GetIndex(in position);
|
||||
int index2 = GetIndex(in _sequenceEnd);
|
||||
if (sequenceType == SequenceType.MultiSegment)
|
||||
{
|
||||
ReadOnlySequenceSegment<T> readOnlySequenceSegment = (ReadOnlySequenceSegment<T>)obj;
|
||||
if (readOnlySequenceSegment != obj2)
|
||||
{
|
||||
ReadOnlySequenceSegment<T> next2 = readOnlySequenceSegment.Next;
|
||||
if (next2 == null)
|
||||
{
|
||||
System.ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached();
|
||||
}
|
||||
next = new SequencePosition(next2, 0);
|
||||
memory = readOnlySequenceSegment.Memory.Slice(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
memory = readOnlySequenceSegment.Memory.Slice(index, index2 - index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (obj != obj2)
|
||||
{
|
||||
System.ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached();
|
||||
}
|
||||
if (sequenceType == SequenceType.Array)
|
||||
{
|
||||
memory = new ReadOnlyMemory<T>((T[])obj, index, index2 - index);
|
||||
}
|
||||
else if (typeof(T) == typeof(char) && sequenceType == SequenceType.String)
|
||||
{
|
||||
memory = (ReadOnlyMemory<T>)(object)MemoryExtensions.AsMemory((string)obj, index, index2 - index);
|
||||
}
|
||||
else
|
||||
{
|
||||
memory = ((MemoryManager<T>)obj).Memory.Slice(index, index2 - index);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private ReadOnlyMemory<T> GetFirstBuffer()
|
||||
{
|
||||
object obj = _sequenceStart.GetObject();
|
||||
if (obj == null)
|
||||
{
|
||||
return default(ReadOnlyMemory<T>);
|
||||
}
|
||||
int integer = _sequenceStart.GetInteger();
|
||||
int integer2 = _sequenceEnd.GetInteger();
|
||||
bool flag = obj != _sequenceEnd.GetObject();
|
||||
if (integer >= 0)
|
||||
{
|
||||
if (integer2 >= 0)
|
||||
{
|
||||
ReadOnlyMemory<T> memory = ((ReadOnlySequenceSegment<T>)obj).Memory;
|
||||
if (flag)
|
||||
{
|
||||
return memory.Slice(integer);
|
||||
}
|
||||
return memory.Slice(integer, integer2 - integer);
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
System.ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached();
|
||||
}
|
||||
return new ReadOnlyMemory<T>((T[])obj, integer, (integer2 & 0x7FFFFFFF) - integer);
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
System.ThrowHelper.ThrowInvalidOperationException_EndPositionNotReached();
|
||||
}
|
||||
if (typeof(T) == typeof(char) && integer2 < 0)
|
||||
{
|
||||
return (ReadOnlyMemory<T>)(object)MemoryExtensions.AsMemory((string)obj, integer & 0x7FFFFFFF, integer2 - integer);
|
||||
}
|
||||
integer &= 0x7FFFFFFF;
|
||||
return ((MemoryManager<T>)obj).Memory.Slice(integer, integer2 - integer);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private SequencePosition Seek(in SequencePosition start, in SequencePosition end, long offset, System.ExceptionArgument argument)
|
||||
{
|
||||
int index = GetIndex(in start);
|
||||
int index2 = GetIndex(in end);
|
||||
object obj = start.GetObject();
|
||||
object obj2 = end.GetObject();
|
||||
if (obj != obj2)
|
||||
{
|
||||
ReadOnlySequenceSegment<T> readOnlySequenceSegment = (ReadOnlySequenceSegment<T>)obj;
|
||||
int num = readOnlySequenceSegment.Memory.Length - index;
|
||||
if (num <= offset)
|
||||
{
|
||||
if (num < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
return SeekMultiSegment(readOnlySequenceSegment.Next, obj2, index2, offset - num, argument);
|
||||
}
|
||||
}
|
||||
else if (index2 - index < offset)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(argument);
|
||||
}
|
||||
return new SequencePosition(obj, index + (int)offset);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static SequencePosition SeekMultiSegment(ReadOnlySequenceSegment<T> currentSegment, object endObject, int endIndex, long offset, System.ExceptionArgument argument)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (currentSegment != null && currentSegment != endObject)
|
||||
{
|
||||
int length = currentSegment.Memory.Length;
|
||||
if (length > offset)
|
||||
{
|
||||
break;
|
||||
}
|
||||
offset -= length;
|
||||
currentSegment = currentSegment.Next;
|
||||
continue;
|
||||
}
|
||||
if (currentSegment == null || endIndex < offset)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(argument);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return new SequencePosition(currentSegment, (int)offset);
|
||||
}
|
||||
|
||||
private void BoundsCheck(in SequencePosition position)
|
||||
{
|
||||
uint index = (uint)GetIndex(in position);
|
||||
uint index2 = (uint)GetIndex(in _sequenceStart);
|
||||
uint index3 = (uint)GetIndex(in _sequenceEnd);
|
||||
object obj = _sequenceStart.GetObject();
|
||||
object obj2 = _sequenceEnd.GetObject();
|
||||
if (obj == obj2)
|
||||
{
|
||||
if (!InRange(index, index2, index3))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
return;
|
||||
}
|
||||
ulong start = (ulong)(((ReadOnlySequenceSegment<T>)obj).RunningIndex + index2);
|
||||
if (!InRange((ulong)(((ReadOnlySequenceSegment<T>)position.GetObject()).RunningIndex + index), start, (ulong)(((ReadOnlySequenceSegment<T>)obj2).RunningIndex + index3)))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
}
|
||||
|
||||
private void BoundsCheck(uint sliceStartIndex, object sliceStartObject, uint sliceEndIndex, object sliceEndObject)
|
||||
{
|
||||
uint index = (uint)GetIndex(in _sequenceStart);
|
||||
uint index2 = (uint)GetIndex(in _sequenceEnd);
|
||||
object obj = _sequenceStart.GetObject();
|
||||
object obj2 = _sequenceEnd.GetObject();
|
||||
if (obj == obj2)
|
||||
{
|
||||
if (sliceStartObject != sliceEndObject || sliceStartObject != obj || sliceStartIndex > sliceEndIndex || sliceStartIndex < index || sliceEndIndex > index2)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
return;
|
||||
}
|
||||
ulong num = (ulong)(((ReadOnlySequenceSegment<T>)sliceStartObject).RunningIndex + sliceStartIndex);
|
||||
ulong num2 = (ulong)(((ReadOnlySequenceSegment<T>)sliceEndObject).RunningIndex + sliceEndIndex);
|
||||
if (num > num2)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
if (num < (ulong)(((ReadOnlySequenceSegment<T>)obj).RunningIndex + index) || num2 > (ulong)(((ReadOnlySequenceSegment<T>)obj2).RunningIndex + index2))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
}
|
||||
|
||||
private static SequencePosition GetEndPosition(ReadOnlySequenceSegment<T> startSegment, object startObject, int startIndex, object endObject, int endIndex, long length)
|
||||
{
|
||||
int num = startSegment.Memory.Length - startIndex;
|
||||
if (num > length)
|
||||
{
|
||||
return new SequencePosition(startObject, startIndex + (int)length);
|
||||
}
|
||||
if (num < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
return SeekMultiSegment(startSegment.Next, endObject, endIndex, length - num, System.ExceptionArgument.length);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private SequenceType GetSequenceType()
|
||||
{
|
||||
return (SequenceType)(-(2 * (_sequenceStart.GetInteger() >> 31) + (_sequenceEnd.GetInteger() >> 31)));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static int GetIndex(in SequencePosition position)
|
||||
{
|
||||
return position.GetInteger() & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private ReadOnlySequence<T> SliceImpl(in SequencePosition start, in SequencePosition end)
|
||||
{
|
||||
return new ReadOnlySequence<T>(start.GetObject(), GetIndex(in start) | (_sequenceStart.GetInteger() & int.MinValue), end.GetObject(), GetIndex(in end) | (_sequenceEnd.GetInteger() & int.MinValue));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private long GetLength()
|
||||
{
|
||||
int index = GetIndex(in _sequenceStart);
|
||||
int index2 = GetIndex(in _sequenceEnd);
|
||||
object obj = _sequenceStart.GetObject();
|
||||
object obj2 = _sequenceEnd.GetObject();
|
||||
if (obj != obj2)
|
||||
{
|
||||
ReadOnlySequenceSegment<T> readOnlySequenceSegment = (ReadOnlySequenceSegment<T>)obj;
|
||||
ReadOnlySequenceSegment<T> readOnlySequenceSegment2 = (ReadOnlySequenceSegment<T>)obj2;
|
||||
return readOnlySequenceSegment2.RunningIndex + index2 - (readOnlySequenceSegment.RunningIndex + index);
|
||||
}
|
||||
return index2 - index;
|
||||
}
|
||||
|
||||
internal bool TryGetReadOnlySequenceSegment(out ReadOnlySequenceSegment<T> startSegment, out int startIndex, out ReadOnlySequenceSegment<T> endSegment, out int endIndex)
|
||||
{
|
||||
object obj = _sequenceStart.GetObject();
|
||||
if (obj == null || GetSequenceType() != SequenceType.MultiSegment)
|
||||
{
|
||||
startSegment = null;
|
||||
startIndex = 0;
|
||||
endSegment = null;
|
||||
endIndex = 0;
|
||||
return false;
|
||||
}
|
||||
startSegment = (ReadOnlySequenceSegment<T>)obj;
|
||||
startIndex = GetIndex(in _sequenceStart);
|
||||
endSegment = (ReadOnlySequenceSegment<T>)_sequenceEnd.GetObject();
|
||||
endIndex = GetIndex(in _sequenceEnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
internal bool TryGetArray(out ArraySegment<T> segment)
|
||||
{
|
||||
if (GetSequenceType() != SequenceType.Array)
|
||||
{
|
||||
segment = default(ArraySegment<T>);
|
||||
return false;
|
||||
}
|
||||
int index = GetIndex(in _sequenceStart);
|
||||
segment = new ArraySegment<T>((T[])_sequenceStart.GetObject(), index, GetIndex(in _sequenceEnd) - index);
|
||||
return true;
|
||||
}
|
||||
|
||||
internal bool TryGetString(out string text, out int start, out int length)
|
||||
{
|
||||
if (typeof(T) != typeof(char) || GetSequenceType() != SequenceType.String)
|
||||
{
|
||||
start = 0;
|
||||
length = 0;
|
||||
text = null;
|
||||
return false;
|
||||
}
|
||||
start = GetIndex(in _sequenceStart);
|
||||
length = GetIndex(in _sequenceEnd) - start;
|
||||
text = (string)_sequenceStart.GetObject();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool InRange(uint value, uint start, uint end)
|
||||
{
|
||||
return value - start <= end - start;
|
||||
}
|
||||
|
||||
private static bool InRange(ulong value, ulong start, ulong end)
|
||||
{
|
||||
return value - start <= end - start;
|
||||
}
|
||||
|
||||
static ReadOnlySequence()
|
||||
{
|
||||
Empty = new ReadOnlySequence<T>(System.SpanHelpers.PerTypeValues<T>.EmptyArray);
|
||||
}
|
||||
}
|
||||
internal static class ReadOnlySequence
|
||||
{
|
||||
public const int FlagBitMask = int.MinValue;
|
||||
|
||||
public const int IndexBitMask = int.MaxValue;
|
||||
|
||||
public const int SegmentStartMask = 0;
|
||||
|
||||
public const int SegmentEndMask = 0;
|
||||
|
||||
public const int ArrayStartMask = 0;
|
||||
|
||||
public const int ArrayEndMask = int.MinValue;
|
||||
|
||||
public const int MemoryManagerStartMask = int.MinValue;
|
||||
|
||||
public const int MemoryManagerEndMask = 0;
|
||||
|
||||
public const int StringStartMask = int.MinValue;
|
||||
|
||||
public const int StringEndMask = int.MinValue;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int SegmentToSequenceStart(int startIndex)
|
||||
{
|
||||
return startIndex | 0;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int SegmentToSequenceEnd(int endIndex)
|
||||
{
|
||||
return endIndex | 0;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int ArrayToSequenceStart(int startIndex)
|
||||
{
|
||||
return startIndex | 0;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int ArrayToSequenceEnd(int endIndex)
|
||||
{
|
||||
return endIndex | int.MinValue;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int MemoryManagerToSequenceStart(int startIndex)
|
||||
{
|
||||
return startIndex | int.MinValue;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int MemoryManagerToSequenceEnd(int endIndex)
|
||||
{
|
||||
return endIndex | 0;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int StringToSequenceStart(int startIndex)
|
||||
{
|
||||
return startIndex | int.MinValue;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int StringToSequenceEnd(int endIndex)
|
||||
{
|
||||
return endIndex | int.MinValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System.Buffers;
|
||||
|
||||
internal sealed class ReadOnlySequenceDebugView<T>
|
||||
{
|
||||
[DebuggerDisplay("Count: {Segments.Length}", Name = "Segments")]
|
||||
public struct ReadOnlySequenceDebugViewSegments
|
||||
{
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public ReadOnlyMemory<T>[] Segments { get; set; }
|
||||
}
|
||||
|
||||
private readonly T[] _array;
|
||||
|
||||
private readonly ReadOnlySequenceDebugViewSegments _segments;
|
||||
|
||||
public ReadOnlySequenceDebugViewSegments BufferSegments => _segments;
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public T[] Items => _array;
|
||||
|
||||
public ReadOnlySequenceDebugView(ReadOnlySequence<T> sequence)
|
||||
{
|
||||
_array = BuffersExtensions.ToArray(in sequence);
|
||||
int num = 0;
|
||||
ReadOnlySequence<T>.Enumerator enumerator = sequence.GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
ReadOnlyMemory<T> current = enumerator.Current;
|
||||
num++;
|
||||
}
|
||||
ReadOnlyMemory<T>[] array = new ReadOnlyMemory<T>[num];
|
||||
int num2 = 0;
|
||||
ReadOnlySequence<T>.Enumerator enumerator2 = sequence.GetEnumerator();
|
||||
while (enumerator2.MoveNext())
|
||||
{
|
||||
ReadOnlyMemory<T> current2 = enumerator2.Current;
|
||||
array[num2] = current2;
|
||||
num2++;
|
||||
}
|
||||
_segments = new ReadOnlySequenceDebugViewSegments
|
||||
{
|
||||
Segments = array
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace System.Buffers;
|
||||
|
||||
public abstract class ReadOnlySequenceSegment<T>
|
||||
{
|
||||
public ReadOnlyMemory<T> Memory { get; protected set; }
|
||||
|
||||
public ReadOnlySequenceSegment<T> Next { get; protected set; }
|
||||
|
||||
public long RunningIndex { get; protected set; }
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
namespace System.Buffers;
|
||||
|
||||
public readonly struct StandardFormat : IEquatable<StandardFormat>
|
||||
{
|
||||
public const byte NoPrecision = byte.MaxValue;
|
||||
|
||||
public const byte MaxPrecision = 99;
|
||||
|
||||
private readonly byte _format;
|
||||
|
||||
private readonly byte _precision;
|
||||
|
||||
public char Symbol => (char)_format;
|
||||
|
||||
public byte Precision => _precision;
|
||||
|
||||
public bool HasPrecision => _precision != byte.MaxValue;
|
||||
|
||||
public bool IsDefault
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_format == 0)
|
||||
{
|
||||
return _precision == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public StandardFormat(char symbol, byte precision = byte.MaxValue)
|
||||
{
|
||||
if (precision != byte.MaxValue && precision > 99)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_PrecisionTooLarge();
|
||||
}
|
||||
if (symbol != (byte)symbol)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException_SymbolDoesNotFit();
|
||||
}
|
||||
_format = (byte)symbol;
|
||||
_precision = precision;
|
||||
}
|
||||
|
||||
public static implicit operator StandardFormat(char symbol)
|
||||
{
|
||||
return new StandardFormat(symbol);
|
||||
}
|
||||
|
||||
public static StandardFormat Parse(ReadOnlySpan<char> format)
|
||||
{
|
||||
if (format.Length == 0)
|
||||
{
|
||||
return default(StandardFormat);
|
||||
}
|
||||
char symbol = format[0];
|
||||
byte precision;
|
||||
if (format.Length == 1)
|
||||
{
|
||||
precision = byte.MaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint num = 0u;
|
||||
for (int i = 1; i < format.Length; i++)
|
||||
{
|
||||
uint num2 = (uint)(format[i] - 48);
|
||||
if (num2 > 9)
|
||||
{
|
||||
throw new FormatException(System.SR.Format(System.SR.Argument_CannotParsePrecision, (byte)99));
|
||||
}
|
||||
num = num * 10 + num2;
|
||||
if (num > 99)
|
||||
{
|
||||
throw new FormatException(System.SR.Format(System.SR.Argument_PrecisionTooLarge, (byte)99));
|
||||
}
|
||||
}
|
||||
precision = (byte)num;
|
||||
}
|
||||
return new StandardFormat(symbol, precision);
|
||||
}
|
||||
|
||||
public static StandardFormat Parse(string format)
|
||||
{
|
||||
if (format != null)
|
||||
{
|
||||
return Parse(MemoryExtensions.AsSpan(format));
|
||||
}
|
||||
return default(StandardFormat);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is StandardFormat other)
|
||||
{
|
||||
return Equals(other);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
byte format = _format;
|
||||
int hashCode = format.GetHashCode();
|
||||
format = _precision;
|
||||
return hashCode ^ format.GetHashCode();
|
||||
}
|
||||
|
||||
public bool Equals(StandardFormat other)
|
||||
{
|
||||
if (_format == other._format)
|
||||
{
|
||||
return _precision == other._precision;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public unsafe override string ToString()
|
||||
{
|
||||
char* ptr = stackalloc char[4];
|
||||
int length = 0;
|
||||
char symbol = Symbol;
|
||||
if (symbol != 0)
|
||||
{
|
||||
ptr[length++] = symbol;
|
||||
byte b = Precision;
|
||||
if (b != byte.MaxValue)
|
||||
{
|
||||
if (b >= 100)
|
||||
{
|
||||
ptr[length++] = (char)(48 + b / 100 % 10);
|
||||
b %= 100;
|
||||
}
|
||||
if (b >= 10)
|
||||
{
|
||||
ptr[length++] = (char)(48 + b / 10 % 10);
|
||||
b %= 10;
|
||||
}
|
||||
ptr[length++] = (char)(48 + b);
|
||||
}
|
||||
}
|
||||
return new string(ptr, 0, length);
|
||||
}
|
||||
|
||||
public static bool operator ==(StandardFormat left, StandardFormat right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(StandardFormat left, StandardFormat right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace System.Numerics.Hashing;
|
||||
|
||||
internal static class HashHelpers
|
||||
{
|
||||
public static readonly int RandomSeed = Guid.NewGuid().GetHashCode();
|
||||
|
||||
public static int Combine(int h1, int h2)
|
||||
{
|
||||
uint num = (uint)((h1 << 5) | (h1 >>> 27));
|
||||
return ((int)num + h1) ^ h2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System.Runtime.InteropServices;
|
||||
|
||||
public static class MemoryMarshal
|
||||
{
|
||||
public static bool TryGetArray<T>(ReadOnlyMemory<T> memory, out ArraySegment<T> segment)
|
||||
{
|
||||
int start;
|
||||
int length;
|
||||
object objectStartLength = memory.GetObjectStartLength(out start, out length);
|
||||
if (start < 0)
|
||||
{
|
||||
if (((MemoryManager<T>)objectStartLength).TryGetArray(out var segment2))
|
||||
{
|
||||
segment = new ArraySegment<T>(segment2.Array, segment2.Offset + (start & 0x7FFFFFFF), length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (objectStartLength is T[] array)
|
||||
{
|
||||
segment = new ArraySegment<T>(array, start, length & 0x7FFFFFFF);
|
||||
return true;
|
||||
}
|
||||
if ((length & 0x7FFFFFFF) == 0)
|
||||
{
|
||||
segment = new ArraySegment<T>(System.SpanHelpers.PerTypeValues<T>.EmptyArray);
|
||||
return true;
|
||||
}
|
||||
segment = default(ArraySegment<T>);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryGetMemoryManager<T, TManager>(ReadOnlyMemory<T> memory, out TManager manager) where TManager : MemoryManager<T>
|
||||
{
|
||||
int start;
|
||||
int length;
|
||||
TManager val = (manager = memory.GetObjectStartLength(out start, out length) as TManager);
|
||||
return manager != null;
|
||||
}
|
||||
|
||||
public static bool TryGetMemoryManager<T, TManager>(ReadOnlyMemory<T> memory, out TManager manager, out int start, out int length) where TManager : MemoryManager<T>
|
||||
{
|
||||
TManager val = (manager = memory.GetObjectStartLength(out start, out length) as TManager);
|
||||
start &= int.MaxValue;
|
||||
if (manager == null)
|
||||
{
|
||||
start = 0;
|
||||
length = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> ToEnumerable<T>(ReadOnlyMemory<T> memory)
|
||||
{
|
||||
for (int i = 0; i < memory.Length; i++)
|
||||
{
|
||||
yield return memory.Span[i];
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryGetString(ReadOnlyMemory<char> memory, out string text, out int start, out int length)
|
||||
{
|
||||
if (memory.GetObjectStartLength(out var start2, out var length2) is string text2)
|
||||
{
|
||||
text = text2;
|
||||
start = start2;
|
||||
length = length2;
|
||||
return true;
|
||||
}
|
||||
text = null;
|
||||
start = 0;
|
||||
length = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static T Read<T>(ReadOnlySpan<byte> source) where T : struct
|
||||
{
|
||||
if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
|
||||
}
|
||||
if (Unsafe.SizeOf<T>() > source.Length)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
|
||||
}
|
||||
return Unsafe.ReadUnaligned<T>(in GetReference(source));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryRead<T>(ReadOnlySpan<byte> source, out T value) where T : struct
|
||||
{
|
||||
if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
|
||||
}
|
||||
if (Unsafe.SizeOf<T>() > (uint)source.Length)
|
||||
{
|
||||
value = default(T);
|
||||
return false;
|
||||
}
|
||||
value = Unsafe.ReadUnaligned<T>(in GetReference(source));
|
||||
return true;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Write<T>(Span<byte> destination, ref T value) where T : struct
|
||||
{
|
||||
if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
|
||||
}
|
||||
if ((uint)Unsafe.SizeOf<T>() > (uint)destination.Length)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
|
||||
}
|
||||
Unsafe.WriteUnaligned(ref GetReference(destination), value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool TryWrite<T>(Span<byte> destination, ref T value) where T : struct
|
||||
{
|
||||
if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
|
||||
}
|
||||
if (Unsafe.SizeOf<T>() > (uint)destination.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Unsafe.WriteUnaligned(ref GetReference(destination), value);
|
||||
return true;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Memory<T> CreateFromPinnedArray<T>(T[] array, int start, int length)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
if (start != 0 || length != 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
}
|
||||
return default(Memory<T>);
|
||||
}
|
||||
if (default(T) == null && array.GetType() != typeof(T[]))
|
||||
{
|
||||
System.ThrowHelper.ThrowArrayTypeMismatchException();
|
||||
}
|
||||
if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
}
|
||||
return new Memory<T>((object)array, start, length | int.MinValue);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Span<byte> AsBytes<T>(Span<T> span) where T : struct
|
||||
{
|
||||
if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
|
||||
}
|
||||
int length = checked(span.Length * Unsafe.SizeOf<T>());
|
||||
return new Span<byte>(Unsafe.As<Pinnable<byte>>(span.Pinnable), span.ByteOffset, length);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ReadOnlySpan<byte> AsBytes<T>(ReadOnlySpan<T> span) where T : struct
|
||||
{
|
||||
if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
|
||||
}
|
||||
int length = checked(span.Length * Unsafe.SizeOf<T>());
|
||||
return new ReadOnlySpan<byte>(Unsafe.As<Pinnable<byte>>(span.Pinnable), span.ByteOffset, length);
|
||||
}
|
||||
|
||||
public static Memory<T> AsMemory<T>(ReadOnlyMemory<T> memory)
|
||||
{
|
||||
return Unsafe.As<ReadOnlyMemory<T>, Memory<T>>(ref memory);
|
||||
}
|
||||
|
||||
public unsafe static ref T GetReference<T>(Span<T> span)
|
||||
{
|
||||
if (span.Pinnable == null)
|
||||
{
|
||||
return ref Unsafe.AsRef<T>(span.ByteOffset.ToPointer());
|
||||
}
|
||||
return ref Unsafe.AddByteOffset(ref span.Pinnable.Data, span.ByteOffset);
|
||||
}
|
||||
|
||||
public unsafe static ref T GetReference<T>(ReadOnlySpan<T> span)
|
||||
{
|
||||
if (span.Pinnable == null)
|
||||
{
|
||||
return ref Unsafe.AsRef<T>(span.ByteOffset.ToPointer());
|
||||
}
|
||||
return ref Unsafe.AddByteOffset(ref span.Pinnable.Data, span.ByteOffset);
|
||||
}
|
||||
|
||||
public static Span<TTo> Cast<TFrom, TTo>(Span<TFrom> span) where TFrom : struct where TTo : struct
|
||||
{
|
||||
if (System.SpanHelpers.IsReferenceOrContainsReferences<TFrom>())
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(TFrom));
|
||||
}
|
||||
if (System.SpanHelpers.IsReferenceOrContainsReferences<TTo>())
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(TTo));
|
||||
}
|
||||
checked
|
||||
{
|
||||
int length = (int)unchecked(checked(unchecked((long)span.Length) * unchecked((long)Unsafe.SizeOf<TFrom>())) / Unsafe.SizeOf<TTo>());
|
||||
return new Span<TTo>(Unsafe.As<Pinnable<TTo>>(span.Pinnable), span.ByteOffset, length);
|
||||
}
|
||||
}
|
||||
|
||||
public static ReadOnlySpan<TTo> Cast<TFrom, TTo>(ReadOnlySpan<TFrom> span) where TFrom : struct where TTo : struct
|
||||
{
|
||||
if (System.SpanHelpers.IsReferenceOrContainsReferences<TFrom>())
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(TFrom));
|
||||
}
|
||||
if (System.SpanHelpers.IsReferenceOrContainsReferences<TTo>())
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(TTo));
|
||||
}
|
||||
checked
|
||||
{
|
||||
int length = (int)unchecked(checked(unchecked((long)span.Length) * unchecked((long)Unsafe.SizeOf<TFrom>())) / Unsafe.SizeOf<TTo>());
|
||||
return new ReadOnlySpan<TTo>(Unsafe.As<Pinnable<TTo>>(span.Pinnable), span.ByteOffset, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.Buffers;
|
||||
|
||||
namespace System.Runtime.InteropServices;
|
||||
|
||||
public static class SequenceMarshal
|
||||
{
|
||||
public static bool TryGetReadOnlySequenceSegment<T>(ReadOnlySequence<T> sequence, out ReadOnlySequenceSegment<T> startSegment, out int startIndex, out ReadOnlySequenceSegment<T> endSegment, out int endIndex)
|
||||
{
|
||||
return sequence.TryGetReadOnlySequenceSegment(out startSegment, out startIndex, out endSegment, out endIndex);
|
||||
}
|
||||
|
||||
public static bool TryGetArray<T>(ReadOnlySequence<T> sequence, out ArraySegment<T> segment)
|
||||
{
|
||||
return sequence.TryGetArray(out segment);
|
||||
}
|
||||
|
||||
public static bool TryGetReadOnlyMemory<T>(ReadOnlySequence<T> sequence, out ReadOnlyMemory<T> memory)
|
||||
{
|
||||
if (!sequence.IsSingleSegment)
|
||||
{
|
||||
memory = default(ReadOnlyMemory<T>);
|
||||
return false;
|
||||
}
|
||||
memory = sequence.First;
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool TryGetString(ReadOnlySequence<char> sequence, out string text, out int start, out int length)
|
||||
{
|
||||
return sequence.TryGetString(out text, out start, out length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
namespace System;
|
||||
|
||||
internal static class DecimalDecCalc
|
||||
{
|
||||
private static uint D32DivMod1E9(uint hi32, ref uint lo32)
|
||||
{
|
||||
ulong num = ((ulong)hi32 << 32) | lo32;
|
||||
lo32 = (uint)(num / 1000000000);
|
||||
return (uint)(num % 1000000000);
|
||||
}
|
||||
|
||||
internal static uint DecDivMod1E9(ref MutableDecimal value)
|
||||
{
|
||||
return D32DivMod1E9(D32DivMod1E9(D32DivMod1E9(0u, ref value.High), ref value.Mid), ref value.Low);
|
||||
}
|
||||
|
||||
internal static void DecAddInt32(ref MutableDecimal value, uint i)
|
||||
{
|
||||
if (D32AddCarry(ref value.Low, i) && D32AddCarry(ref value.Mid, 1u))
|
||||
{
|
||||
D32AddCarry(ref value.High, 1u);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool D32AddCarry(ref uint value, uint i)
|
||||
{
|
||||
uint num = value;
|
||||
uint num2 = (value = num + i);
|
||||
if (num2 >= num)
|
||||
{
|
||||
return num2 < i;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static void DecMul10(ref MutableDecimal value)
|
||||
{
|
||||
MutableDecimal d = value;
|
||||
DecShiftLeft(ref value);
|
||||
DecShiftLeft(ref value);
|
||||
DecAdd(ref value, d);
|
||||
DecShiftLeft(ref value);
|
||||
}
|
||||
|
||||
private static void DecShiftLeft(ref MutableDecimal value)
|
||||
{
|
||||
uint num = (((value.Low & 0x80000000u) != 0) ? 1u : 0u);
|
||||
uint num2 = (((value.Mid & 0x80000000u) != 0) ? 1u : 0u);
|
||||
value.Low <<= 1;
|
||||
value.Mid = (value.Mid << 1) | num;
|
||||
value.High = (value.High << 1) | num2;
|
||||
}
|
||||
|
||||
private static void DecAdd(ref MutableDecimal value, MutableDecimal d)
|
||||
{
|
||||
if (D32AddCarry(ref value.Low, d.Low) && D32AddCarry(ref value.Mid, 1u))
|
||||
{
|
||||
D32AddCarry(ref value.High, 1u);
|
||||
}
|
||||
if (D32AddCarry(ref value.Mid, d.Mid))
|
||||
{
|
||||
D32AddCarry(ref value.High, 1u);
|
||||
}
|
||||
D32AddCarry(ref value.High, d.High);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace System;
|
||||
|
||||
internal enum ExceptionArgument
|
||||
{
|
||||
length,
|
||||
start,
|
||||
minimumBufferSize,
|
||||
elementIndex,
|
||||
comparable,
|
||||
comparer,
|
||||
destination,
|
||||
offset,
|
||||
startSegment,
|
||||
endSegment,
|
||||
startIndex,
|
||||
endIndex,
|
||||
array,
|
||||
culture,
|
||||
manager
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
using System.Buffers;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System;
|
||||
|
||||
[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
|
||||
[DebuggerDisplay("{ToString(),raw}")]
|
||||
public readonly struct Memory<T>
|
||||
{
|
||||
private readonly object _object;
|
||||
|
||||
private readonly int _index;
|
||||
|
||||
private readonly int _length;
|
||||
|
||||
private const int RemoveFlagsBitMask = int.MaxValue;
|
||||
|
||||
public static Memory<T> Empty => default(Memory<T>);
|
||||
|
||||
public int Length => _length & 0x7FFFFFFF;
|
||||
|
||||
public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;
|
||||
|
||||
public Span<T> Span
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
Span<T> result;
|
||||
if (_index < 0)
|
||||
{
|
||||
result = ((MemoryManager<T>)_object).GetSpan();
|
||||
return result.Slice(_index & 0x7FFFFFFF, _length);
|
||||
}
|
||||
if (typeof(T) == typeof(char) && _object is string text)
|
||||
{
|
||||
result = new Span<T>(Unsafe.As<Pinnable<T>>(text), MemoryExtensions.StringAdjustment, text.Length);
|
||||
return result.Slice(_index, _length);
|
||||
}
|
||||
if (_object != null)
|
||||
{
|
||||
return new Span<T>((T[])_object, _index, _length & 0x7FFFFFFF);
|
||||
}
|
||||
result = default(Span<T>);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Memory(T[] array)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
this = default(Memory<T>);
|
||||
return;
|
||||
}
|
||||
if (default(T) == null && array.GetType() != typeof(T[]))
|
||||
{
|
||||
System.ThrowHelper.ThrowArrayTypeMismatchException();
|
||||
}
|
||||
_object = array;
|
||||
_index = 0;
|
||||
_length = array.Length;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal Memory(T[] array, int start)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
if (start != 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
}
|
||||
this = default(Memory<T>);
|
||||
return;
|
||||
}
|
||||
if (default(T) == null && array.GetType() != typeof(T[]))
|
||||
{
|
||||
System.ThrowHelper.ThrowArrayTypeMismatchException();
|
||||
}
|
||||
if ((uint)start > (uint)array.Length)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
}
|
||||
_object = array;
|
||||
_index = start;
|
||||
_length = array.Length - start;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Memory(T[] array, int start, int length)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
if (start != 0 || length != 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
}
|
||||
this = default(Memory<T>);
|
||||
return;
|
||||
}
|
||||
if (default(T) == null && array.GetType() != typeof(T[]))
|
||||
{
|
||||
System.ThrowHelper.ThrowArrayTypeMismatchException();
|
||||
}
|
||||
if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
}
|
||||
_object = array;
|
||||
_index = start;
|
||||
_length = length;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal Memory(MemoryManager<T> manager, int length)
|
||||
{
|
||||
if (length < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
}
|
||||
_object = manager;
|
||||
_index = int.MinValue;
|
||||
_length = length;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal Memory(MemoryManager<T> manager, int start, int length)
|
||||
{
|
||||
if (length < 0 || start < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
}
|
||||
_object = manager;
|
||||
_index = start | int.MinValue;
|
||||
_length = length;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal Memory(object obj, int start, int length)
|
||||
{
|
||||
_object = obj;
|
||||
_index = start;
|
||||
_length = length;
|
||||
}
|
||||
|
||||
public static implicit operator Memory<T>(T[] array)
|
||||
{
|
||||
return new Memory<T>(array);
|
||||
}
|
||||
|
||||
public static implicit operator Memory<T>(ArraySegment<T> segment)
|
||||
{
|
||||
return new Memory<T>(segment.Array, segment.Offset, segment.Count);
|
||||
}
|
||||
|
||||
public static implicit operator ReadOnlyMemory<T>(Memory<T> memory)
|
||||
{
|
||||
return Unsafe.As<Memory<T>, ReadOnlyMemory<T>>(ref memory);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (typeof(T) == typeof(char))
|
||||
{
|
||||
if (!(_object is string text))
|
||||
{
|
||||
return Span.ToString();
|
||||
}
|
||||
return text.Substring(_index, _length & 0x7FFFFFFF);
|
||||
}
|
||||
return $"System.Memory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Memory<T> Slice(int start)
|
||||
{
|
||||
int length = _length;
|
||||
int num = length & 0x7FFFFFFF;
|
||||
if ((uint)start > (uint)num)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
return new Memory<T>(_object, _index + start, length - start);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Memory<T> Slice(int start, int length)
|
||||
{
|
||||
int length2 = _length;
|
||||
int num = length2 & 0x7FFFFFFF;
|
||||
if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
}
|
||||
return new Memory<T>(_object, _index + start, length | (length2 & int.MinValue));
|
||||
}
|
||||
|
||||
public void CopyTo(Memory<T> destination)
|
||||
{
|
||||
Span.CopyTo(destination.Span);
|
||||
}
|
||||
|
||||
public bool TryCopyTo(Memory<T> destination)
|
||||
{
|
||||
return Span.TryCopyTo(destination.Span);
|
||||
}
|
||||
|
||||
public unsafe MemoryHandle Pin()
|
||||
{
|
||||
if (_index < 0)
|
||||
{
|
||||
return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
|
||||
}
|
||||
if (typeof(T) == typeof(char) && _object is string value)
|
||||
{
|
||||
GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
|
||||
void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
|
||||
return new MemoryHandle(pointer, handle);
|
||||
}
|
||||
if (_object is T[] array)
|
||||
{
|
||||
if (_length < 0)
|
||||
{
|
||||
void* pointer2 = Unsafe.Add<T>(Unsafe.AsPointer(in MemoryMarshal.GetReference((Span<T>)array)), _index);
|
||||
return new MemoryHandle(pointer2);
|
||||
}
|
||||
GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
|
||||
void* pointer3 = Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
|
||||
return new MemoryHandle(pointer3, handle2);
|
||||
}
|
||||
return default(MemoryHandle);
|
||||
}
|
||||
|
||||
public T[] ToArray()
|
||||
{
|
||||
return Span.ToArray();
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is ReadOnlyMemory<T> readOnlyMemory)
|
||||
{
|
||||
return readOnlyMemory.Equals(this);
|
||||
}
|
||||
if (obj is Memory<T> other)
|
||||
{
|
||||
return Equals(other);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Equals(Memory<T> other)
|
||||
{
|
||||
if (_object == other._object && _index == other._index)
|
||||
{
|
||||
return _length == other._length;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (_object == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int hashCode = _object.GetHashCode();
|
||||
int index = _index;
|
||||
int hashCode2 = index.GetHashCode();
|
||||
index = _length;
|
||||
return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
|
||||
}
|
||||
|
||||
private static int CombineHashCodes(int left, int right)
|
||||
{
|
||||
return ((left << 5) + left) ^ right;
|
||||
}
|
||||
|
||||
private static int CombineHashCodes(int h1, int h2, int h3)
|
||||
{
|
||||
return CombineHashCodes(CombineHashCodes(h1, h2), h3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System;
|
||||
|
||||
internal sealed class MemoryDebugView<T>
|
||||
{
|
||||
private readonly ReadOnlyMemory<T> _memory;
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public T[] Items => _memory.ToArray();
|
||||
|
||||
public MemoryDebugView(Memory<T> memory)
|
||||
{
|
||||
_memory = memory;
|
||||
}
|
||||
|
||||
public MemoryDebugView(ReadOnlyMemory<T> memory)
|
||||
{
|
||||
_memory = memory;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,42 @@
|
||||
namespace System;
|
||||
|
||||
internal struct MutableDecimal
|
||||
{
|
||||
public uint Flags;
|
||||
|
||||
public uint High;
|
||||
|
||||
public uint Low;
|
||||
|
||||
public uint Mid;
|
||||
|
||||
private const uint SignMask = 2147483648u;
|
||||
|
||||
private const uint ScaleMask = 16711680u;
|
||||
|
||||
private const int ScaleShift = 16;
|
||||
|
||||
public bool IsNegative
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Flags & 0x80000000u) != 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
Flags = (Flags & 0x7FFFFFFF) | (uint)(value ? int.MinValue : 0);
|
||||
}
|
||||
}
|
||||
|
||||
public int Scale
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)(Flags >> 16);
|
||||
}
|
||||
set
|
||||
{
|
||||
Flags = (Flags & 0xFF00FFFFu) | (uint)(value << 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System;
|
||||
|
||||
internal struct NUInt
|
||||
{
|
||||
private unsafe readonly void* _value = (void*)value;
|
||||
|
||||
private unsafe NUInt(uint value)
|
||||
{
|
||||
}
|
||||
|
||||
private unsafe NUInt(ulong value)
|
||||
{
|
||||
}
|
||||
|
||||
public static implicit operator NUInt(uint value)
|
||||
{
|
||||
return new NUInt(value);
|
||||
}
|
||||
|
||||
public unsafe static implicit operator IntPtr(NUInt value)
|
||||
{
|
||||
return (IntPtr)value._value;
|
||||
}
|
||||
|
||||
public static explicit operator NUInt(int value)
|
||||
{
|
||||
return new NUInt((uint)value);
|
||||
}
|
||||
|
||||
public unsafe static explicit operator void*(NUInt value)
|
||||
{
|
||||
return value._value;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public unsafe static NUInt operator *(NUInt left, NUInt right)
|
||||
{
|
||||
if (sizeof(IntPtr) != 4)
|
||||
{
|
||||
return new NUInt((ulong)left._value * (ulong)right._value);
|
||||
}
|
||||
return new NUInt((uint)((int)left._value * (int)right._value));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace System;
|
||||
|
||||
internal static class NotImplemented
|
||||
{
|
||||
internal static Exception ByDesign => new NotImplementedException();
|
||||
|
||||
internal static Exception ByDesignWithMessage(string message)
|
||||
{
|
||||
return new NotImplementedException(message);
|
||||
}
|
||||
|
||||
internal static Exception ActiveIssue(string issue)
|
||||
{
|
||||
return new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
using System.Buffers.Text;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System;
|
||||
|
||||
internal static class Number
|
||||
{
|
||||
private static class DoubleHelper
|
||||
{
|
||||
public unsafe static uint Exponent(double d)
|
||||
{
|
||||
return (((uint*)(&d))[1] >> 20) & 0x7FF;
|
||||
}
|
||||
|
||||
public unsafe static ulong Mantissa(double d)
|
||||
{
|
||||
return (uint)(*(int*)(&d)) | ((ulong)(((uint*)(&d))[1] & 0xFFFFF) << 32);
|
||||
}
|
||||
|
||||
public unsafe static bool Sign(double d)
|
||||
{
|
||||
return ((uint*)(&d))[1] >> 31 != 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal const int DECIMAL_PRECISION = 29;
|
||||
|
||||
private static readonly ulong[] s_rgval64Power10 = new ulong[30]
|
||||
{
|
||||
11529215046068469760uL, 14411518807585587200uL, 18014398509481984000uL, 11258999068426240000uL, 14073748835532800000uL, 17592186044416000000uL, 10995116277760000000uL, 13743895347200000000uL, 17179869184000000000uL, 10737418240000000000uL,
|
||||
13421772800000000000uL, 16777216000000000000uL, 10485760000000000000uL, 13107200000000000000uL, 16384000000000000000uL, 14757395258967641293uL, 11805916207174113035uL, 9444732965739290428uL, 15111572745182864686uL, 12089258196146291749uL,
|
||||
9671406556917033399uL, 15474250491067253438uL, 12379400392853802751uL, 9903520314283042201uL, 15845632502852867522uL, 12676506002282294018uL, 10141204801825835215uL, 16225927682921336344uL, 12980742146337069075uL, 10384593717069655260uL
|
||||
};
|
||||
|
||||
private static readonly sbyte[] s_rgexp64Power10 = new sbyte[15]
|
||||
{
|
||||
4, 7, 10, 14, 17, 20, 24, 27, 30, 34,
|
||||
37, 40, 44, 47, 50
|
||||
};
|
||||
|
||||
private static readonly ulong[] s_rgval64Power10By16 = new ulong[42]
|
||||
{
|
||||
10240000000000000000uL, 11368683772161602974uL, 12621774483536188886uL, 14012984643248170708uL, 15557538194652854266uL, 17272337110188889248uL, 9588073174409622172uL, 10644899600020376798uL, 11818212630765741798uL, 13120851772591970216uL,
|
||||
14567071740625403792uL, 16172698447808779622uL, 17955302187076837696uL, 9967194951097567532uL, 11065809325636130658uL, 12285516299433008778uL, 13639663065038175358uL, 15143067982934716296uL, 16812182738118149112uL, 9332636185032188787uL,
|
||||
10361307573072618722uL, 16615349947311448416uL, 14965776766268445891uL, 13479973333575319909uL, 12141680576410806707uL, 10936253623915059637uL, 9850501549098619819uL, 17745086042373215136uL, 15983352577617880260uL, 14396524142538228461uL,
|
||||
12967236152753103031uL, 11679847981112819795uL, 10520271803096747049uL, 9475818434452569218uL, 17070116948172427008uL, 15375394465392026135uL, 13848924157002783096uL, 12474001934591998882uL, 11235582092889474480uL, 10120112665365530972uL,
|
||||
18230774251475056952uL, 16420821625123739930uL
|
||||
};
|
||||
|
||||
private static readonly short[] s_rgexp64Power10By16 = new short[21]
|
||||
{
|
||||
54, 107, 160, 213, 266, 319, 373, 426, 479, 532,
|
||||
585, 638, 691, 745, 798, 851, 904, 957, 1010, 1064,
|
||||
1117
|
||||
};
|
||||
|
||||
public static void RoundNumber(ref NumberBuffer number, int pos)
|
||||
{
|
||||
Span<byte> digits = number.Digits;
|
||||
int i;
|
||||
for (i = 0; i < pos && digits[i] != 0; i++)
|
||||
{
|
||||
}
|
||||
if (i == pos && digits[i] >= 53)
|
||||
{
|
||||
while (i > 0 && digits[i - 1] == 57)
|
||||
{
|
||||
i--;
|
||||
}
|
||||
if (i > 0)
|
||||
{
|
||||
digits[i - 1]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
number.Scale++;
|
||||
digits[0] = 49;
|
||||
i = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (i > 0 && digits[i - 1] == 48)
|
||||
{
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
number.Scale = 0;
|
||||
number.IsNegative = false;
|
||||
}
|
||||
digits[i] = 0;
|
||||
}
|
||||
|
||||
internal static bool NumberBufferToDouble(ref NumberBuffer number, out double value)
|
||||
{
|
||||
double num = NumberToDouble(ref number);
|
||||
uint num2 = DoubleHelper.Exponent(num);
|
||||
ulong num3 = DoubleHelper.Mantissa(num);
|
||||
switch (num2)
|
||||
{
|
||||
case 2047u:
|
||||
value = 0.0;
|
||||
return false;
|
||||
case 0u:
|
||||
if (num3 == 0L)
|
||||
{
|
||||
num = 0.0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
value = num;
|
||||
return true;
|
||||
}
|
||||
|
||||
public unsafe static bool NumberBufferToDecimal(ref NumberBuffer number, ref decimal value)
|
||||
{
|
||||
MutableDecimal source = default(MutableDecimal);
|
||||
byte* ptr = number.UnsafeDigits;
|
||||
int num = number.Scale;
|
||||
if (*ptr == 0)
|
||||
{
|
||||
if (num > 0)
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (num > 29)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
while ((num > 0 || (*ptr != 0 && num > -28)) && (source.High < 429496729 || (source.High == 429496729 && (source.Mid < 2576980377u || (source.Mid == 2576980377u && (source.Low < 2576980377u || (source.Low == 2576980377u && *ptr <= 53)))))))
|
||||
{
|
||||
DecimalDecCalc.DecMul10(ref source);
|
||||
if (*ptr != 0)
|
||||
{
|
||||
DecimalDecCalc.DecAddInt32(ref source, (uint)(*(ptr++) - 48));
|
||||
}
|
||||
num--;
|
||||
}
|
||||
if (*(ptr++) >= 53)
|
||||
{
|
||||
bool flag = true;
|
||||
if (*(ptr - 1) == 53 && *(ptr - 2) % 2 == 0)
|
||||
{
|
||||
int num2 = 20;
|
||||
while (*ptr == 48 && num2 != 0)
|
||||
{
|
||||
ptr++;
|
||||
num2--;
|
||||
}
|
||||
if (*ptr == 0 || num2 == 0)
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
DecimalDecCalc.DecAddInt32(ref source, 1u);
|
||||
if ((source.High | source.Mid | source.Low) == 0)
|
||||
{
|
||||
source.High = 429496729u;
|
||||
source.Mid = 2576980377u;
|
||||
source.Low = 2576980378u;
|
||||
num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (num > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (num <= -29)
|
||||
{
|
||||
source.High = 0u;
|
||||
source.Low = 0u;
|
||||
source.Mid = 0u;
|
||||
source.Scale = 28;
|
||||
}
|
||||
else
|
||||
{
|
||||
source.Scale = -num;
|
||||
}
|
||||
source.IsNegative = number.IsNegative;
|
||||
value = Unsafe.As<MutableDecimal, decimal>(ref source);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void DecimalToNumber(decimal value, ref NumberBuffer number)
|
||||
{
|
||||
ref MutableDecimal reference = ref Unsafe.As<decimal, MutableDecimal>(ref value);
|
||||
Span<byte> digits = number.Digits;
|
||||
number.IsNegative = reference.IsNegative;
|
||||
int num = 29;
|
||||
while ((reference.Mid != 0) | (reference.High != 0))
|
||||
{
|
||||
uint num2 = DecimalDecCalc.DecDivMod1E9(ref reference);
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
digits[--num] = (byte)(num2 % 10 + 48);
|
||||
num2 /= 10;
|
||||
}
|
||||
}
|
||||
for (uint num3 = reference.Low; num3 != 0; num3 /= 10)
|
||||
{
|
||||
digits[--num] = (byte)(num3 % 10 + 48);
|
||||
}
|
||||
int num4 = 29 - num;
|
||||
number.Scale = num4 - reference.Scale;
|
||||
Span<byte> digits2 = number.Digits;
|
||||
int index = 0;
|
||||
while (--num4 >= 0)
|
||||
{
|
||||
digits2[index++] = digits[num++];
|
||||
}
|
||||
digits2[index] = 0;
|
||||
}
|
||||
|
||||
private static uint DigitsToInt(ReadOnlySpan<byte> digits, int count)
|
||||
{
|
||||
uint value;
|
||||
int bytesConsumed;
|
||||
bool flag = Utf8Parser.TryParse(digits.Slice(0, count), out value, out bytesConsumed, 'D');
|
||||
return value;
|
||||
}
|
||||
|
||||
private static ulong Mul32x32To64(uint a, uint b)
|
||||
{
|
||||
return (ulong)a * (ulong)b;
|
||||
}
|
||||
|
||||
private static ulong Mul64Lossy(ulong a, ulong b, ref int pexp)
|
||||
{
|
||||
ulong num = Mul32x32To64((uint)(a >> 32), (uint)(b >> 32)) + (Mul32x32To64((uint)(a >> 32), (uint)b) >> 32) + (Mul32x32To64((uint)a, (uint)(b >> 32)) >> 32);
|
||||
if ((num & 0x8000000000000000uL) == 0L)
|
||||
{
|
||||
num <<= 1;
|
||||
pexp--;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
private static int abs(int value)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
return -value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private unsafe static double NumberToDouble(ref NumberBuffer number)
|
||||
{
|
||||
ReadOnlySpan<byte> digits = number.Digits;
|
||||
int i = 0;
|
||||
int numDigits = number.NumDigits;
|
||||
int num = numDigits;
|
||||
for (; digits[i] == 48; i++)
|
||||
{
|
||||
num--;
|
||||
}
|
||||
if (num == 0)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
int num2 = Math.Min(num, 9);
|
||||
num -= num2;
|
||||
ulong num3 = DigitsToInt(digits, num2);
|
||||
if (num > 0)
|
||||
{
|
||||
num2 = Math.Min(num, 9);
|
||||
num -= num2;
|
||||
uint b = (uint)(s_rgval64Power10[num2 - 1] >> 64 - s_rgexp64Power10[num2 - 1]);
|
||||
num3 = Mul32x32To64((uint)num3, b) + DigitsToInt(digits.Slice(9), num2);
|
||||
}
|
||||
int num4 = number.Scale - (numDigits - num);
|
||||
int num5 = abs(num4);
|
||||
if (num5 >= 352)
|
||||
{
|
||||
ulong num6 = ((num4 > 0) ? 9218868437227405312uL : 0);
|
||||
if (number.IsNegative)
|
||||
{
|
||||
num6 |= 0x8000000000000000uL;
|
||||
}
|
||||
return *(double*)(&num6);
|
||||
}
|
||||
int pexp = 64;
|
||||
if ((num3 & 0xFFFFFFFF00000000uL) == 0L)
|
||||
{
|
||||
num3 <<= 32;
|
||||
pexp -= 32;
|
||||
}
|
||||
if ((num3 & 0xFFFF000000000000uL) == 0L)
|
||||
{
|
||||
num3 <<= 16;
|
||||
pexp -= 16;
|
||||
}
|
||||
if ((num3 & 0xFF00000000000000uL) == 0L)
|
||||
{
|
||||
num3 <<= 8;
|
||||
pexp -= 8;
|
||||
}
|
||||
if ((num3 & 0xF000000000000000uL) == 0L)
|
||||
{
|
||||
num3 <<= 4;
|
||||
pexp -= 4;
|
||||
}
|
||||
if ((num3 & 0xC000000000000000uL) == 0L)
|
||||
{
|
||||
num3 <<= 2;
|
||||
pexp -= 2;
|
||||
}
|
||||
if ((num3 & 0x8000000000000000uL) == 0L)
|
||||
{
|
||||
num3 <<= 1;
|
||||
pexp--;
|
||||
}
|
||||
int num7 = num5 & 0xF;
|
||||
if (num7 != 0)
|
||||
{
|
||||
int num8 = s_rgexp64Power10[num7 - 1];
|
||||
pexp += ((num4 < 0) ? (-num8 + 1) : num8);
|
||||
ulong b2 = s_rgval64Power10[num7 + ((num4 < 0) ? 15 : 0) - 1];
|
||||
num3 = Mul64Lossy(num3, b2, ref pexp);
|
||||
}
|
||||
num7 = num5 >> 4;
|
||||
if (num7 != 0)
|
||||
{
|
||||
int num9 = s_rgexp64Power10By16[num7 - 1];
|
||||
pexp += ((num4 < 0) ? (-num9 + 1) : num9);
|
||||
ulong b3 = s_rgval64Power10By16[num7 + ((num4 < 0) ? 21 : 0) - 1];
|
||||
num3 = Mul64Lossy(num3, b3, ref pexp);
|
||||
}
|
||||
if (((int)num3 & 0x400) != 0)
|
||||
{
|
||||
ulong num10 = num3 + 1023 + (ulong)(((int)num3 >> 11) & 1);
|
||||
if (num10 < num3)
|
||||
{
|
||||
num10 = (num10 >> 1) | 0x8000000000000000uL;
|
||||
pexp++;
|
||||
}
|
||||
num3 = num10;
|
||||
}
|
||||
pexp += 1022;
|
||||
num3 = ((pexp <= 0) ? ((pexp == -52 && num3 >= 9223372036854775896uL) ? 1 : ((pexp > -52) ? (num3 >> -pexp + 11 + 1) : 0)) : ((pexp < 2047) ? ((ulong)((long)pexp << 52) + ((num3 >> 11) & 0xFFFFFFFFFFFFFL)) : 9218868437227405312uL));
|
||||
if (number.IsNegative)
|
||||
{
|
||||
num3 |= 0x8000000000000000uL;
|
||||
}
|
||||
return *(double*)(&num3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace System;
|
||||
|
||||
internal ref struct NumberBuffer
|
||||
{
|
||||
public int Scale;
|
||||
|
||||
public bool IsNegative;
|
||||
|
||||
public const int BufferSize = 51;
|
||||
|
||||
private byte _b0;
|
||||
|
||||
private byte _b1;
|
||||
|
||||
private byte _b2;
|
||||
|
||||
private byte _b3;
|
||||
|
||||
private byte _b4;
|
||||
|
||||
private byte _b5;
|
||||
|
||||
private byte _b6;
|
||||
|
||||
private byte _b7;
|
||||
|
||||
private byte _b8;
|
||||
|
||||
private byte _b9;
|
||||
|
||||
private byte _b10;
|
||||
|
||||
private byte _b11;
|
||||
|
||||
private byte _b12;
|
||||
|
||||
private byte _b13;
|
||||
|
||||
private byte _b14;
|
||||
|
||||
private byte _b15;
|
||||
|
||||
private byte _b16;
|
||||
|
||||
private byte _b17;
|
||||
|
||||
private byte _b18;
|
||||
|
||||
private byte _b19;
|
||||
|
||||
private byte _b20;
|
||||
|
||||
private byte _b21;
|
||||
|
||||
private byte _b22;
|
||||
|
||||
private byte _b23;
|
||||
|
||||
private byte _b24;
|
||||
|
||||
private byte _b25;
|
||||
|
||||
private byte _b26;
|
||||
|
||||
private byte _b27;
|
||||
|
||||
private byte _b28;
|
||||
|
||||
private byte _b29;
|
||||
|
||||
private byte _b30;
|
||||
|
||||
private byte _b31;
|
||||
|
||||
private byte _b32;
|
||||
|
||||
private byte _b33;
|
||||
|
||||
private byte _b34;
|
||||
|
||||
private byte _b35;
|
||||
|
||||
private byte _b36;
|
||||
|
||||
private byte _b37;
|
||||
|
||||
private byte _b38;
|
||||
|
||||
private byte _b39;
|
||||
|
||||
private byte _b40;
|
||||
|
||||
private byte _b41;
|
||||
|
||||
private byte _b42;
|
||||
|
||||
private byte _b43;
|
||||
|
||||
private byte _b44;
|
||||
|
||||
private byte _b45;
|
||||
|
||||
private byte _b46;
|
||||
|
||||
private byte _b47;
|
||||
|
||||
private byte _b48;
|
||||
|
||||
private byte _b49;
|
||||
|
||||
private byte _b50;
|
||||
|
||||
public unsafe Span<byte> Digits => new Span<byte>(Unsafe.AsPointer(in _b0), 51);
|
||||
|
||||
public unsafe byte* UnsafeDigits => (byte*)Unsafe.AsPointer(in _b0);
|
||||
|
||||
public int NumDigits => Digits.IndexOf((byte)0);
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
public void CheckConsistency()
|
||||
{
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append('[');
|
||||
stringBuilder.Append('"');
|
||||
Span<byte> digits = Digits;
|
||||
for (int i = 0; i < 51; i++)
|
||||
{
|
||||
byte b = digits[i];
|
||||
if (b == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
stringBuilder.Append((char)b);
|
||||
}
|
||||
stringBuilder.Append('"');
|
||||
stringBuilder.Append(", Scale = " + Scale);
|
||||
stringBuilder.Append(", IsNegative = " + IsNegative);
|
||||
stringBuilder.Append(']');
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal sealed class Pinnable<T>
|
||||
{
|
||||
public T Data;
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
using System.Buffers;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace System;
|
||||
|
||||
[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
|
||||
[DebuggerDisplay("{ToString(),raw}")]
|
||||
public readonly struct ReadOnlyMemory<T>
|
||||
{
|
||||
private readonly object _object;
|
||||
|
||||
private readonly int _index;
|
||||
|
||||
private readonly int _length;
|
||||
|
||||
internal const int RemoveFlagsBitMask = int.MaxValue;
|
||||
|
||||
public static ReadOnlyMemory<T> Empty => default(ReadOnlyMemory<T>);
|
||||
|
||||
public int Length => _length & 0x7FFFFFFF;
|
||||
|
||||
public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;
|
||||
|
||||
public ReadOnlySpan<T> Span
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
if (_index < 0)
|
||||
{
|
||||
return ((MemoryManager<T>)_object).GetSpan().Slice(_index & 0x7FFFFFFF, _length);
|
||||
}
|
||||
ReadOnlySpan<T> result;
|
||||
if (typeof(T) == typeof(char) && _object is string text)
|
||||
{
|
||||
result = new ReadOnlySpan<T>(Unsafe.As<Pinnable<T>>(text), MemoryExtensions.StringAdjustment, text.Length);
|
||||
return result.Slice(_index, _length);
|
||||
}
|
||||
if (_object != null)
|
||||
{
|
||||
return new ReadOnlySpan<T>((T[])_object, _index, _length & 0x7FFFFFFF);
|
||||
}
|
||||
result = default(ReadOnlySpan<T>);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ReadOnlyMemory(T[] array)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
this = default(ReadOnlyMemory<T>);
|
||||
return;
|
||||
}
|
||||
_object = array;
|
||||
_index = 0;
|
||||
_length = array.Length;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ReadOnlyMemory(T[] array, int start, int length)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
if (start != 0 || length != 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
}
|
||||
this = default(ReadOnlyMemory<T>);
|
||||
return;
|
||||
}
|
||||
if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException();
|
||||
}
|
||||
_object = array;
|
||||
_index = start;
|
||||
_length = length;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal ReadOnlyMemory(object obj, int start, int length)
|
||||
{
|
||||
_object = obj;
|
||||
_index = start;
|
||||
_length = length;
|
||||
}
|
||||
|
||||
public static implicit operator ReadOnlyMemory<T>(T[] array)
|
||||
{
|
||||
return new ReadOnlyMemory<T>(array);
|
||||
}
|
||||
|
||||
public static implicit operator ReadOnlyMemory<T>(ArraySegment<T> segment)
|
||||
{
|
||||
return new ReadOnlyMemory<T>(segment.Array, segment.Offset, segment.Count);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (typeof(T) == typeof(char))
|
||||
{
|
||||
if (!(_object is string text))
|
||||
{
|
||||
return Span.ToString();
|
||||
}
|
||||
return text.Substring(_index, _length & 0x7FFFFFFF);
|
||||
}
|
||||
return $"System.ReadOnlyMemory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ReadOnlyMemory<T> Slice(int start)
|
||||
{
|
||||
int length = _length;
|
||||
int num = length & 0x7FFFFFFF;
|
||||
if ((uint)start > (uint)num)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
return new ReadOnlyMemory<T>(_object, _index + start, length - start);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ReadOnlyMemory<T> Slice(int start, int length)
|
||||
{
|
||||
int length2 = _length;
|
||||
int num = _length & 0x7FFFFFFF;
|
||||
if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
return new ReadOnlyMemory<T>(_object, _index + start, length | (length2 & int.MinValue));
|
||||
}
|
||||
|
||||
public void CopyTo(Memory<T> destination)
|
||||
{
|
||||
Span.CopyTo(destination.Span);
|
||||
}
|
||||
|
||||
public bool TryCopyTo(Memory<T> destination)
|
||||
{
|
||||
return Span.TryCopyTo(destination.Span);
|
||||
}
|
||||
|
||||
public unsafe MemoryHandle Pin()
|
||||
{
|
||||
if (_index < 0)
|
||||
{
|
||||
return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
|
||||
}
|
||||
if (typeof(T) == typeof(char) && _object is string value)
|
||||
{
|
||||
GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
|
||||
void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
|
||||
return new MemoryHandle(pointer, handle);
|
||||
}
|
||||
if (_object is T[] array)
|
||||
{
|
||||
if (_length < 0)
|
||||
{
|
||||
void* pointer2 = Unsafe.Add<T>(Unsafe.AsPointer(in MemoryMarshal.GetReference((Span<T>)array)), _index);
|
||||
return new MemoryHandle(pointer2);
|
||||
}
|
||||
GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
|
||||
void* pointer3 = Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
|
||||
return new MemoryHandle(pointer3, handle2);
|
||||
}
|
||||
return default(MemoryHandle);
|
||||
}
|
||||
|
||||
public T[] ToArray()
|
||||
{
|
||||
return Span.ToArray();
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is ReadOnlyMemory<T> other)
|
||||
{
|
||||
return Equals(other);
|
||||
}
|
||||
if (obj is Memory<T> memory)
|
||||
{
|
||||
return Equals(memory);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Equals(ReadOnlyMemory<T> other)
|
||||
{
|
||||
if (_object == other._object && _index == other._index)
|
||||
{
|
||||
return _length == other._length;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
if (_object == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int hashCode = _object.GetHashCode();
|
||||
int index = _index;
|
||||
int hashCode2 = index.GetHashCode();
|
||||
index = _length;
|
||||
return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
|
||||
}
|
||||
|
||||
private static int CombineHashCodes(int left, int right)
|
||||
{
|
||||
return ((left << 5) + left) ^ right;
|
||||
}
|
||||
|
||||
private static int CombineHashCodes(int h1, int h2, int h3)
|
||||
{
|
||||
return CombineHashCodes(CombineHashCodes(h1, h2), h3);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal object GetObjectStartLength(out int start, out int length)
|
||||
{
|
||||
start = _index;
|
||||
length = _length;
|
||||
return _object;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System;
|
||||
|
||||
[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
|
||||
[DebuggerDisplay("{ToString(),raw}")]
|
||||
[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
|
||||
[DebuggerDisplay("{ToString(),raw}")]
|
||||
public readonly ref struct ReadOnlySpan<T>
|
||||
{
|
||||
public ref struct Enumerator
|
||||
{
|
||||
private readonly ReadOnlySpan<T> _span;
|
||||
|
||||
private int _index;
|
||||
|
||||
public ref readonly T Current
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return ref _span[_index];
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal Enumerator(ReadOnlySpan<T> span)
|
||||
{
|
||||
_span = span;
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool MoveNext()
|
||||
{
|
||||
int num = _index + 1;
|
||||
if (num < _span.Length)
|
||||
{
|
||||
_index = num;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Pinnable<T> _pinnable;
|
||||
|
||||
private readonly IntPtr _byteOffset;
|
||||
|
||||
private readonly int _length;
|
||||
|
||||
public int Length => _length;
|
||||
|
||||
public bool IsEmpty => _length == 0;
|
||||
|
||||
public static ReadOnlySpan<T> Empty => default(ReadOnlySpan<T>);
|
||||
|
||||
public unsafe ref readonly T this[int index]
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
if ((uint)index >= (uint)_length)
|
||||
{
|
||||
System.ThrowHelper.ThrowIndexOutOfRangeException();
|
||||
}
|
||||
if (_pinnable == null)
|
||||
{
|
||||
IntPtr byteOffset = _byteOffset;
|
||||
return ref Unsafe.Add(ref Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
|
||||
}
|
||||
return ref Unsafe.Add(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset), index);
|
||||
}
|
||||
}
|
||||
|
||||
internal Pinnable<T> Pinnable => _pinnable;
|
||||
|
||||
internal IntPtr ByteOffset => _byteOffset;
|
||||
|
||||
public static bool operator !=(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
[Obsolete("Equals() on ReadOnlySpan will always throw an exception. Use == instead.")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
|
||||
}
|
||||
|
||||
[Obsolete("GetHashCode() on ReadOnlySpan will always throw an exception.")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
|
||||
}
|
||||
|
||||
public static implicit operator ReadOnlySpan<T>(T[] array)
|
||||
{
|
||||
return new ReadOnlySpan<T>(array);
|
||||
}
|
||||
|
||||
public static implicit operator ReadOnlySpan<T>(ArraySegment<T> segment)
|
||||
{
|
||||
return new ReadOnlySpan<T>(segment.Array, segment.Offset, segment.Count);
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ReadOnlySpan(T[] array)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
this = default(ReadOnlySpan<T>);
|
||||
return;
|
||||
}
|
||||
_length = array.Length;
|
||||
_pinnable = Unsafe.As<Pinnable<T>>(array);
|
||||
_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ReadOnlySpan(T[] array, int start, int length)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
if (start != 0 || length != 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
this = default(ReadOnlySpan<T>);
|
||||
return;
|
||||
}
|
||||
if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
_length = length;
|
||||
_pinnable = Unsafe.As<Pinnable<T>>(array);
|
||||
_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public unsafe ReadOnlySpan(void* pointer, int length)
|
||||
{
|
||||
if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
|
||||
}
|
||||
if (length < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
_length = length;
|
||||
_pinnable = null;
|
||||
_byteOffset = new IntPtr(pointer);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal ReadOnlySpan(Pinnable<T> pinnable, IntPtr byteOffset, int length)
|
||||
{
|
||||
_length = length;
|
||||
_pinnable = pinnable;
|
||||
_byteOffset = byteOffset;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public unsafe ref readonly T GetPinnableReference()
|
||||
{
|
||||
if (_length != 0)
|
||||
{
|
||||
if (_pinnable == null)
|
||||
{
|
||||
IntPtr byteOffset = _byteOffset;
|
||||
return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
|
||||
}
|
||||
return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
|
||||
}
|
||||
return ref Unsafe.AsRef<T>(null);
|
||||
}
|
||||
|
||||
public void CopyTo(Span<T> destination)
|
||||
{
|
||||
if (!TryCopyTo(destination))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryCopyTo(Span<T> destination)
|
||||
{
|
||||
int length = _length;
|
||||
int length2 = destination.Length;
|
||||
if (length == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ((uint)length > (uint)length2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ref T src = ref DangerousGetPinnableReference();
|
||||
System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool operator ==(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
|
||||
{
|
||||
if (left._length == right._length)
|
||||
{
|
||||
return Unsafe.AreSame(in left.DangerousGetPinnableReference(), in right.DangerousGetPinnableReference());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public unsafe override string ToString()
|
||||
{
|
||||
if (typeof(T) == typeof(char))
|
||||
{
|
||||
if (_byteOffset == MemoryExtensions.StringAdjustment)
|
||||
{
|
||||
object obj = Unsafe.As<object>(_pinnable);
|
||||
if (obj is string text && _length == text.Length)
|
||||
{
|
||||
return text;
|
||||
}
|
||||
}
|
||||
fixed (char* value = &Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
|
||||
{
|
||||
return new string(value, 0, _length);
|
||||
}
|
||||
}
|
||||
return $"System.ReadOnlySpan<{typeof(T).Name}>[{_length}]";
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ReadOnlySpan<T> Slice(int start)
|
||||
{
|
||||
if ((uint)start > (uint)_length)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
IntPtr byteOffset = _byteOffset.Add<T>(start);
|
||||
int length = _length - start;
|
||||
return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ReadOnlySpan<T> Slice(int start, int length)
|
||||
{
|
||||
if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
IntPtr byteOffset = _byteOffset.Add<T>(start);
|
||||
return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
|
||||
}
|
||||
|
||||
public T[] ToArray()
|
||||
{
|
||||
if (_length == 0)
|
||||
{
|
||||
return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
|
||||
}
|
||||
T[] array = new T[_length];
|
||||
CopyTo(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
internal unsafe ref T DangerousGetPinnableReference()
|
||||
{
|
||||
if (_pinnable == null)
|
||||
{
|
||||
IntPtr byteOffset = _byteOffset;
|
||||
return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
|
||||
}
|
||||
return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using FxResources.System.Memory;
|
||||
|
||||
namespace System;
|
||||
|
||||
internal static class SR
|
||||
{
|
||||
private static ResourceManager s_resourceManager;
|
||||
|
||||
private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType));
|
||||
|
||||
internal static Type ResourceType { get; } = typeof(FxResources.System.Memory.SR);
|
||||
|
||||
internal static string NotSupported_CannotCallEqualsOnSpan => GetResourceString("NotSupported_CannotCallEqualsOnSpan", null);
|
||||
|
||||
internal static string NotSupported_CannotCallGetHashCodeOnSpan => GetResourceString("NotSupported_CannotCallGetHashCodeOnSpan", null);
|
||||
|
||||
internal static string Argument_InvalidTypeWithPointersNotSupported => GetResourceString("Argument_InvalidTypeWithPointersNotSupported", null);
|
||||
|
||||
internal static string Argument_DestinationTooShort => GetResourceString("Argument_DestinationTooShort", null);
|
||||
|
||||
internal static string MemoryDisposed => GetResourceString("MemoryDisposed", null);
|
||||
|
||||
internal static string OutstandingReferences => GetResourceString("OutstandingReferences", null);
|
||||
|
||||
internal static string Argument_BadFormatSpecifier => GetResourceString("Argument_BadFormatSpecifier", null);
|
||||
|
||||
internal static string Argument_GWithPrecisionNotSupported => GetResourceString("Argument_GWithPrecisionNotSupported", null);
|
||||
|
||||
internal static string Argument_CannotParsePrecision => GetResourceString("Argument_CannotParsePrecision", null);
|
||||
|
||||
internal static string Argument_PrecisionTooLarge => GetResourceString("Argument_PrecisionTooLarge", null);
|
||||
|
||||
internal static string Argument_OverlapAlignmentMismatch => GetResourceString("Argument_OverlapAlignmentMismatch", null);
|
||||
|
||||
internal static string EndPositionNotReached => GetResourceString("EndPositionNotReached", null);
|
||||
|
||||
internal static string UnexpectedSegmentType => GetResourceString("UnexpectedSegmentType", null);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static bool UsingResourceKeys()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static string GetResourceString(string resourceKey, string defaultString)
|
||||
{
|
||||
string text = null;
|
||||
try
|
||||
{
|
||||
text = ResourceManager.GetString(resourceKey);
|
||||
}
|
||||
catch (MissingManifestResourceException)
|
||||
{
|
||||
}
|
||||
if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal))
|
||||
{
|
||||
return defaultString;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
internal static string Format(string resourceFormat, params object[] args)
|
||||
{
|
||||
if (args != null)
|
||||
{
|
||||
if (UsingResourceKeys())
|
||||
{
|
||||
return resourceFormat + string.Join(", ", args);
|
||||
}
|
||||
return string.Format(resourceFormat, args);
|
||||
}
|
||||
return resourceFormat;
|
||||
}
|
||||
|
||||
internal static string Format(string resourceFormat, object p1)
|
||||
{
|
||||
if (UsingResourceKeys())
|
||||
{
|
||||
return string.Join(", ", new object[2] { resourceFormat, p1 });
|
||||
}
|
||||
return string.Format(resourceFormat, p1);
|
||||
}
|
||||
|
||||
internal static string Format(string resourceFormat, object p1, object p2)
|
||||
{
|
||||
if (UsingResourceKeys())
|
||||
{
|
||||
return string.Join(", ", new object[3] { resourceFormat, p1, p2 });
|
||||
}
|
||||
return string.Format(resourceFormat, p1, p2);
|
||||
}
|
||||
|
||||
internal static string Format(string resourceFormat, object p1, object p2, object p3)
|
||||
{
|
||||
if (UsingResourceKeys())
|
||||
{
|
||||
return string.Join(", ", new object[4] { resourceFormat, p1, p2, p3 });
|
||||
}
|
||||
return string.Format(resourceFormat, p1, p2, p3);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.ComponentModel;
|
||||
using System.Numerics.Hashing;
|
||||
|
||||
namespace System;
|
||||
|
||||
public readonly struct SequencePosition(object @object, int integer) : IEquatable<SequencePosition>
|
||||
{
|
||||
private readonly object _object = @object;
|
||||
|
||||
private readonly int _integer = integer;
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public object GetObject()
|
||||
{
|
||||
return _object;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public int GetInteger()
|
||||
{
|
||||
return _integer;
|
||||
}
|
||||
|
||||
public bool Equals(SequencePosition other)
|
||||
{
|
||||
if (_integer == other._integer)
|
||||
{
|
||||
return object.Equals(_object, other._object);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is SequencePosition other)
|
||||
{
|
||||
return Equals(other);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashHelpers.Combine(_object?.GetHashCode() ?? 0, _integer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,398 @@
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System;
|
||||
|
||||
[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
|
||||
[DebuggerDisplay("{ToString(),raw}")]
|
||||
[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
|
||||
[DebuggerDisplay("{ToString(),raw}")]
|
||||
public readonly ref struct Span<T>
|
||||
{
|
||||
public ref struct Enumerator
|
||||
{
|
||||
private readonly Span<T> _span;
|
||||
|
||||
private int _index;
|
||||
|
||||
public ref T Current
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return ref _span[_index];
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal Enumerator(Span<T> span)
|
||||
{
|
||||
_span = span;
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool MoveNext()
|
||||
{
|
||||
int num = _index + 1;
|
||||
if (num < _span.Length)
|
||||
{
|
||||
_index = num;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Pinnable<T> _pinnable;
|
||||
|
||||
private readonly IntPtr _byteOffset;
|
||||
|
||||
private readonly int _length;
|
||||
|
||||
public int Length => _length;
|
||||
|
||||
public bool IsEmpty => _length == 0;
|
||||
|
||||
public static Span<T> Empty => default(Span<T>);
|
||||
|
||||
public unsafe ref T this[int index]
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
if ((uint)index >= (uint)_length)
|
||||
{
|
||||
System.ThrowHelper.ThrowIndexOutOfRangeException();
|
||||
}
|
||||
if (_pinnable == null)
|
||||
{
|
||||
IntPtr byteOffset = _byteOffset;
|
||||
return ref Unsafe.Add(ref Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
|
||||
}
|
||||
return ref Unsafe.Add(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset), index);
|
||||
}
|
||||
}
|
||||
|
||||
internal Pinnable<T> Pinnable => _pinnable;
|
||||
|
||||
internal IntPtr ByteOffset => _byteOffset;
|
||||
|
||||
public static bool operator !=(Span<T> left, Span<T> right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
[Obsolete("Equals() on Span will always throw an exception. Use == instead.")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
|
||||
}
|
||||
|
||||
[Obsolete("GetHashCode() on Span will always throw an exception.")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
|
||||
}
|
||||
|
||||
public static implicit operator Span<T>(T[] array)
|
||||
{
|
||||
return new Span<T>(array);
|
||||
}
|
||||
|
||||
public static implicit operator Span<T>(ArraySegment<T> segment)
|
||||
{
|
||||
return new Span<T>(segment.Array, segment.Offset, segment.Count);
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Span(T[] array)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
this = default(Span<T>);
|
||||
return;
|
||||
}
|
||||
if (default(T) == null && array.GetType() != typeof(T[]))
|
||||
{
|
||||
System.ThrowHelper.ThrowArrayTypeMismatchException();
|
||||
}
|
||||
_length = array.Length;
|
||||
_pinnable = Unsafe.As<Pinnable<T>>(array);
|
||||
_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static Span<T> Create(T[] array, int start)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
if (start != 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
return default(Span<T>);
|
||||
}
|
||||
if (default(T) == null && array.GetType() != typeof(T[]))
|
||||
{
|
||||
System.ThrowHelper.ThrowArrayTypeMismatchException();
|
||||
}
|
||||
if ((uint)start > (uint)array.Length)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
IntPtr byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
|
||||
int length = array.Length - start;
|
||||
return new Span<T>(Unsafe.As<Pinnable<T>>(array), byteOffset, length);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Span(T[] array, int start, int length)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
if (start != 0 || length != 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
this = default(Span<T>);
|
||||
return;
|
||||
}
|
||||
if (default(T) == null && array.GetType() != typeof(T[]))
|
||||
{
|
||||
System.ThrowHelper.ThrowArrayTypeMismatchException();
|
||||
}
|
||||
if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
_length = length;
|
||||
_pinnable = Unsafe.As<Pinnable<T>>(array);
|
||||
_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[CLSCompliant(false)]
|
||||
public unsafe Span(void* pointer, int length)
|
||||
{
|
||||
if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
|
||||
}
|
||||
if (length < 0)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
_length = length;
|
||||
_pinnable = null;
|
||||
_byteOffset = new IntPtr(pointer);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal Span(Pinnable<T> pinnable, IntPtr byteOffset, int length)
|
||||
{
|
||||
_length = length;
|
||||
_pinnable = pinnable;
|
||||
_byteOffset = byteOffset;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public unsafe ref T GetPinnableReference()
|
||||
{
|
||||
if (_length != 0)
|
||||
{
|
||||
if (_pinnable == null)
|
||||
{
|
||||
IntPtr byteOffset = _byteOffset;
|
||||
return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
|
||||
}
|
||||
return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
|
||||
}
|
||||
return ref Unsafe.AsRef<T>(null);
|
||||
}
|
||||
|
||||
public unsafe void Clear()
|
||||
{
|
||||
int length = _length;
|
||||
if (length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
UIntPtr byteLength = (UIntPtr)(ulong)((uint)length * Unsafe.SizeOf<T>());
|
||||
if ((Unsafe.SizeOf<T>() & (sizeof(IntPtr) - 1)) != 0)
|
||||
{
|
||||
if (_pinnable == null)
|
||||
{
|
||||
IntPtr byteOffset = _byteOffset;
|
||||
byte* ptr = (byte*)byteOffset.ToPointer();
|
||||
System.SpanHelpers.ClearLessThanPointerSized(ptr, byteLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.SpanHelpers.ClearLessThanPointerSized(ref Unsafe.As<T, byte>(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset)), byteLength);
|
||||
}
|
||||
}
|
||||
else if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
UIntPtr pointerSizeLength = (UIntPtr)(ulong)(length * Unsafe.SizeOf<T>() / sizeof(IntPtr));
|
||||
System.SpanHelpers.ClearPointerSizedWithReferences(ref Unsafe.As<T, IntPtr>(ref DangerousGetPinnableReference()), pointerSizeLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.SpanHelpers.ClearPointerSizedWithoutReferences(ref Unsafe.As<T, byte>(ref DangerousGetPinnableReference()), byteLength);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void Fill(T value)
|
||||
{
|
||||
int length = _length;
|
||||
if (length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (Unsafe.SizeOf<T>() == 1)
|
||||
{
|
||||
byte value2 = Unsafe.As<T, byte>(ref value);
|
||||
if (_pinnable == null)
|
||||
{
|
||||
IntPtr byteOffset = _byteOffset;
|
||||
Unsafe.InitBlockUnaligned(byteOffset.ToPointer(), value2, (uint)length);
|
||||
}
|
||||
else
|
||||
{
|
||||
Unsafe.InitBlockUnaligned(ref Unsafe.As<T, byte>(ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset)), value2, (uint)length);
|
||||
}
|
||||
return;
|
||||
}
|
||||
ref T source = ref DangerousGetPinnableReference();
|
||||
int i;
|
||||
for (i = 0; i < (length & -8); i += 8)
|
||||
{
|
||||
Unsafe.Add(ref source, i) = value;
|
||||
Unsafe.Add(ref source, i + 1) = value;
|
||||
Unsafe.Add(ref source, i + 2) = value;
|
||||
Unsafe.Add(ref source, i + 3) = value;
|
||||
Unsafe.Add(ref source, i + 4) = value;
|
||||
Unsafe.Add(ref source, i + 5) = value;
|
||||
Unsafe.Add(ref source, i + 6) = value;
|
||||
Unsafe.Add(ref source, i + 7) = value;
|
||||
}
|
||||
if (i < (length & -4))
|
||||
{
|
||||
Unsafe.Add(ref source, i) = value;
|
||||
Unsafe.Add(ref source, i + 1) = value;
|
||||
Unsafe.Add(ref source, i + 2) = value;
|
||||
Unsafe.Add(ref source, i + 3) = value;
|
||||
i += 4;
|
||||
}
|
||||
for (; i < length; i++)
|
||||
{
|
||||
Unsafe.Add(ref source, i) = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(Span<T> destination)
|
||||
{
|
||||
if (!TryCopyTo(destination))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryCopyTo(Span<T> destination)
|
||||
{
|
||||
int length = _length;
|
||||
int length2 = destination._length;
|
||||
if (length == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ((uint)length > (uint)length2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ref T src = ref DangerousGetPinnableReference();
|
||||
System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool operator ==(Span<T> left, Span<T> right)
|
||||
{
|
||||
if (left._length == right._length)
|
||||
{
|
||||
return Unsafe.AreSame(in left.DangerousGetPinnableReference(), in right.DangerousGetPinnableReference());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static implicit operator ReadOnlySpan<T>(Span<T> span)
|
||||
{
|
||||
return new ReadOnlySpan<T>(span._pinnable, span._byteOffset, span._length);
|
||||
}
|
||||
|
||||
public unsafe override string ToString()
|
||||
{
|
||||
if (typeof(T) == typeof(char))
|
||||
{
|
||||
fixed (char* value = &Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
|
||||
{
|
||||
return new string(value, 0, _length);
|
||||
}
|
||||
}
|
||||
return $"System.Span<{typeof(T).Name}>[{_length}]";
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Span<T> Slice(int start)
|
||||
{
|
||||
if ((uint)start > (uint)_length)
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
IntPtr byteOffset = _byteOffset.Add<T>(start);
|
||||
int length = _length - start;
|
||||
return new Span<T>(_pinnable, byteOffset, length);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Span<T> Slice(int start, int length)
|
||||
{
|
||||
if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
|
||||
{
|
||||
System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
IntPtr byteOffset = _byteOffset.Add<T>(start);
|
||||
return new Span<T>(_pinnable, byteOffset, length);
|
||||
}
|
||||
|
||||
public T[] ToArray()
|
||||
{
|
||||
if (_length == 0)
|
||||
{
|
||||
return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
|
||||
}
|
||||
T[] array = new T[_length];
|
||||
CopyTo(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
internal unsafe ref T DangerousGetPinnableReference()
|
||||
{
|
||||
if (_pinnable == null)
|
||||
{
|
||||
IntPtr byteOffset = _byteOffset;
|
||||
return ref Unsafe.AsRef<T>(byteOffset.ToPointer());
|
||||
}
|
||||
return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace System;
|
||||
|
||||
internal sealed class SpanDebugView<T>
|
||||
{
|
||||
private readonly T[] _array;
|
||||
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public T[] Items => _array;
|
||||
|
||||
public SpanDebugView(Span<T> span)
|
||||
{
|
||||
_array = span.ToArray();
|
||||
}
|
||||
|
||||
public SpanDebugView(ReadOnlySpan<T> span)
|
||||
{
|
||||
_array = span.ToArray();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,289 @@
|
||||
using System.Buffers;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System;
|
||||
|
||||
internal static class ThrowHelper
|
||||
{
|
||||
internal static void ThrowArgumentNullException(System.ExceptionArgument argument)
|
||||
{
|
||||
throw CreateArgumentNullException(argument);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateArgumentNullException(System.ExceptionArgument argument)
|
||||
{
|
||||
return new ArgumentNullException(argument.ToString());
|
||||
}
|
||||
|
||||
internal static void ThrowArrayTypeMismatchException()
|
||||
{
|
||||
throw CreateArrayTypeMismatchException();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateArrayTypeMismatchException()
|
||||
{
|
||||
return new ArrayTypeMismatchException();
|
||||
}
|
||||
|
||||
internal static void ThrowArgumentException_InvalidTypeWithPointersNotSupported(Type type)
|
||||
{
|
||||
throw CreateArgumentException_InvalidTypeWithPointersNotSupported(type);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateArgumentException_InvalidTypeWithPointersNotSupported(Type type)
|
||||
{
|
||||
return new ArgumentException(System.SR.Format(System.SR.Argument_InvalidTypeWithPointersNotSupported, type));
|
||||
}
|
||||
|
||||
internal static void ThrowArgumentException_DestinationTooShort()
|
||||
{
|
||||
throw CreateArgumentException_DestinationTooShort();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateArgumentException_DestinationTooShort()
|
||||
{
|
||||
return new ArgumentException(System.SR.Argument_DestinationTooShort);
|
||||
}
|
||||
|
||||
internal static void ThrowIndexOutOfRangeException()
|
||||
{
|
||||
throw CreateIndexOutOfRangeException();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateIndexOutOfRangeException()
|
||||
{
|
||||
return new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
internal static void ThrowArgumentOutOfRangeException()
|
||||
{
|
||||
throw CreateArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateArgumentOutOfRangeException()
|
||||
{
|
||||
return new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
internal static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument)
|
||||
{
|
||||
throw CreateArgumentOutOfRangeException(argument);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateArgumentOutOfRangeException(System.ExceptionArgument argument)
|
||||
{
|
||||
return new ArgumentOutOfRangeException(argument.ToString());
|
||||
}
|
||||
|
||||
internal static void ThrowArgumentOutOfRangeException_PrecisionTooLarge()
|
||||
{
|
||||
throw CreateArgumentOutOfRangeException_PrecisionTooLarge();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateArgumentOutOfRangeException_PrecisionTooLarge()
|
||||
{
|
||||
return new ArgumentOutOfRangeException("precision", System.SR.Format(System.SR.Argument_PrecisionTooLarge, (byte)99));
|
||||
}
|
||||
|
||||
internal static void ThrowArgumentOutOfRangeException_SymbolDoesNotFit()
|
||||
{
|
||||
throw CreateArgumentOutOfRangeException_SymbolDoesNotFit();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateArgumentOutOfRangeException_SymbolDoesNotFit()
|
||||
{
|
||||
return new ArgumentOutOfRangeException("symbol", System.SR.Argument_BadFormatSpecifier);
|
||||
}
|
||||
|
||||
internal static void ThrowInvalidOperationException()
|
||||
{
|
||||
throw CreateInvalidOperationException();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateInvalidOperationException()
|
||||
{
|
||||
return new InvalidOperationException();
|
||||
}
|
||||
|
||||
internal static void ThrowInvalidOperationException_OutstandingReferences()
|
||||
{
|
||||
throw CreateInvalidOperationException_OutstandingReferences();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateInvalidOperationException_OutstandingReferences()
|
||||
{
|
||||
return new InvalidOperationException(System.SR.OutstandingReferences);
|
||||
}
|
||||
|
||||
internal static void ThrowInvalidOperationException_UnexpectedSegmentType()
|
||||
{
|
||||
throw CreateInvalidOperationException_UnexpectedSegmentType();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateInvalidOperationException_UnexpectedSegmentType()
|
||||
{
|
||||
return new InvalidOperationException(System.SR.UnexpectedSegmentType);
|
||||
}
|
||||
|
||||
internal static void ThrowInvalidOperationException_EndPositionNotReached()
|
||||
{
|
||||
throw CreateInvalidOperationException_EndPositionNotReached();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateInvalidOperationException_EndPositionNotReached()
|
||||
{
|
||||
return new InvalidOperationException(System.SR.EndPositionNotReached);
|
||||
}
|
||||
|
||||
internal static void ThrowArgumentOutOfRangeException_PositionOutOfRange()
|
||||
{
|
||||
throw CreateArgumentOutOfRangeException_PositionOutOfRange();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateArgumentOutOfRangeException_PositionOutOfRange()
|
||||
{
|
||||
return new ArgumentOutOfRangeException("position");
|
||||
}
|
||||
|
||||
internal static void ThrowArgumentOutOfRangeException_OffsetOutOfRange()
|
||||
{
|
||||
throw CreateArgumentOutOfRangeException_OffsetOutOfRange();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateArgumentOutOfRangeException_OffsetOutOfRange()
|
||||
{
|
||||
return new ArgumentOutOfRangeException("offset");
|
||||
}
|
||||
|
||||
internal static void ThrowObjectDisposedException_ArrayMemoryPoolBuffer()
|
||||
{
|
||||
throw CreateObjectDisposedException_ArrayMemoryPoolBuffer();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateObjectDisposedException_ArrayMemoryPoolBuffer()
|
||||
{
|
||||
return new ObjectDisposedException("ArrayMemoryPoolBuffer");
|
||||
}
|
||||
|
||||
internal static void ThrowFormatException_BadFormatSpecifier()
|
||||
{
|
||||
throw CreateFormatException_BadFormatSpecifier();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateFormatException_BadFormatSpecifier()
|
||||
{
|
||||
return new FormatException(System.SR.Argument_BadFormatSpecifier);
|
||||
}
|
||||
|
||||
internal static void ThrowArgumentException_OverlapAlignmentMismatch()
|
||||
{
|
||||
throw CreateArgumentException_OverlapAlignmentMismatch();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateArgumentException_OverlapAlignmentMismatch()
|
||||
{
|
||||
return new ArgumentException(System.SR.Argument_OverlapAlignmentMismatch);
|
||||
}
|
||||
|
||||
internal static void ThrowNotSupportedException()
|
||||
{
|
||||
throw CreateThrowNotSupportedException();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static Exception CreateThrowNotSupportedException()
|
||||
{
|
||||
return new NotSupportedException();
|
||||
}
|
||||
|
||||
public static bool TryFormatThrowFormatException(out int bytesWritten)
|
||||
{
|
||||
bytesWritten = 0;
|
||||
ThrowFormatException_BadFormatSpecifier();
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryParseThrowFormatException<T>(out T value, out int bytesConsumed)
|
||||
{
|
||||
value = default(T);
|
||||
bytesConsumed = 0;
|
||||
ThrowFormatException_BadFormatSpecifier();
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void ThrowArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment)
|
||||
{
|
||||
throw CreateArgumentValidationException(startSegment, startIndex, endSegment);
|
||||
}
|
||||
|
||||
private static Exception CreateArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment)
|
||||
{
|
||||
if (startSegment == null)
|
||||
{
|
||||
return CreateArgumentNullException(System.ExceptionArgument.startSegment);
|
||||
}
|
||||
if (endSegment == null)
|
||||
{
|
||||
return CreateArgumentNullException(System.ExceptionArgument.endSegment);
|
||||
}
|
||||
if (startSegment != endSegment && startSegment.RunningIndex > endSegment.RunningIndex)
|
||||
{
|
||||
return CreateArgumentOutOfRangeException(System.ExceptionArgument.endSegment);
|
||||
}
|
||||
if ((uint)startSegment.Memory.Length < (uint)startIndex)
|
||||
{
|
||||
return CreateArgumentOutOfRangeException(System.ExceptionArgument.startIndex);
|
||||
}
|
||||
return CreateArgumentOutOfRangeException(System.ExceptionArgument.endIndex);
|
||||
}
|
||||
|
||||
public static void ThrowArgumentValidationException(Array array, int start)
|
||||
{
|
||||
throw CreateArgumentValidationException(array, start);
|
||||
}
|
||||
|
||||
private static Exception CreateArgumentValidationException(Array array, int start)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
return CreateArgumentNullException(System.ExceptionArgument.array);
|
||||
}
|
||||
if ((uint)start > (uint)array.Length)
|
||||
{
|
||||
return CreateArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
return CreateArgumentOutOfRangeException(System.ExceptionArgument.length);
|
||||
}
|
||||
|
||||
public static void ThrowStartOrEndArgumentValidationException(long start)
|
||||
{
|
||||
throw CreateStartOrEndArgumentValidationException(start);
|
||||
}
|
||||
|
||||
private static Exception CreateStartOrEndArgumentValidationException(long start)
|
||||
{
|
||||
if (start < 0)
|
||||
{
|
||||
return CreateArgumentOutOfRangeException(System.ExceptionArgument.start);
|
||||
}
|
||||
return CreateArgumentOutOfRangeException(System.ExceptionArgument.length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<AssemblyName>System.Memory</AssemblyName>
|
||||
<GenerateAssemblyInfo>False</GenerateAssemblyInfo>
|
||||
<TargetFramework>net40</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<LangVersion>14.0</LangVersion>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RootNamespace />
|
||||
</PropertyGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Numerics.Vectors" />
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe" />
|
||||
<Reference Include="System.Buffers" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user