SpanWriter<T>
Represents simple memory writer backed by Span<T>.
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace DotNext.Buffers
{
[StructLayout(LayoutKind.Auto)]
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public ref struct SpanWriter<[System.Runtime.CompilerServices.Nullable(2)] T>
{
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
private readonly Span<T> span;
private int position;
public ref T Current {
[IsReadOnly]
get {
if (position >= span.Length)
throw new InvalidOperationException();
return ref Unsafe.Add<T>(ref MemoryMarshal.GetReference<T>(span), position);
}
}
public int FreeCapacity {
[IsReadOnly]
get {
return span.Length - position;
}
}
public int WrittenCount {
[IsReadOnly]
get {
return position;
}
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public Span<T> RemainingSpan {
[IsReadOnly]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
get {
return span.Slice(position);
}
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public Span<T> WrittenSpan {
[IsReadOnly]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
get {
return span.Slice(0, position);
}
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public Span<T> Span {
[IsReadOnly]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
get {
return span;
}
}
public SpanWriter([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] Span<T> span)
{
this.span = span;
position = 0;
}
public SpanWriter(ref T reference, int length)
{
if (Unsafe.IsNullRef<T>(ref reference))
throw new ArgumentNullException("reference");
span = MemoryMarshal.CreateSpan<T>(ref reference, length);
position = 0;
}
public void Advance(int count)
{
int num = checked(position + count);
if (num > span.Length)
throw new ArgumentOutOfRangeException("count");
position = num;
}
public void Rewind(int count)
{
if (count < 0 || count > position)
throw new ArgumentOutOfRangeException("count");
position -= count;
}
public void Reset()
{
position = 0;
}
public bool TryWrite([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ReadOnlySpan<T> input)
{
if (!input.TryCopyTo(span.Slice(position)))
return false;
position += input.Length;
return true;
}
public int Write([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ReadOnlySpan<T> input)
{
DotNext.Span.CopyTo<T>(input, RemainingSpan, out int writtenCount);
position += writtenCount;
return writtenCount;
}
public bool TryAdd(T item)
{
int num = checked(position + 1);
if (num > span.Length)
return false;
Unsafe.Add<T>(ref MemoryMarshal.GetReference<T>(span), position) = item;
position = num;
return true;
}
public void Add(T item)
{
if (!TryAdd(item))
throw new EndOfStreamException(ExceptionMessages.NotEnoughMemory);
}
public bool TrySlide(int count, [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] out Span<T> segment)
{
if (count < 0)
throw new ArgumentOutOfRangeException("count");
int num = checked(position + count);
if (num <= span.Length) {
segment = span.Slice(position, count);
position = num;
return true;
}
segment = default(Span<T>);
return false;
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public Span<T> Slide(int count)
{
if (!TrySlide(count, out Span<T> segment))
throw new EndOfStreamException(ExceptionMessages.NotEnoughMemory);
return segment;
}
[CLSCompliant(false)]
public unsafe void Write<[System.Runtime.CompilerServices.Nullable(2)] TArg>([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
0,
1,
1
})] IntPtr action, TArg arg, int count)
{
if (action == (IntPtr)(void*)null)
throw new ArgumentNullException("action");
if (!this.TrySlide(count, out Span<T> segment))
throw new EndOfStreamException(ExceptionMessages.NotEnoughMemory);
;
}
[CLSCompliant(false)]
public unsafe bool TryWrite<[System.Runtime.CompilerServices.Nullable(2)] TArg>([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
0,
1
})] IntPtr action, TArg arg)
{
if (action == (IntPtr)(void*)null)
throw new ArgumentNullException("action");
int num2 = (int);
if (num2 != 0) {
int num = default(int);
this.position += num;
}
return (byte)num2 != 0;
}
[IsReadOnly]
public override string ToString()
{
return WrittenSpan.ToString();
}
}
}