SpanWriter<T>
struct SpanWriter<T> where T : ValueType modreq(System.Runtime.InteropServices.UnmanagedType), IEquatable<T>
Fast stack based Span<T> writer.
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace System
{
[CompilerFeatureRequired("RefStructs")]
internal ref struct SpanWriter<[IsUnmanaged] T> where T : struct, IEquatable<T>
{
private Span<T> _unwritten;
public Span<T> Span {
[IsReadOnly]
get;
}
public int Position {
[IsReadOnly]
get {
return Span.Length - _unwritten.Length;
}
set {
Span<T> span = Span;
_unwritten = span.Slice(value, span.Length - value);
}
}
public int Length {
[IsReadOnly]
get {
return Span.Length;
}
}
public SpanWriter(Span<T> span)
{
_unwritten = span;
Span = span;
}
public bool TryWrite(T value)
{
bool result = false;
if (!_unwritten.IsEmpty) {
result = true;
_unwritten[0] = value;
UnsafeAdvance(1);
}
return result;
}
public bool TryWrite([ParamCollection] [ScopedRef] ReadOnlySpan<T> values)
{
bool result = false;
if (_unwritten.Length >= values.Length) {
result = true;
values.CopyTo(_unwritten);
UnsafeAdvance(values.Length);
}
return result;
}
public bool TryWriteCount(int count, T value)
{
bool result = false;
if (_unwritten.Length >= count) {
result = true;
_unwritten.Slice(0, count).Fill(value);
UnsafeAdvance(count);
}
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Advance(int count)
{
ref Span<T> unwritten = ref _unwritten;
_unwritten = unwritten.Slice(count, unwritten.Length - count);
}
public void Rewind(int count)
{
Span<T> span = Span;
int num = Span.Length - _unwritten.Length - count;
_unwritten = span.Slice(num, span.Length - num);
}
public void Reset()
{
_unwritten = Span;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void UnsafeAdvance(int count)
{
UncheckedSlice(ref _unwritten, count, _unwritten.Length - count);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe static void UncheckedSlice(ref Span<T> span, int start, int length)
{
span = MemoryMarshal.CreateSpan<T>(ref Unsafe.Add<T>(ref MemoryMarshal.GetReference<T>(span), (IntPtr)(void*)(uint)start), length);
}
}
}