DotNext by .NET Foundation and Contributors

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

 ReadOnlyStream

abstract class ReadOnlyStream : Stream, IFlushable
using DotNext.Threading; using System; using System.IO; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; namespace DotNext.IO { internal abstract class ReadOnlyStream : Stream, IFlushable { public sealed override bool CanRead => true; public sealed override bool CanWrite => false; public sealed override bool CanTimeout => false; public override void Flush() { } public override Task FlushAsync(CancellationToken token) { if (!token.IsCancellationRequested) return Task.CompletedTask; return Task.FromCanceled(token); } public abstract override int Read(Span<byte> buffer); public sealed override int ReadByte() { byte reference = 0; if (Read(MemoryMarshal.CreateSpan(ref reference, 1)) != 1) return -1; return reference; } public sealed override int Read(byte[] buffer, int offset, int count) { Stream.ValidateBufferArguments(buffer, offset, count); return Read(buffer.AsSpan(offset, count)); } public sealed override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken token) { if (!token.IsCancellationRequested) try { return new ValueTask<int>(Read(buffer.Span)); } catch (Exception exception) { return ValueTask.FromException<int>(exception); } return ValueTask.FromCanceled<int>(token); } public sealed override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken token) { return ReadAsync(buffer.AsMemory(offset, count), token).AsTask(); } public sealed override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { return AsyncDelegate.BeginInvoke((object _) => Read(buffer, offset, count), state, callback, TaskCreationOptions.None, null); } private static int EndRead(Task<int> task) { using (task) return task.Result; } public sealed override int EndRead(IAsyncResult ar) { return EndRead((Task<int>)ar); } public sealed override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } public sealed override void Write(ReadOnlySpan<byte> buffer) { throw new NotSupportedException(); } public sealed override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken token) { if (!token.IsCancellationRequested) return Task.FromException(new NotSupportedException()); return Task.FromCanceled(token); } public sealed override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken token) { if (!token.IsCancellationRequested) return ValueTask.FromException(new NotSupportedException()); return ValueTask.FromCanceled(token); } public sealed override void WriteByte(byte value) { throw new NotSupportedException(); } public sealed override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { throw new NotSupportedException(); } public sealed override void EndWrite(IAsyncResult ar) { throw new InvalidOperationException(); } } }