DotNext by Roman Sakno

<PackageReference Include="DotNext" Version="3.1.1" />

 ReadOnlyMemoryStream

using System; using System.Buffers; using System.IO; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; namespace DotNext.IO { internal sealed class ReadOnlyMemoryStream : ReadOnlyStream { private ReadOnlySequence<byte> sequence; private long position; public override bool CanSeek => true; public override long Length => sequence.Length; public override long Position { get { return position; } set { if (value < 0 || value > sequence.Length) throw new ArgumentOutOfRangeException("value"); position = value; } } internal ReadOnlyMemoryStream(ReadOnlySequence<byte> sequence) { this.sequence = sequence; position = 0; } [System.Runtime.CompilerServices.NullableContext(1)] [AsyncStateMachine(typeof(<CopyToAsync>d__10))] public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken token) { <CopyToAsync>d__10 stateMachine = default(<CopyToAsync>d__10); stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create(); stateMachine.<>4__this = this; stateMachine.destination = destination; stateMachine.token = token; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } [System.Runtime.CompilerServices.NullableContext(1)] public override void CopyTo(Stream destination, int bufferSize) { SequencePosition sequencePosition = sequence.GetPosition(position); ReadOnlyMemory<byte> memory; while (sequence.TryGet(ref sequencePosition, out memory, true) && !memory.IsEmpty) { destination.Write(memory.Span); position += memory.Length; } } public override void SetLength(long value) { sequence = sequence.Slice(0, value); position = Math.Min(position, sequence.Length); } public override int Read(Span<byte> buffer) { long num = sequence.Length - position; if (num <= 0 || buffer.Length == 0) return 0; int num2 = (int)Math.Min(buffer.Length, num); ReadOnlySequence<byte> source = sequence.Slice(position, num2); ref source.CopyTo(buffer); position += num2; return num2; } public override long Seek(long offset, SeekOrigin origin) { long num; switch (origin) { case SeekOrigin.Begin: num = offset; break; case SeekOrigin.Current: num = position + offset; break; case SeekOrigin.End: num = sequence.Length + offset; break; default: throw new ArgumentOutOfRangeException("origin"); } long num2 = num; if (num2 < 0) throw new IOException(); if (num2 > sequence.Length) throw new ArgumentOutOfRangeException("offset"); return position = num2; } [System.Runtime.CompilerServices.NullableContext(1)] public override string ToString() { return sequence.ToString(); } } }