using System.IO; using File = System.IO.File; namespace DTLib; /// /// Stream wrapper for some operations over data chunks. /// You can add multiple transform operations. /// /// using var pipe = new TransformStream(File.OpenRead("encrypted")) /// .AddTransform(ReportProgress) /// .AddTransform(Decrypt); /// using var o = File.OpenWrite("decrypted"); /// pipe.CopyTo(o); /// /// public class TransformStream : Stream { private readonly Stream _inputStream; public delegate void TransformFuncDelegate(byte[] buffer, int offset, int count); private List _transformFunctions = new(); public TransformStream(Stream inputStream) { _inputStream = inputStream; } public TransformStream AddTransform(TransformFuncDelegate f) { _transformFunctions.Add(f); return this; } public TransformStream AddTransforms(IEnumerable f) { _transformFunctions.AddRange(f); return this; } public override bool CanRead => _inputStream.CanRead; public override bool CanSeek => _inputStream.CanSeek; public override bool CanWrite => false; public override long Length => _inputStream.Length; public override long Position { get => _inputStream.Position; set => _inputStream.Position = value; } public override int Read(byte[] buffer, int offset, int count) { int read = _inputStream.Read(buffer, offset, count); if(read > 0) { for (int i = 0; i < _transformFunctions.Count; i++) { _transformFunctions[i].Invoke(buffer, offset, read); } } return read; } public override void Flush() {} public override long Seek(long offset, SeekOrigin origin) => _inputStream.Seek(offset, origin); public override void SetLength(long value) => throw new NotImplementedException(); public override void Write(byte[] buffer, int offset, int count) => throw new NotImplementedException(); public override void Close() => _inputStream.Close(); }