DotNext by .NET Foundation and Contributors

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

 WriterStream<TOutput>

abstract class WriterStream<TOutput> : Stream, IFlushable where TOutput : IFlushable
using DotNext.Threading; using DotNext.Threading.Tasks; using System; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; namespace DotNext.IO { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] internal abstract class WriterStream<TOutput> : Stream, IFlushable where TOutput : IFlushable { private protected TOutput output; private protected long writtenBytes; public sealed override bool CanRead => false; public sealed override bool CanWrite => true; public sealed override bool CanSeek => false; public override bool CanTimeout => false; public sealed override long Position { get { return writtenBytes; } set { throw new NotSupportedException(); } } public sealed override long Length => writtenBytes; private protected WriterStream(TOutput output) { this.output = output; } public sealed override void SetLength(long value) { throw new NotSupportedException(); } public sealed override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } [System.Runtime.CompilerServices.NullableContext(0)] public abstract override void Write(ReadOnlySpan<byte> buffer); public sealed override void Write(byte[] buffer, int offset, int count) { Stream.ValidateBufferArguments(buffer, offset, count); Write(new ReadOnlySpan<byte>(buffer, offset, count)); } public sealed override void WriteByte(byte value) { Write(MemoryMarshal.CreateReadOnlySpan<byte>(ref value, 1)); } [System.Runtime.CompilerServices.NullableContext(0)] public abstract override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken token); public sealed override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken token) { return WriteAsync(MemoryExtensions.AsMemory<byte>(buffer, offset, count), token).AsTask(); } [System.Runtime.CompilerServices.NullableContext(0)] [AsyncStateMachine(typeof(WriterStream<>.<WriteWithTimeoutAsync>d__23))] [return: System.Runtime.CompilerServices.Nullable(1)] private Task WriteWithTimeoutAsync(ReadOnlyMemory<byte> buffer) { <WriteWithTimeoutAsync>d__23 stateMachine = default(<WriteWithTimeoutAsync>d__23); stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create(); stateMachine.<>4__this = this; stateMachine.buffer = buffer; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start<<WriteWithTimeoutAsync>d__23>(ref stateMachine); return stateMachine.<>t__builder.Task; } public sealed override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, [System.Runtime.CompilerServices.Nullable(2)] AsyncCallback callback, [System.Runtime.CompilerServices.Nullable(2)] object state) { Task task; if (CanTimeout) { task = WriteWithTimeoutAsync(MemoryExtensions.AsMemory<byte>(buffer, offset, count)); if (state != null) task = task.AttachState(state, default(CancellationToken)); if (callback != null) { if (task.IsCompleted) callback(task); else task.ConfigureAwait(false).GetAwaiter().OnCompleted(delegate { callback(task); }); } } else task = ((Action<object>)delegate { Write(buffer, offset, count); }).BeginInvoke(state, callback, TaskCreationOptions.None, (TaskScheduler)null); return task; } private static void EndWrite(Task task) { using (task) task.Wait(); } public override void EndWrite(IAsyncResult ar) { EndWrite((Task)ar); } public sealed override void CopyTo(Stream destination, int bufferSize) { throw new NotSupportedException(); } public sealed override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken token) { if (!token.IsCancellationRequested) return Task.FromException(new NotSupportedException()); return Task.FromCanceled(token); } public sealed override void Flush() { output.Flush(); } public sealed override Task FlushAsync(CancellationToken token) { return output.FlushAsync(token); } public sealed override IAsyncResult BeginRead(byte[] buffer, int offset, int count, [System.Runtime.CompilerServices.Nullable(2)] AsyncCallback callback, [System.Runtime.CompilerServices.Nullable(2)] object state) { throw new NotSupportedException(); } public sealed override int EndRead(IAsyncResult ar) { throw new InvalidOperationException(); } [System.Runtime.CompilerServices.NullableContext(0)] public sealed override int Read(Span<byte> buffer) { throw new NotSupportedException(); } public sealed override int ReadByte() { throw new NotSupportedException(); } public sealed override int Read(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } public sealed override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken token) { if (!token.IsCancellationRequested) return Task.FromException<int>((Exception)new NotSupportedException()); return Task.FromCanceled<int>(token); } [System.Runtime.CompilerServices.NullableContext(0)] public sealed override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken token = default(CancellationToken)) { if (!token.IsCancellationRequested) return ValueTask.FromException<int>((Exception)new NotSupportedException()); return ValueTask.FromCanceled<int>(token); } } }