BufferWriter<T>
public abstract class BufferWriter<T> : Disposable, IBufferWriter<T>, ISupplier<ReadOnlyMemory<T>>, IReadOnlyList<T>, IEnumerable<T>, IEnumerable, IReadOnlyCollection<T>, IGrowableBuffer<T>, IReadOnlySpanConsumer<T>, ISupplier<ReadOnlyMemory<T>, CancellationToken, ValueTask>, IDisposable
Represents memory-backed output sink which T data can be written.
using DotNext.Collections.Generic;
using System;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace DotNext.Buffers
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
[DebuggerDisplay("WrittenCount = {WrittenCount}, FreeCapacity = {FreeCapacity}")]
public abstract class BufferWriter<[System.Runtime.CompilerServices.Nullable(2)] T> : Disposable, IBufferWriter<T>, ISupplier<ReadOnlyMemory<T>>, IReadOnlyList<T>, IEnumerable<T>, IEnumerable, IReadOnlyCollection<T>, IGrowableBuffer<T>, IReadOnlySpanConsumer<T>, ISupplier<ReadOnlyMemory<T>, CancellationToken, ValueTask>, IDisposable
{
[System.Runtime.CompilerServices.Nullable(2)]
private object diagObj;
private protected int position;
[System.Runtime.CompilerServices.Nullable(2)]
public EventCounter AllocationCounter {
[System.Runtime.CompilerServices.NullableContext(2)]
private protected get {
return diagObj as EventCounter;
}
[System.Runtime.CompilerServices.NullableContext(2)]
[param: DisallowNull]
set {
diagObj = value;
}
}
[System.Runtime.CompilerServices.Nullable(2)]
public Action<int> BufferSizeCallback {
[System.Runtime.CompilerServices.NullableContext(2)]
private protected get {
return diagObj as Action<int>;
}
[System.Runtime.CompilerServices.NullableContext(2)]
[param: DisallowNull]
set {
diagObj = value;
}
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public abstract ReadOnlyMemory<T> WrittenMemory {
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
get;
}
public int WrittenCount {
get {
ThrowIfDisposed();
return position;
}
}
long IGrowableBuffer<T>.WrittenCount {
get {
return WrittenCount;
}
}
int IReadOnlyCollection<T>.Count {
get {
return WrittenCount;
}
}
[IsReadOnly]
public ref T this[int index] {
[return: IsReadOnly]
get {
return ref WrittenMemory.Span[index];
}
}
T IReadOnlyList<T>.this[int index] {
get {
return this[index];
}
}
public abstract int Capacity { get; }
public int FreeCapacity {
get {
ThrowIfDisposed();
return Capacity - WrittenCount;
}
}
private protected BufferWriter()
{
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
ReadOnlyMemory<T> ISupplier<ReadOnlyMemory<T>>.Invoke()
{
return WrittenMemory;
}
void IGrowableBuffer<T>.Write([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ReadOnlySpan<T> input)
{
BuffersExtensions.Write<T>((IBufferWriter<T>)this, input);
}
void IGrowableBuffer<T>.CopyTo<TConsumer>(TConsumer consumer)
{
((IReadOnlySpanConsumer<T>)consumer).Invoke(this.WrittenMemory.Span);
}
void IGrowableBuffer<T>.Clear()
{
Clear(false);
}
int IGrowableBuffer<T>.CopyTo([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] Span<T> output)
{
Span.CopyTo<T>(WrittenMemory.Span, output, out int writtenCount);
return writtenCount;
}
ValueTask IGrowableBuffer<T>.CopyToAsync<TConsumer>(TConsumer consumer, CancellationToken token)
{
if (!base.IsDisposed)
return ((ISupplier<ReadOnlyMemory<T>, CancellationToken, ValueTask>)consumer).Invoke(this.WrittenMemory, token);
return new ValueTask(base.DisposedTask);
}
public void Add(T item)
{
GetSpan(1)[0] = item;
Advance(1);
}
public void AddAll(ICollection<T> items)
{
if (items.Count != 0) {
Span<T> span = GetSpan(items.Count);
int i = default(int);
using (IEnumerator<T> enumerator = items.GetEnumerator()) {
for (i = 0; i < items.Count; i++) {
if (!enumerator.MoveNext())
break;
span[i] = enumerator.Current;
}
}
Advance(i);
}
}
public abstract void Clear(bool reuseBuffer = false);
public void Advance(int count)
{
ThrowIfDisposed();
if (count < 0)
throw new ArgumentOutOfRangeException("count");
if (position > Capacity - count)
throw new InvalidOperationException();
position += count;
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public abstract Memory<T> GetMemory(int sizeHint = 0);
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public virtual Span<T> GetSpan(int sizeHint = 0)
{
return GetMemory(sizeHint).Span;
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public abstract MemoryOwner<T> DetachBuffer();
private protected abstract void Resize(int newSize);
private protected void CheckAndResizeBuffer(int sizeHint)
{
int capacity = Capacity;
int writtenCount = position;
int? bufferSize = ((IGrowableBuffer<T>)).GetBufferSize(sizeHint, capacity, writtenCount);
if (bufferSize.HasValue)
Resize(bufferSize.GetValueOrDefault());
}
protected override void Dispose(bool disposing)
{
if (disposing)
diagObj = null;
base.Dispose(disposing);
}
public IEnumerator<T> GetEnumerator()
{
return Sequence.ToEnumerator<T>(WrittenMemory);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public override string ToString()
{
return WrittenMemory.ToString();
}
}
}