SpanReader<T>
Represents simple memory reader backed by ReadOnlySpan<T>.
using System;
using System.Diagnostics.CodeAnalysis;
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 SpanReader<[System.Runtime.CompilerServices.Nullable(2)] T>
{
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
private readonly ReadOnlySpan<T> span;
private int position;
[IsReadOnly]
public ref T Current {
[IsReadOnly]
[return: IsReadOnly]
get {
if (position >= span.Length)
throw new InvalidOperationException();
return ref Unsafe.Add<T>(ref MemoryMarshal.GetReference<T>(span), position);
}
}
public int ConsumedCount {
[IsReadOnly]
get {
return position;
}
}
public int RemainingCount {
[IsReadOnly]
get {
return span.Length - position;
}
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public ReadOnlySpan<T> Span {
[IsReadOnly]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
get {
return span;
}
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public ReadOnlySpan<T> ConsumedSpan {
[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 ReadOnlySpan<T> RemainingSpan {
[IsReadOnly]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
get {
return span.Slice(position);
}
}
public SpanReader([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ReadOnlySpan<T> span)
{
this.span = span;
position = 0;
}
public SpanReader(ref T reference, int length)
{
if (Unsafe.IsNullRef<T>(ref reference))
throw new ArgumentNullException("reference");
span = MemoryMarshal.CreateReadOnlySpan<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 TryRead([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] Span<T> output)
{
if (TryRead(output.Length, out ReadOnlySpan<T> result))
return result.TryCopyTo(output);
return false;
}
public bool TryRead(int count, [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] out ReadOnlySpan<T> result)
{
if (count < 0)
throw new ArgumentOutOfRangeException("count");
int num = checked(position + count);
if (num <= span.Length) {
result = span.Slice(position, count);
position = num;
return true;
}
result = default(ReadOnlySpan<T>);
return false;
}
public bool TryRead([MaybeNullWhen(false)] out T result)
{
int num = checked(position + 1);
if (num <= span.Length) {
result = Unsafe.Add<T>(ref MemoryMarshal.GetReference<T>(span), position);
position = num;
return true;
}
result = default(T);
return false;
}
public int Read([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] Span<T> output)
{
DotNext.Span.CopyTo<T>(RemainingSpan, output, out int writtenCount);
position += writtenCount;
return writtenCount;
}
public T Read()
{
if (!TryRead(out T result))
throw new InternalBufferOverflowException();
return result;
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public ReadOnlySpan<T> Read(int count)
{
if (!TryRead(count, out ReadOnlySpan<T> result))
throw new InternalBufferOverflowException();
return result;
}
[CLSCompliant(false)]
public unsafe TResult Read<[System.Runtime.CompilerServices.Nullable(2)] TResult>([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
0,
1
})] IntPtr reader, int count)
{
if (reader == (IntPtr)(void*)null)
throw new ArgumentNullException("reader");
if (!this.TryRead(count, out ReadOnlySpan<T> result))
throw new InternalBufferOverflowException();
return (TResult);
}
[CLSCompliant(false)]
public unsafe bool TryRead<[System.Runtime.CompilerServices.Nullable(2)] TResult>([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
0,
1
})] IntPtr reader, int count, [MaybeNullWhen(false)] out TResult result)
{
if (reader == (IntPtr)(void*)null)
throw new ArgumentNullException("reader");
if (this.TryRead(count, out ReadOnlySpan<T> result2)) {
result = (TResult);
return true;
}
result = default(TResult);
return false;
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public ReadOnlySpan<T> ReadToEnd()
{
ReadOnlySpan<T> remainingSpan = RemainingSpan;
position = span.Length;
return remainingSpan;
}
[IsReadOnly]
public override string ToString()
{
return ConsumedSpan.ToString();
}
}
}