Skip to content

Commit

Permalink
Merge pull request #226 from gardebring/master
Browse files Browse the repository at this point in the history
Add new event handler to allow tracking of progress of extraction progress for individual entry
  • Loading branch information
adamhathcock authored Apr 25, 2017
2 parents 58b4fe4 + 2aa123c commit bf55595
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 24 deletions.
5 changes: 4 additions & 1 deletion src/SharpCompress/Common/ReaderExtractionEventArgs.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
using System;
using SharpCompress.Readers;

namespace SharpCompress.Common
{
public class ReaderExtractionEventArgs<T> : EventArgs
{
internal ReaderExtractionEventArgs(T entry)
internal ReaderExtractionEventArgs(T entry, ReaderProgress readerProgress = null)
{
Item = entry;
ReaderProgress = readerProgress;
}

public T Item { get; private set; }
public ReaderProgress ReaderProgress { get; private set; }
}
}
24 changes: 8 additions & 16 deletions src/SharpCompress/Readers/AbstractReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public abstract class AbstractReader<TEntry, TVolume> : IReader, IReaderExtracti

public event EventHandler<ReaderExtractionEventArgs<IEntry>> EntryExtractionBegin;
public event EventHandler<ReaderExtractionEventArgs<IEntry>> EntryExtractionEnd;
public event EventHandler<ReaderExtractionEventArgs<IEntry>> EntryExtractionProgress;

public event EventHandler<CompressedBytesReadEventArgs> CompressedBytesRead;
public event EventHandler<FilePartExtractionBeginEventArgs> FilePartExtractionBegin;
Expand Down Expand Up @@ -179,18 +180,16 @@ public void WriteEntryTo(Stream writableStream)
"A writable Stream was required. Use Cancel if that was intended.");
}

var streamListener = this as IReaderExtractionListener;
streamListener.FireEntryExtractionBegin(Entry);
Write(writableStream);
streamListener.FireEntryExtractionEnd(Entry);
wroteCurrentEntry = true;
}

internal void Write(Stream writeStream)
{
var streamListener = this as IReaderExtractionListener;
using (Stream s = OpenEntryStream())
{
s.TransferTo(writeStream);
s.TransferTo(writeStream, Entry, streamListener);
}
}

Expand Down Expand Up @@ -246,20 +245,13 @@ void IExtractionListener.FireFilePartExtractionBegin(string name, long size, lon
});
}
}

void IReaderExtractionListener.FireEntryExtractionBegin(Entry entry)
{
if (EntryExtractionBegin != null)
{
EntryExtractionBegin(this, new ReaderExtractionEventArgs<IEntry>(entry));
}
}

void IReaderExtractionListener.FireEntryExtractionEnd(Entry entry)
void IReaderExtractionListener.FireEntryExtractionProgress(Entry entry, long bytesTransferred, int iterations)
{
if (EntryExtractionEnd != null)
if (EntryExtractionProgress != null)
{
EntryExtractionEnd(this, new ReaderExtractionEventArgs<IEntry>(entry));
EntryExtractionProgress(this,
new ReaderExtractionEventArgs<IEntry>(entry, new ReaderProgress(entry, bytesTransferred, iterations))
);
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/SharpCompress/Readers/IReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ namespace SharpCompress.Readers
{
public interface IReader : IDisposable
{
event EventHandler<ReaderExtractionEventArgs<IEntry>> EntryExtractionBegin;
event EventHandler<ReaderExtractionEventArgs<IEntry>> EntryExtractionEnd;
event EventHandler<ReaderExtractionEventArgs<IEntry>> EntryExtractionProgress;

event EventHandler<CompressedBytesReadEventArgs> CompressedBytesRead;
event EventHandler<FilePartExtractionBeginEventArgs> FilePartExtractionBegin;
Expand Down
4 changes: 1 addition & 3 deletions src/SharpCompress/Readers/IReaderExtractionListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ namespace SharpCompress.Readers
{
internal interface IReaderExtractionListener : IExtractionListener
{
// void EnsureEntriesLoaded();
void FireEntryExtractionBegin(Entry entry);
void FireEntryExtractionEnd(Entry entry);
void FireEntryExtractionProgress(Entry entry, long sizeTransferred, int iterations);
}
}
24 changes: 24 additions & 0 deletions src/SharpCompress/Readers/ReaderProgress.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
31 changes: 29 additions & 2 deletions src/SharpCompress/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using SharpCompress.Readers;

namespace SharpCompress
{
Expand Down Expand Up @@ -231,17 +232,43 @@ public static DateTime DosDateToDateTime(Int32 iTime)

public static long TransferTo(this Stream source, Stream destination)
{
byte[] array = new byte[81920];
byte[] array = GetTransferByteArray();
int count;
long total = 0;
while ((count = source.Read(array, 0, array.Length)) != 0)
while (ReadTransferBlock(source, array, out count))
{
total += count;
destination.Write(array, 0, count);
}
return total;
}

public static long TransferTo(this Stream source, Stream destination, Common.Entry entry, IReaderExtractionListener readerExtractionListener)
{
byte[] array = GetTransferByteArray();
int count;
var iterations = 0;
long total = 0;
while (ReadTransferBlock(source, array, out count))
{
total += count;
destination.Write(array, 0, count);
iterations++;
readerExtractionListener.FireEntryExtractionProgress(entry, total, iterations);
}
return total;
}

private static bool ReadTransferBlock(Stream source, byte[] array, out int count)
{
return (count = source.Read(array, 0, array.Length)) != 0;
}

private static byte[] GetTransferByteArray()
{
return new byte[81920];
}

public static bool ReadFully(this Stream stream, byte[] buffer)
{
int total = 0;
Expand Down

0 comments on commit bf55595

Please sign in to comment.