DotNext by .NET Foundation and Contributors

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

 ReadOnlyMemoryStream

using DotNext.Buffers; 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 SequencePosition position; private ReadOnlySequence<byte> RemainingSequence => sequence.Slice(position); public override bool CanSeek => true; public override long Length => sequence.Length; public override long Position { get { return sequence.GetOffset(position); } set { if ((ulong)value > (ulong)sequence.Length) throw new ArgumentOutOfRangeException("value"); position = sequence.GetPosition(value); } } internal ReadOnlyMemoryStream(ReadOnlySequence<byte> sequence) { this.sequence = sequence; position = sequence.Start; } [AsyncStateMachine(typeof(<CopyToAsync>d__12))] public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken token) { <CopyToAsync>d__12 stateMachine = default(<CopyToAsync>d__12); stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create(); stateMachine.<>4__this = this; stateMachine.destination = destination; stateMachine.bufferSize = bufferSize; stateMachine.token = token; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } public override void CopyTo(Stream destination, int bufferSize) { Stream.ValidateCopyToArguments(destination, bufferSize); ReadOnlySequence<byte>.Enumerator enumerator = RemainingSequence.GetEnumerator(); while (enumerator.MoveNext()) { destination.Write(enumerator.Current.Span); } position = sequence.End; } public override void SetLength(long value) { ReadOnlySequence<byte> readOnlySequence = sequence.Slice(0, value); position = readOnlySequence.GetPosition(Math.Min(sequence.GetOffset(position), readOnlySequence.Length)); sequence = readOnlySequence; } public override int Read(Span<byte> buffer) { ReadOnlySequence<byte> source = RemainingSequence; ref source.CopyTo(buffer, out int writtenCount); position = sequence.GetPosition(writtenCount, position); return writtenCount; } public override long Seek(long offset, SeekOrigin origin) { long num; switch (origin) { case SeekOrigin.Begin: num = offset; break; case SeekOrigin.Current: num = sequence.GetOffset(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"); position = sequence.GetPosition(num2); return num2; } public override string ToString() { return sequence.ToString(); } } }