ReadOnlyMemory<T>
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 & 2147483647;
public bool IsEmpty => (_length & 2147483647) == 0;
public ReadOnlySpan<T> Span {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get {
if (_index < 0)
return ((MemoryManager<T>)_object).GetSpan().Slice(_index & 2147483647, _length);
string text;
ReadOnlySpan<T> result;
if (typeof(T) == typeof(char) && (text = (_object as string)) != null) {
result = new ReadOnlySpan<T>(Unsafe.As<Pinnable<T>>((object)text), MemoryExtensions.StringAdjustment, text.Length);
return result.Slice(_index, _length);
}
if (_object != null)
return new ReadOnlySpan<T>((T[])_object, _index, _length & 2147483647);
result = default(ReadOnlySpan<T>);
return result;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlyMemory(T[] array)
{
if (array == null)
this = default(ReadOnlyMemory<T>);
else {
_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>);
} else {
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)) {
string text;
if ((text = (_object as string)) == null)
return Span.ToString();
return text.Substring(_index, _length & 2147483647);
}
return $"""{typeof(T).Name}""{_length & 2147483647}""";
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlyMemory<T> Slice(int start)
{
int length = _length;
int num = length & 2147483647;
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 & 2147483647;
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 & -2147483648));
}
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 & 2147483647);
string value;
if (typeof(T) == typeof(char) && (value = (_object as string)) != null) {
GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
void* pointer = Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
return new MemoryHandle(pointer, handle, null);
}
T[] array;
if ((array = (_object as T[])) != null) {
if (_length < 0) {
void* pointer2 = Unsafe.Add<T>(Unsafe.AsPointer<T>(ref MemoryMarshal.GetReference<T>((Span<T>)array)), _index);
return new MemoryHandle(pointer2, default(GCHandle), null);
}
GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
void* pointer3 = Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
return new MemoryHandle(pointer3, handle2, null);
}
return default(MemoryHandle);
}
public T[] ToArray()
{
return Span.ToArray();
}
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj)
{
object obj2;
if ((obj2 = obj) is ReadOnlyMemory<T>) {
ReadOnlyMemory<T> other = (ReadOnlyMemory<T>)obj2;
return Equals(other);
}
if ((obj2 = obj) is Memory<T>) {
Memory<T> memory = (Memory<T>)obj2;
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 num = _index;
int hashCode2 = num.GetHashCode();
num = _length;
return CombineHashCodes(hashCode, hashCode2, num.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;
}
}
}