SpanWriter<T>
Represents simple memory writer backed by Span<T>.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace DotNext.Buffers
{
[StructLayout(LayoutKind.Auto)]
[NullableContext(1)]
[Nullable(0)]
[CompilerFeatureRequired("RefStructs")]
public ref struct SpanWriter<[Nullable(2)] T>
{
private readonly ref T reference;
private readonly int length;
private int position;
public unsafe ref T Current {
[IsReadOnly]
get {
if ((uint)position >= (uint)length)
<get_Current>g__ThrowInvalidOperationException|6_0();
return ref Unsafe.Add<T>(*(ref T*)(&reference), position);
}
}
public int FreeCapacity {
[IsReadOnly]
get {
return length - position;
}
}
public int WrittenCount {
[IsReadOnly]
get {
return position;
}
set {
ArgumentOutOfRangeException.ThrowIfGreaterThan<uint>((uint)value, (uint)length, "value");
position = value;
}
}
[Nullable(new byte[] {
0,
1
})]
public unsafe Span<T> RemainingSpan {
[IsReadOnly]
[return: Nullable(new byte[] {
0,
1
})]
get {
return MemoryMarshal.CreateSpan<T>(ref Unsafe.Add<T>(*(ref T*)(&reference), position), FreeCapacity);
}
}
[Nullable(new byte[] {
0,
1
})]
public unsafe Span<T> WrittenSpan {
[IsReadOnly]
[return: Nullable(new byte[] {
0,
1
})]
get {
return MemoryMarshal.CreateSpan<T>(*(ref T*)(&reference), position);
}
}
[Nullable(new byte[] {
0,
1
})]
public unsafe Span<T> Span {
[IsReadOnly]
[return: Nullable(new byte[] {
0,
1
})]
get {
return MemoryMarshal.CreateSpan<T>(*(ref T*)(&reference), length);
}
}
public unsafe SpanWriter([Nullable(new byte[] {
0,
1
})] Span<T> span)
{
position = 0;
*(ref T*)(&reference) = ref MemoryMarshal.GetReference<T>(span);
length = span.Length;
}
public unsafe SpanWriter(ref T reference, int length)
{
position = 0;
if (length < 0)
throw new ArgumentOutOfRangeException("length");
if (length > 0 && Unsafe.IsNullRef<T>(ref reference))
throw new ArgumentNullException("reference");
*(ref T*)(&this.reference) = ref reference;
this.length = length;
}
public void Advance(int count)
{
ArgumentOutOfRangeException.ThrowIfGreaterThan<uint>((uint)count, (uint)FreeCapacity, "count");
position += count;
}
public void Rewind(int count)
{
ArgumentOutOfRangeException.ThrowIfGreaterThan<uint>((uint)count, (uint)position, "count");
position -= count;
}
public void Reset()
{
position = 0;
}
public bool TryWrite([ScopedRef] [Nullable(new byte[] {
0,
1
})] ReadOnlySpan<T> input)
{
if (!input.TryCopyTo(RemainingSpan))
return false;
position += input.Length;
return true;
}
public int Write([ScopedRef] [Nullable(new byte[] {
0,
1
})] ReadOnlySpan<T> input)
{
DotNext.Span.CopyTo<T>(input, RemainingSpan, out int writtenCount);
position += writtenCount;
return writtenCount;
}
public unsafe bool TryAdd(T item)
{
if ((uint)position < (uint)length) {
Unsafe.Add<T>(*(ref T*)(&reference), position++) = item;
return true;
}
return false;
}
public void Add(T item)
{
Add() = item;
}
public unsafe ref T Add()
{
if ((uint)position >= (uint)length)
<Add>g__ThrowInternalBufferOverflowException|25_0();
return ref Unsafe.Add<T>(*(ref T*)(&reference), position++);
}
public unsafe bool TrySlide(int count, [Nullable(new byte[] {
0,
1
})] out Span<T> segment)
{
ArgumentOutOfRangeException.ThrowIfNegative<int>(count, "count");
int num = position + count;
if ((uint)num <= (uint)length) {
segment = MemoryMarshal.CreateSpan<T>(ref Unsafe.Add<T>(*(ref T*)(&reference), position), count);
position = num;
return true;
}
segment = default(Span<T>);
return false;
}
[return: Nullable(new byte[] {
0,
1
})]
public unsafe Span<T> Slide(int count)
{
ArgumentOutOfRangeException.ThrowIfNegative<int>(count, "count");
int num = position + count;
ArgumentOutOfRangeException.ThrowIfGreaterThan<uint>((uint)num, (uint)length, "count");
Span<T> result = MemoryMarshal.CreateSpan<T>(ref Unsafe.Add<T>(*(ref T*)(&reference), position), count);
position = num;
return result;
}
[return: Nullable(new byte[] {
0,
1
})]
public Span<T> SlideToEnd()
{
Span<T> remainingSpan = RemainingSpan;
position = length;
return remainingSpan;
}
[CLSCompliant(false)]
public unsafe void Write<[Nullable(2)] TArg>([Nullable(new byte[] {
0,
1,
0,
1
})] IntPtr action, TArg arg, int count)
{
ArgumentNullException.ThrowIfNull((void*)(long)action, "action");
ArgumentOutOfRangeException.ThrowIfNegative<int>(count, "count");
int num = this.position + count;
ArgumentOutOfRangeException.ThrowIfGreaterThan<uint>((uint)num, (uint)this.length, "count");
Span<T> span = MemoryMarshal.CreateSpan<T>(ref Unsafe.Add<T>(*(ref T*)(&this.reference), this.position), count);
;
this.position = num;
}
[CLSCompliant(false)]
public unsafe bool TryWrite<[Nullable(2)] TArg>([Nullable(new byte[] {
0,
1,
0,
1
})] IntPtr action, TArg arg)
{
ArgumentNullException.ThrowIfNull((void*)(long)action, "action");
if ((int) == 0)
return false;
int num = default(int);
this.position += num;
return true;
}
[IsReadOnly]
public override string ToString()
{
return WrittenSpan.ToString();
}
}
}