BufferScope<T>
Allows renting a buffer from ArrayPool<T> with a using statement. Can be used directly as if it
were a Span<T>.
using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace System
{
[NullableContext(1)]
[Nullable(0)]
[CompilerFeatureRequired("RefStructs")]
internal ref struct BufferScope<[Nullable(2)] T>
{
[Nullable(new byte[] {
2,
1
})]
private T[] _array;
[Nullable(new byte[] {
0,
1
})]
private Span<T> _span;
public ref T this[int i] {
get {
return ref _span[i];
}
}
[Nullable(new byte[] {
0,
1
})]
public Span<T> this[Range range] {
[IsReadOnly]
[return: Nullable(new byte[] {
0,
1
})]
get {
Span<T> span = _span;
Range range2 = range;
int length = span.Length;
Index index = range2.Start;
int offset = index.GetOffset(length);
index = range2.End;
int length2 = index.GetOffset(length) - offset;
return span.Slice(offset, length2);
}
}
public int Length {
[IsReadOnly]
get {
return _span.Length;
}
}
public BufferScope(int minimumLength)
{
_array = ArrayPool<T>.Shared.Rent(minimumLength);
_span = _array;
}
public BufferScope([Nullable(new byte[] {
0,
1
})] Span<T> initialBuffer)
{
_array = null;
_span = initialBuffer;
}
public BufferScope([Nullable(new byte[] {
0,
1
})] Span<T> initialBuffer, int minimumLength)
{
if (initialBuffer.Length >= minimumLength) {
_array = null;
_span = initialBuffer;
} else {
_array = ArrayPool<T>.Shared.Rent(minimumLength);
_span = _array;
}
}
public void EnsureCapacity(int capacity, bool copy = false)
{
if (_span.Length < capacity) {
T[] array = ArrayPool<T>.Shared.Rent(capacity);
if (copy)
_span.CopyTo(array);
if (_array != null)
ArrayPool<T>.Shared.Return(_array, false);
_array = array;
_span = _array;
}
}
[IsReadOnly]
[return: Nullable(new byte[] {
0,
1
})]
public Span<T> Slice(int start, int length)
{
return _span.Slice(start, length);
}
[IsReadOnly]
public ref T GetPinnableReference()
{
return ref MemoryMarshal.GetReference<T>(_span);
}
[IsReadOnly]
[return: Nullable(new byte[] {
0,
1
})]
public Span<T> AsSpan()
{
return _span;
}
public static implicit operator Span<T>([Nullable(new byte[] {
0,
1
})] BufferScope<T> scope)
{
return scope._span;
}
public static implicit operator ReadOnlySpan<T>([Nullable(new byte[] {
0,
1
})] BufferScope<T> scope)
{
return scope._span;
}
public void Dispose()
{
if (_array != null)
ArrayPool<T>.Shared.Return(_array, false);
_array = null;
}
[IsReadOnly]
public override string ToString()
{
return _span.ToString();
}
}
}