StreamSource
Represents Stream factory methods.
using DotNext.Buffers;
using System;
using System.Buffers;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace DotNext.IO
{
public static class StreamSource
{
[StructLayout(LayoutKind.Auto)]
private readonly struct ReadOnlySpanWriter<[System.Runtime.CompilerServices.Nullable(2)] TArg> : IReadOnlySpanConsumer<byte>, ISupplier<ReadOnlyMemory<byte>, CancellationToken, ValueTask>, IFlushable
{
[System.Runtime.CompilerServices.Nullable(1)]
private readonly ReadOnlySpanAction<byte, TArg> output;
[System.Runtime.CompilerServices.Nullable(1)]
private readonly TArg arg;
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})]
private readonly Action<TArg> flush;
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})]
private readonly Func<TArg, CancellationToken, Task> flushAsync;
[System.Runtime.CompilerServices.NullableContext(1)]
internal ReadOnlySpanWriter(ReadOnlySpanAction<byte, TArg> output, TArg arg, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] Action<TArg> flush, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})] Func<TArg, CancellationToken, Task> flushAsync)
{
this.output = output;
this.arg = arg;
this.flush = flush;
this.flushAsync = flushAsync;
}
void IFlushable.Flush()
{
StreamSource.Flush<TArg>(flush, flushAsync, arg);
}
[System.Runtime.CompilerServices.NullableContext(1)]
Task IFlushable.FlushAsync(CancellationToken token)
{
return StreamSource.FlushAsync<TArg>(flush, flushAsync, arg, token);
}
void IReadOnlySpanConsumer<byte>.Invoke(ReadOnlySpan<byte> input)
{
output(input, arg);
}
}
[StructLayout(LayoutKind.Auto)]
private readonly struct ReadOnlyMemoryWriter<[System.Runtime.CompilerServices.Nullable(2)] TArg> : ISupplier<ReadOnlyMemory<byte>, CancellationToken, ValueTask>, IFlushable
{
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1
})]
private readonly Func<ReadOnlyMemory<byte>, TArg, CancellationToken, ValueTask> output;
[System.Runtime.CompilerServices.Nullable(1)]
private readonly TArg arg;
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})]
private readonly Action<TArg> flush;
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})]
private readonly Func<TArg, CancellationToken, Task> flushAsync;
[System.Runtime.CompilerServices.NullableContext(1)]
internal ReadOnlyMemoryWriter([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1
})] Func<ReadOnlyMemory<byte>, TArg, CancellationToken, ValueTask> output, TArg arg, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] Action<TArg> flush, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})] Func<TArg, CancellationToken, Task> flushAsync)
{
this.output = output;
this.arg = arg;
this.flush = flush;
this.flushAsync = flushAsync;
}
void IFlushable.Flush()
{
StreamSource.Flush<TArg>(flush, flushAsync, arg);
}
[System.Runtime.CompilerServices.NullableContext(1)]
Task IFlushable.FlushAsync(CancellationToken token)
{
return StreamSource.FlushAsync<TArg>(flush, flushAsync, arg, token);
}
ValueTask ISupplier<ReadOnlyMemory<byte>, CancellationToken, ValueTask>.Invoke(ReadOnlyMemory<byte> input, CancellationToken token)
{
return output(input, arg, token);
}
}
[StructLayout(LayoutKind.Auto)]
private readonly struct BufferWriter<[System.Runtime.CompilerServices.Nullable(1)] TBuffer> : IReadOnlySpanConsumer<byte>, ISupplier<ReadOnlyMemory<byte>, CancellationToken, ValueTask>, IFlushable where TBuffer : class, IBufferWriter<byte>
{
[System.Runtime.CompilerServices.Nullable(1)]
private readonly TBuffer output;
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})]
private readonly Action<TBuffer> flush;
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})]
private readonly Func<TBuffer, CancellationToken, Task> flushAsync;
[System.Runtime.CompilerServices.NullableContext(1)]
internal BufferWriter(TBuffer output, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] Action<TBuffer> flush, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})] Func<TBuffer, CancellationToken, Task> flushAsync)
{
this.output = output;
this.flush = flush;
this.flushAsync = flushAsync;
}
void IFlushable.Flush()
{
StreamSource.Flush<TBuffer>(flush, flushAsync, output);
}
[System.Runtime.CompilerServices.NullableContext(1)]
Task IFlushable.FlushAsync(CancellationToken token)
{
return StreamSource.FlushAsync<TBuffer>(flush, flushAsync, output, token);
}
void IReadOnlySpanConsumer<byte>.Invoke(ReadOnlySpan<byte> input)
{
BuffersExtensions.Write<byte>((IBufferWriter<byte>)output, input);
}
}
[StructLayout(LayoutKind.Auto)]
private readonly struct DelegatingWriter<[System.Runtime.CompilerServices.Nullable(1)] TBuffer> : IReadOnlySpanConsumer<byte>, ISupplier<ReadOnlyMemory<byte>, CancellationToken, ValueTask>, IFlushable where TBuffer : class, IBufferWriter<byte>
{
[System.Runtime.CompilerServices.Nullable(1)]
private readonly TBuffer output;
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})]
private readonly Action<TBuffer> flush;
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})]
private readonly Func<TBuffer, CancellationToken, Task> flushAsync;
[System.Runtime.CompilerServices.NullableContext(1)]
internal DelegatingWriter(TBuffer output, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] Action<TBuffer> flush, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})] Func<TBuffer, CancellationToken, Task> flushAsync)
{
this.output = output;
this.flush = flush;
this.flushAsync = flushAsync;
}
void IFlushable.Flush()
{
StreamSource.Flush<TBuffer>(flush, flushAsync, output);
}
[System.Runtime.CompilerServices.NullableContext(1)]
Task IFlushable.FlushAsync(CancellationToken token)
{
return StreamSource.FlushAsync<TBuffer>(flush, flushAsync, output, token);
}
void IReadOnlySpanConsumer<byte>.Invoke(ReadOnlySpan<byte> input)
{
Unsafe.As<IReadOnlySpanConsumer<byte>>((object)output).Invoke(input);
}
}
[return: System.Runtime.CompilerServices.Nullable(1)]
public static Stream AsStream(this ArraySegment<byte> segment, bool writable = false)
{
if (!segment.Array.IsNullOrEmpty())
return new MemoryStream(segment.Array, segment.Offset, segment.Count, writable, false);
return Stream.Null;
}
[return: System.Runtime.CompilerServices.Nullable(1)]
public static Stream AsStream(this ReadOnlySequence<byte> sequence)
{
if (sequence.IsEmpty)
return Stream.Null;
if (SequenceMarshal.TryGetArray(sequence, out ArraySegment<byte> segment))
return segment.AsStream(false);
return new ReadOnlyMemoryStream(sequence);
}
[return: System.Runtime.CompilerServices.Nullable(1)]
public static Stream AsStream(this ReadOnlyMemory<byte> memory)
{
return new ReadOnlySequence<byte>(memory).AsStream();
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static Stream AsSynchronousStream<TOutput>(TOutput output) where TOutput : IFlushable, IReadOnlySpanConsumer<byte>
{
return new SyncWriterStream<TOutput>(output);
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static Stream AsStream<[System.Runtime.CompilerServices.Nullable(2)] TArg>(this ReadOnlySpanAction<byte, TArg> writer, TArg arg, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] Action<TArg> flush = null, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})] Func<TArg, CancellationToken, Task> flushAsync = null)
{
if (writer == null)
throw new ArgumentNullException("writer");
return AsSynchronousStream(new ReadOnlySpanWriter<TArg>(writer, arg, flush, flushAsync));
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static Stream AsStream<TWriter>(this TWriter writer, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] Action<TWriter> flush = null, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})] Func<TWriter, CancellationToken, Task> flushAsync = null) where TWriter : class, IBufferWriter<byte>
{
((IFlushable)).DiscoverFlushMethods(writer, ref flush, ref flushAsync);
if (!(writer is IReadOnlySpanConsumer<byte>))
return AsSynchronousStream(new BufferWriter<TWriter>(writer, flush, flushAsync));
return AsSynchronousStream(new DelegatingWriter<TWriter>(writer, flush, flushAsync));
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static Stream AsStream(this SparseBufferWriter<byte> writer, bool readable)
{
if (!readable)
return writer.AsStream(null, null);
SparseBufferWriter<byte>.MemoryChunk firstChunk = writer.FirstChunk;
if (firstChunk == null)
return Stream.Null;
if (firstChunk.Next == null)
return firstChunk.WrittenMemory.AsStream();
return new SparseMemoryStream(writer);
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static Stream AsAsynchronousStream<TOutput>(TOutput output) where TOutput : ISupplier<ReadOnlyMemory<byte>, CancellationToken, ValueTask>, IFlushable
{
return new AsyncWriterStream<TOutput>(output);
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static Stream AsStream<[System.Runtime.CompilerServices.Nullable(2)] TArg>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1
})] this Func<ReadOnlyMemory<byte>, TArg, CancellationToken, ValueTask> writer, TArg arg, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] Action<TArg> flush = null, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})] Func<TArg, CancellationToken, Task> flushAsync = null)
{
return AsAsynchronousStream(new ReadOnlyMemoryWriter<TArg>(writer, arg, flush, flushAsync));
}
[System.Runtime.CompilerServices.NullableContext(1)]
private static void Flush<[System.Runtime.CompilerServices.Nullable(2)] TArg>([System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] Action<TArg> flush, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})] Func<TArg, CancellationToken, Task> flushAsync, TArg arg)
{
if (flush == null)
flushAsync?.Invoke(arg, CancellationToken.None).ConfigureAwait(false).GetAwaiter()
.GetResult();
else
flush(arg);
}
[System.Runtime.CompilerServices.NullableContext(1)]
private static Task FlushAsync<[System.Runtime.CompilerServices.Nullable(2)] TArg>([System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] Action<TArg> flush, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})] Func<TArg, CancellationToken, Task> flushAsync, TArg arg, CancellationToken token)
{
if (flushAsync == null) {
if (flush != null)
return Task.Factory.StartNew(<FlushAsync>g__CreateTaskCallback|14_0(flush, arg), token, TaskCreationOptions.None, TaskScheduler.Current);
return Task.CompletedTask;
}
return flushAsync(arg, token);
}
}
}