DotNext by .NET Foundation and Contributors

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

 StreamSource

public static class 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); } } }