Skip to content

Instantly share code, notes, and snippets.

@MiloszKrajewski
Created August 15, 2025 11:01
Show Gist options
  • Select an option

  • Save MiloszKrajewski/185f2b5593329a0b3c443a76ce12128e to your computer and use it in GitHub Desktop.

Select an option

Save MiloszKrajewski/185f2b5593329a0b3c443a76ce12128e to your computer and use it in GitHub Desktop.
Passthrough stream
public abstract class PassthroughStream: Stream
{
private readonly Stream _stream;
/// <summary>Creates a new passthrough stream that wraps the given stream.
/// Technically, not all methods need to be implemented as we could use
/// base implementations from <see cref="Stream"/> itself, but default implementation
/// is not optimized for async methods.</summary>
/// <param name="stream">Wrapped stream.</param>
protected PassthroughStream(Stream stream) => _stream = stream;
/// <summary>Access to the inner stream.</summary>
protected Stream InnerStream => _stream;
/// <inheritdoc/>
public override bool CanRead => _stream.CanRead;
/// <inheritdoc/>
public override bool CanSeek => _stream.CanSeek;
/// <inheritdoc/>
public override bool CanWrite => _stream.CanWrite;
/// <inheritdoc/>
public override long Length => _stream.Length;
/// <inheritdoc/>
public override long Position
{
get => _stream.Position;
set => _stream.Position = value;
}
/// <inheritdoc/>
public override int ReadTimeout
{
get => _stream.ReadTimeout;
set => _stream.ReadTimeout = value;
}
/// <inheritdoc/>
public override int WriteTimeout
{
get => _stream.WriteTimeout;
set => _stream.WriteTimeout = value;
}
/// <inheritdoc/>
public override void Flush() =>
_stream.Flush();
/// <inheritdoc/>
public override int Read(byte[] buffer, int offset, int count) =>
_stream.Read(buffer, offset, count);
/// <inheritdoc/>
public override long Seek(long offset, SeekOrigin origin) =>
_stream.Seek(offset, origin);
/// <inheritdoc/>
public override void SetLength(long value) =>
_stream.SetLength(value);
/// <inheritdoc/>
public override void Write(byte[] buffer, int offset, int count) =>
_stream.Write(buffer, offset, count);
/// <inheritdoc/>
public override Task FlushAsync(CancellationToken cancellationToken) =>
_stream.FlushAsync(cancellationToken);
/// <inheritdoc/>
public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
_stream.ReadAsync(buffer, offset, count, cancellationToken);
/// <inheritdoc/>
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
_stream.WriteAsync(buffer, offset, count, cancellationToken);
/// <inheritdoc/>
public override ValueTask<int> ReadAsync(Memory<byte> buffer, CancellationToken cancellationToken = default) =>
_stream.ReadAsync(buffer, cancellationToken);
/// <inheritdoc/>
public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default) =>
_stream.WriteAsync(buffer, cancellationToken);
/// <inheritdoc/>
public override bool CanTimeout => _stream.CanTimeout;
/// <inheritdoc/>
public override int Read(Span<byte> buffer) =>
_stream.Read(buffer);
/// <inheritdoc/>
public override int ReadByte() =>
_stream.ReadByte();
/// <inheritdoc/>
public override void Write(ReadOnlySpan<byte> buffer) =>
_stream.Write(buffer);
/// <inheritdoc/>
public override void WriteByte(byte value) =>
_stream.WriteByte(value);
/// <inheritdoc/>
public override void CopyTo(Stream destination, int bufferSize) =>
_stream.CopyTo(destination, bufferSize);
/// <inheritdoc/>
public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) =>
_stream.CopyToAsync(destination, bufferSize, cancellationToken);
/// <inheritdoc/>
protected override void Dispose(bool disposing) =>
_stream.Dispose();
/// <inheritdoc/>
public override ValueTask DisposeAsync() =>
_stream.DisposeAsync();
/// <inheritdoc/>
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
_stream.BeginRead(buffer, offset, count, callback, state);
/// <inheritdoc/>
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) =>
_stream.BeginWrite(buffer, offset, count, callback, state);
/// <inheritdoc/>
public override int EndRead(IAsyncResult asyncResult) =>
_stream.EndRead(asyncResult);
/// <inheritdoc/>
public override void EndWrite(IAsyncResult asyncResult) =>
_stream.EndWrite(asyncResult);
protected static Exception NotSupported([CallerMemberName] string? operation = null) =>
new NotSupportedException($"Operation {operation ?? "<unknown>"} is not supported.");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment