| File: src\runtime\src\libraries\Common\src\System\ReadWriteAdapter.cs | Web Access |
| Project: src\runtime\src\libraries\System.Formats.Tar\src\System.Formats.Tar.csproj (System.Formats.Tar) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.IO; using System.Threading; using System.Threading.Tasks; namespace System { // Static-abstract adapter that lets a single generic implementation serve both // synchronous and asynchronous code paths. The sync entry point passes // SyncReadWriteAdapter and asserts the returned ValueTask is already completed; // the async entry point passes AsyncReadWriteAdapter. // // Originally used by SslStream and SmtpClient for networking I/O deduplication. // Extended for System.Formats.Tar (CopyToAsync, ReadExactlyAsync, DisposeAsync) // to unify TarReader/TarWriter/GnuSparseStream sync/async pairs. internal interface IReadWriteAdapter { static abstract ValueTask<int> ReadAsync(Stream stream, Memory<byte> buffer, CancellationToken cancellationToken); static abstract ValueTask<int> ReadAtLeastAsync(Stream stream, Memory<byte> buffer, int minimumBytes, bool throwOnEndOfStream, CancellationToken cancellationToken); static abstract ValueTask ReadExactlyAsync(Stream stream, Memory<byte> buffer, CancellationToken cancellationToken); static abstract ValueTask WriteAsync(Stream stream, ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken); static abstract ValueTask CopyToAsync(Stream source, Stream destination, CancellationToken cancellationToken); static abstract ValueTask DisposeAsync(Stream stream); static abstract Task FlushAsync(Stream stream, CancellationToken cancellationToken); static abstract Task WaitAsync(TaskCompletionSource<bool> waiter); static abstract Task WaitAsync(Task task); static abstract ValueTask<T> WaitAsync<T>(ValueTask<T> task); } internal readonly struct AsyncReadWriteAdapter : IReadWriteAdapter { public static ValueTask<int> ReadAsync(Stream stream, Memory<byte> buffer, CancellationToken cancellationToken) => stream.ReadAsync(buffer, cancellationToken); public static ValueTask<int> ReadAtLeastAsync(Stream stream, Memory<byte> buffer, int minimumBytes, bool throwOnEndOfStream, CancellationToken cancellationToken) => stream.ReadAtLeastAsync(buffer, minimumBytes, throwOnEndOfStream, cancellationToken); public static ValueTask ReadExactlyAsync(Stream stream, Memory<byte> buffer, CancellationToken cancellationToken) => stream.ReadExactlyAsync(buffer, cancellationToken); public static ValueTask WriteAsync(Stream stream, ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken) => stream.WriteAsync(buffer, cancellationToken); public static ValueTask CopyToAsync(Stream source, Stream destination, CancellationToken cancellationToken) => new ValueTask(source.CopyToAsync(destination, cancellationToken)); public static ValueTask DisposeAsync(Stream stream) => stream.DisposeAsync(); public static Task FlushAsync(Stream stream, CancellationToken cancellationToken) => stream.FlushAsync(cancellationToken); public static Task WaitAsync(TaskCompletionSource<bool> waiter) => waiter.Task; public static Task WaitAsync(Task task) => task; public static ValueTask<T> WaitAsync<T>(ValueTask<T> task) => task; } internal readonly struct SyncReadWriteAdapter : IReadWriteAdapter { public static ValueTask<int> ReadAsync(Stream stream, Memory<byte> buffer, CancellationToken cancellationToken) => new ValueTask<int>(stream.Read(buffer.Span)); public static ValueTask<int> ReadAtLeastAsync(Stream stream, Memory<byte> buffer, int minimumBytes, bool throwOnEndOfStream, CancellationToken cancellationToken) => new ValueTask<int>(stream.ReadAtLeast(buffer.Span, minimumBytes, throwOnEndOfStream)); public static ValueTask ReadExactlyAsync(Stream stream, Memory<byte> buffer, CancellationToken cancellationToken) { stream.ReadExactly(buffer.Span); return default; } public static ValueTask WriteAsync(Stream stream, ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken) { stream.Write(buffer.Span); return default; } public static ValueTask CopyToAsync(Stream source, Stream destination, CancellationToken cancellationToken) { source.CopyTo(destination); return default; } public static ValueTask DisposeAsync(Stream stream) { stream.Dispose(); return default; } public static Task FlushAsync(Stream stream, CancellationToken cancellationToken) { stream.Flush(); return Task.CompletedTask; } public static Task WaitAsync(TaskCompletionSource<bool> waiter) { waiter.Task.GetAwaiter().GetResult(); return Task.CompletedTask; } public static Task WaitAsync(Task task) { task.GetAwaiter().GetResult(); return Task.CompletedTask; } public static ValueTask<T> WaitAsync<T>(ValueTask<T> task) { return ValueTask.FromResult(task.AsTask().GetAwaiter().GetResult()); } } }