diff --git a/src/SharpCompress/Common/ReaderExtractionEventArgs.cs b/src/SharpCompress/Common/ReaderExtractionEventArgs.cs index b33b8635..fd11e894 100644 --- a/src/SharpCompress/Common/ReaderExtractionEventArgs.cs +++ b/src/SharpCompress/Common/ReaderExtractionEventArgs.cs @@ -4,11 +4,13 @@ namespace SharpCompress.Common { public class ReaderExtractionEventArgs : EventArgs { - internal ReaderExtractionEventArgs(T entry) + internal ReaderExtractionEventArgs(T entry, params object[] paramList) { Item = entry; + ParamList = paramList; } public T Item { get; private set; } + public object[] ParamList { get; private set; } } } \ No newline at end of file diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs index 380e8df5..85289cb4 100644 --- a/src/SharpCompress/Readers/AbstractReader.cs +++ b/src/SharpCompress/Readers/AbstractReader.cs @@ -19,6 +19,7 @@ namespace SharpCompress.Readers public event EventHandler> EntryExtractionBegin; public event EventHandler> EntryExtractionEnd; + public event EventHandler> EntryExtractionProgress; public event EventHandler CompressedBytesRead; public event EventHandler FilePartExtractionBegin; @@ -181,16 +182,16 @@ namespace SharpCompress.Readers var streamListener = this as IReaderExtractionListener; streamListener.FireEntryExtractionBegin(Entry); - Write(writableStream); + Write(writableStream, streamListener); streamListener.FireEntryExtractionEnd(Entry); wroteCurrentEntry = true; } - internal void Write(Stream writeStream) + internal void Write(Stream writeStream, IReaderExtractionListener streamListener) { using (Stream s = OpenEntryStream()) { - s.TransferTo(writeStream); + s.TransferTo(writeStream, (sizeTransferred, iterations) => streamListener.FireEntryExtractionProgress(Entry, sizeTransferred, iterations)); } } @@ -255,6 +256,14 @@ namespace SharpCompress.Readers } } + void IReaderExtractionListener.FireEntryExtractionProgress(Entry entry, long bytesTransferred, int iterations) + { + if (EntryExtractionProgress != null) + { + EntryExtractionProgress(this, new ReaderExtractionEventArgs(entry, new ReaderProgress(entry, bytesTransferred, iterations))); + } + } + void IReaderExtractionListener.FireEntryExtractionEnd(Entry entry) { if (EntryExtractionEnd != null) diff --git a/src/SharpCompress/Readers/IReader.cs b/src/SharpCompress/Readers/IReader.cs index 0df03177..1f8dbdab 100644 --- a/src/SharpCompress/Readers/IReader.cs +++ b/src/SharpCompress/Readers/IReader.cs @@ -8,6 +8,7 @@ namespace SharpCompress.Readers { event EventHandler> EntryExtractionBegin; event EventHandler> EntryExtractionEnd; + event EventHandler> EntryExtractionProgress; event EventHandler CompressedBytesRead; event EventHandler FilePartExtractionBegin; diff --git a/src/SharpCompress/Readers/IReaderExtractionListener.cs b/src/SharpCompress/Readers/IReaderExtractionListener.cs index 226b0944..e00d9801 100644 --- a/src/SharpCompress/Readers/IReaderExtractionListener.cs +++ b/src/SharpCompress/Readers/IReaderExtractionListener.cs @@ -7,5 +7,6 @@ namespace SharpCompress.Readers // void EnsureEntriesLoaded(); void FireEntryExtractionBegin(Entry entry); void FireEntryExtractionEnd(Entry entry); + void FireEntryExtractionProgress(Entry entry, long sizeTransferred, int iterations); } } \ No newline at end of file diff --git a/src/SharpCompress/Readers/ReaderProgress.cs b/src/SharpCompress/Readers/ReaderProgress.cs new file mode 100644 index 00000000..94feb74d --- /dev/null +++ b/src/SharpCompress/Readers/ReaderProgress.cs @@ -0,0 +1,24 @@ + + +using System; +using SharpCompress.Common; + +namespace SharpCompress.Readers +{ + public class ReaderProgress + { + private readonly IEntry _entry; + public long BytesTransferred { get; private set; } + public int Iterations { get; private set; } + + public int PercentageRead => (int)Math.Round(PercentageReadExact); + public double PercentageReadExact => (float)BytesTransferred / _entry.Size * 100; + + public ReaderProgress(IEntry entry, long bytesTransferred, int iterations) + { + _entry = entry; + BytesTransferred = bytesTransferred; + Iterations = iterations; + } + } +} diff --git a/src/SharpCompress/Utility.cs b/src/SharpCompress/Utility.cs index 451075f3..00952846 100644 --- a/src/SharpCompress/Utility.cs +++ b/src/SharpCompress/Utility.cs @@ -229,15 +229,18 @@ namespace SharpCompress return DosDateToDateTime((UInt32)iTime); } - public static long TransferTo(this Stream source, Stream destination) + public static long TransferTo(this Stream source, Stream destination, Action action = null) { byte[] array = new byte[81920]; int count; + var iterations = 0; long total = 0; while ((count = source.Read(array, 0, array.Length)) != 0) { total += count; destination.Write(array, 0, count); + iterations++; + action?.Invoke(total, iterations); } return total; }