| File: System\Net\DelegatedStream.cs | Web Access |
| Project: src\runtime\src\libraries\System.Net.Mail\src\System.Net.Mail.csproj (System.Net.Mail) |
// 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; using System.Buffers; namespace System.Net { internal abstract class DelegatedStream : Stream { private readonly Stream _stream; protected DelegatedStream(Stream stream) { ArgumentNullException.ThrowIfNull(stream); _stream = stream; } protected Stream BaseStream => _stream; public override bool CanSeek => _stream.CanSeek; public abstract override bool CanRead { get; } public abstract override bool CanWrite { get; } public override long Length { get { if (!CanSeek) throw new NotSupportedException(SR.SeekNotSupported); return _stream.Length; } } public override long Position { get { if (!CanSeek) throw new NotSupportedException(SR.SeekNotSupported); return _stream.Position; } set { if (!CanSeek) throw new NotSupportedException(SR.SeekNotSupported); _stream.Position = value; } } public sealed override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) { return TaskToAsyncResult.Begin(ReadAsync(buffer, offset, count, CancellationToken.None), callback, state); } public sealed override int EndRead(IAsyncResult asyncResult) { return TaskToAsyncResult.End<int>(asyncResult); } public sealed override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) { return TaskToAsyncResult.Begin(WriteAsync(buffer, offset, count, CancellationToken.None), callback, state); } public sealed override void EndWrite(IAsyncResult asyncResult) { TaskToAsyncResult.End(asyncResult); } public override void Close() { _stream.Close(); base.Close(); } protected override void Dispose(bool disposing) { if (disposing) { _stream.Dispose(); } base.Dispose(disposing); } public override void Flush() { _stream.Flush(); } public override Task FlushAsync(CancellationToken cancellationToken) { return _stream.FlushAsync(cancellationToken); } // Abstract methods for derived classes to implement core logic protected abstract int ReadInternal(Span<byte> buffer); protected abstract ValueTask<int> ReadAsyncInternal(Memory<byte> buffer, CancellationToken cancellationToken); protected abstract void WriteInternal(ReadOnlySpan<byte> buffer); protected abstract ValueTask WriteAsyncInternal(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken); // Sealed methods implementing the Stream Read/Write methods public sealed override int Read(Span<byte> buffer) { if (!CanRead) throw new NotSupportedException(SR.ReadNotSupported); return ReadInternal(buffer); } public sealed override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default) { if (!CanRead) throw new NotSupportedException(SR.ReadNotSupported); return ReadAsyncInternal(buffer, cancellationToken); } public sealed override int Read(byte[] buffer, int offset, int count) { ValidateBufferArguments(buffer, offset, count); if (!CanRead) throw new NotSupportedException(SR.ReadNotSupported); return ReadInternal(buffer.AsSpan(offset, count)); } public sealed override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { ValidateBufferArguments(buffer, offset, count); if (!CanRead) throw new NotSupportedException(SR.ReadNotSupported); return ReadAsyncInternal(buffer.AsMemory(offset, count), cancellationToken).AsTask(); } public sealed override int ReadByte() { if (!CanRead) throw new NotSupportedException(SR.ReadNotSupported); byte b = 0; return ReadInternal(new Span<byte>(ref b)) != 0 ? b : -1; } public sealed override long Seek(long offset, SeekOrigin origin) { if (!CanSeek) throw new NotSupportedException(SR.SeekNotSupported); return _stream.Seek(offset, origin); } public sealed override void SetLength(long value) { if (!CanSeek) throw new NotSupportedException(SR.SeekNotSupported); _stream.SetLength(value); } public sealed override void Write(ReadOnlySpan<byte> buffer) { if (!CanWrite) throw new NotSupportedException(SR.WriteNotSupported); WriteInternal(buffer); } public sealed override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default) { if (!CanWrite) throw new NotSupportedException(SR.WriteNotSupported); return WriteAsyncInternal(buffer, cancellationToken); } public sealed override void Write(byte[] buffer, int offset, int count) { ValidateBufferArguments(buffer, offset, count); if (!CanWrite) throw new NotSupportedException(SR.WriteNotSupported); WriteInternal(buffer.AsSpan(offset, count)); } public sealed override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) { ValidateBufferArguments(buffer, offset, count); if (!CanWrite) throw new NotSupportedException(SR.WriteNotSupported); return WriteAsyncInternal(buffer.AsMemory(offset, count), cancellationToken).AsTask(); } } }