DotNext by .NET Foundation and Contributors

<PackageReference Include="DotNext" Version="5.16.1" />

.NET API 532,936 bytes

 PoolingArrayBufferWriter<T>

Represents memory writer that is backed by the array obtained from the pool.
using DotNext.Runtime; using DotNext.Runtime.CompilerServices; using System; using System.Buffers; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace DotNext.Buffers { [NullableContext(1)] [Nullable(new byte[] { 0, 1 })] public sealed class PoolingArrayBufferWriter<[Nullable(2)] T> : BufferWriter<T>, ISupplier<ArraySegment<T>>, IFunctional<Func<ArraySegment<T>>>, IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable { private readonly ArrayPool<T> pool = pool ?? ArrayPool<T>.Shared; private T[] buffer = Array.Empty<T>(); int ICollection<T>.Count { get { return base.WrittenCount; } } bool ICollection<T>.IsReadOnly { get { return false; } } public new ref T this[int index] { get { ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, (uint)position, "index"); return ref Unsafe.Add<T>(ref MemoryMarshal.GetArrayDataReference<T>(buffer), index); } } T IList<T>.this[int index] { get { return this[index]; } set { this[index] = value; } } public override int Capacity { get { return buffer.Length; } set { if (value < 0) throw new ArgumentOutOfRangeException("value"); if (value > 0) buffer = pool.Rent(value); } } [Nullable(new byte[] { 0, 1 })] public override ReadOnlyMemory<T> WrittenMemory { [return: Nullable(new byte[] { 0, 1 })] get { ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); return new ReadOnlyMemory<T>(buffer, 0, position); } } [Nullable(new byte[] { 0, 1 })] public ArraySegment<T> WrittenArray { [return: Nullable(new byte[] { 0, 1 })] get { ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); return new ArraySegment<T>(buffer, 0, position); } } public PoolingArrayBufferWriter([Nullable(new byte[] { 2, 1 })] ArrayPool<T> pool = null) { } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { MemoryMarshal.CreateReadOnlySpan<T>(ref MemoryMarshal.GetArrayDataReference<T>(buffer), position).CopyTo(MemoryExtensions.AsSpan<T>(array, arrayIndex)); } int IList<T>.IndexOf(T item) { ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); return Array.IndexOf<T>(buffer, item, 0, position); } bool ICollection<T>.Contains(T item) { ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); return Array.IndexOf<T>(buffer, item, 0, position) >= 0; } private void RemoveAt(int index) { CopyFast(buffer, index + 1, buffer, index, position - index - 1); if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) buffer[position - 1] = default(T); if (--position == 0) { ReturnBuffer(); buffer = Array.Empty<T>(); } } void IList<T>.RemoveAt(int index) { ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, (uint)position, "index"); RemoveAt(index); } bool ICollection<T>.Remove(T item) { ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); int num = Array.IndexOf<T>(buffer, item, 0, position); if (num < 0) return false; RemoveAt(num); return true; } void IList<T>.Insert(int index, T item) { Insert(index, new ReadOnlySpan<T>(ref item)); } public unsafe void Insert(int index, [Nullable(new byte[] { 0, 1 })] ReadOnlySpan<T> items) { ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); ArgumentOutOfRangeException.ThrowIfGreaterThan<uint>((uint)index, (uint)position, "index"); if (!items.IsEmpty) { if (buffer.GetLength() == (UIntPtr)(void*)null) buffer = pool.Rent(items.Length); else if ((ulong)(uint)(position + items.Length) <= (ulong)buffer.GetLength()) { CopyFast(buffer, index, buffer, index + items.Length, position - index); } else { T[] destination = pool.Rent(buffer.Length + items.Length); CopyFast(buffer, destination, index); CopyFast(buffer, index, destination, index + items.Length, buffer.Length - index); ReturnBuffer(); buffer = destination; } items.CopyTo(MemoryExtensions.AsSpan<T>(buffer, index)); position += items.Length; } } public unsafe void Overwrite(int index, [Nullable(new byte[] { 0, 1 })] ReadOnlySpan<T> items) { ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); ArgumentOutOfRangeException.ThrowIfGreaterThan<uint>((uint)index, (uint)position, "index"); if (buffer.GetLength() == (UIntPtr)(void*)null) buffer = pool.Rent(items.Length); else if ((ulong)(uint)(index + items.Length) <= (ulong)buffer.GetLength()) { if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) Array.Clear(buffer, index, position - index); } else { T[] destination = pool.Rent(index + items.Length); CopyFast(buffer, destination, index); ReturnBuffer(); buffer = destination; } items.CopyTo(MemoryExtensions.AsSpan<T>(buffer, index)); position = index + items.Length; } void ICollection<T>.Clear() { Clear(false); } ArraySegment<T> ISupplier<ArraySegment<T>>.Invoke() { return WrittenArray; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ReturnBuffer() { pool.Return(buffer, RuntimeHelpers.IsReferenceOrContainsReferences<T>()); } public unsafe override void Clear(bool reuseBuffer = false) { ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); if (buffer.GetLength() != (UIntPtr)(void*)null) { if (!reuseBuffer) { ReturnBuffer(); buffer = Array.Empty<T>(); } else if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) { Array.Clear(buffer, 0, position); } } position = 0; } [return: Nullable(new byte[] { 0, 1 })] public override MemoryOwner<T> DetachBuffer() { ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); MemoryOwner<T> result; if (position > 0) { result = new MemoryOwner<T>(pool, buffer, position); buffer = Array.Empty<T>(); position = 0; } else result = default(MemoryOwner<T>); return result; } private T[] GetRawArray(int sizeHint) { ArgumentOutOfRangeException.ThrowIfNegative<int>(sizeHint, "sizeHint"); ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); CheckAndResizeBuffer(sizeHint); return buffer; } [return: Nullable(new byte[] { 0, 1 })] public override Memory<T> GetMemory(int sizeHint = 0) { return MemoryExtensions.AsMemory<T>(GetRawArray(sizeHint), position); } [return: Nullable(new byte[] { 0, 1 })] public override Span<T> GetSpan(int sizeHint = 0) { T[] rawArray = GetRawArray(sizeHint); return MemoryMarshal.CreateSpan<T>(ref Unsafe.Add<T>(ref MemoryMarshal.GetArrayDataReference<T>(rawArray), position), rawArray.Length - position); } [return: Nullable(new byte[] { 0, 1 })] public ArraySegment<T> GetArray(int sizeHint = 0) { return new ArraySegment<T>(GetRawArray(sizeHint), position, base.FreeCapacity); } public override void AddAll(ICollection<T> items) { ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); int count = items.Count; if (count > 0) { CheckAndResizeBuffer(count); items.CopyTo(buffer, position); position += count; } } public unsafe void RemoveLast(int count) { ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); ArgumentOutOfRangeException.ThrowIfNegative<int>(count, "count"); if (buffer.GetLength() != (UIntPtr)(void*)null) { if (count >= position) { ReturnBuffer(); buffer = Array.Empty<T>(); position = 0; } else if (count > 0) { int num = position - count; if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) Array.Clear(buffer, num, position - num); position = num; } } } public unsafe void RemoveFirst(int count) { ObjectDisposedException.ThrowIf(base.IsDisposed, (object)this); ArgumentOutOfRangeException.ThrowIfNegative<int>(count, "count"); if (buffer.GetLength() != (UIntPtr)(void*)null) { if (count >= position) { ReturnBuffer(); buffer = Array.Empty<T>(); position = 0; } else if (count > 0) { int num = position - count; T[] destinationArray = pool.Rent(num); Array.Copy(buffer, count, destinationArray, 0, num); ReturnBuffer(); buffer = destinationArray; position = num; } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void CopyFast(T[] source, T[] destination, int length) { ReadOnlySpan<T> readOnlySpan = MemoryMarshal.CreateReadOnlySpan<T>(ref MemoryMarshal.GetArrayDataReference<T>(source), length); Span<T> destination2 = MemoryMarshal.CreateSpan<T>(ref MemoryMarshal.GetArrayDataReference<T>(destination), length); readOnlySpan.CopyTo(destination2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void CopyFast(T[] source, int sourceIndex, T[] destination, int destinationIndex, int length) { ReadOnlySpan<T> readOnlySpan = MemoryMarshal.CreateReadOnlySpan<T>(ref Unsafe.Add<T>(ref MemoryMarshal.GetArrayDataReference<T>(source), sourceIndex), length); Span<T> destination2 = MemoryMarshal.CreateSpan<T>(ref Unsafe.Add<T>(ref MemoryMarshal.GetArrayDataReference<T>(destination), destinationIndex), length); readOnlySpan.CopyTo(destination2); } private protected unsafe override void Resize(int newSize) { T[] array = pool.Rent(newSize); if (buffer.GetLength() != (UIntPtr)(void*)null) { CopyFast(buffer, array, position); ReturnBuffer(); } buffer = array; <PoolingArrayBufferWriter>FDA5BBF4E667473AEB3E690976E04ABB18D2410DFFD7065711E010FA78152906B__PoolingArrayBufferWriter.AllocationMeter.Record(array.LongLength, ref measurementTags); } protected unsafe override void Dispose(bool disposing) { if (disposing && buffer.GetLength() != (UIntPtr)(void*)null) { ReturnBuffer(); buffer = Array.Empty<T>(); } base.Dispose(disposing); } } }