WriterStream<TOutput>
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);
}
}
}