Moved ExtractTo to common logic

This commit is contained in:
Adam Hathcock
2013-12-23 11:42:08 +00:00
parent afd65a7505
commit 4eda2043df
16 changed files with 83 additions and 118 deletions

View File

@@ -7,7 +7,7 @@ using SharpCompress.Reader;
namespace SharpCompress.Archive
{
public abstract class AbstractArchive<TEntry, TVolume> : IArchive, IStreamListener
public abstract class AbstractArchive<TEntry, TVolume> : IArchive, IArchiveExtractionListener
where TEntry : IArchiveEntry
where TVolume : IVolume
{
@@ -23,7 +23,7 @@ namespace SharpCompress.Archive
#if !PORTABLE && !NETFX_CORE
internal AbstractArchive(ArchiveType type, FileInfo fileInfo, Options options)
{
this.Type = type;
Type = type;
if (!fileInfo.Exists)
{
throw new ArgumentException("File does not exist: " + fileInfo.FullName);
@@ -52,7 +52,7 @@ namespace SharpCompress.Archive
lazyEntries = new LazyReadOnlyCollection<TEntry>(Enumerable.Empty<TEntry>());
}
internal void FireEntryExtractionBegin(IArchiveEntry entry)
void IArchiveExtractionListener.FireEntryExtractionBegin(IArchiveEntry entry)
{
if (EntryExtractionBegin != null)
{
@@ -60,7 +60,7 @@ namespace SharpCompress.Archive
}
}
internal void FireEntryExtractionEnd(IArchiveEntry entry)
void IArchiveExtractionListener.FireEntryExtractionEnd(IArchiveEntry entry)
{
if (EntryExtractionEnd != null)
{
@@ -128,7 +128,7 @@ namespace SharpCompress.Archive
}
}
internal void EnsureEntriesLoaded()
void IArchiveExtractionListener.EnsureEntriesLoaded()
{
lazyEntries.EnsureFullyLoaded();
lazyVolumes.EnsureFullyLoaded();
@@ -137,7 +137,7 @@ namespace SharpCompress.Archive
public ArchiveType Type { get; private set; }
void IStreamListener.FireCompressedBytesRead(long currentPartCompressedBytes, long compressedReadBytes)
void IExtractionListener.FireCompressedBytesRead(long currentPartCompressedBytes, long compressedReadBytes)
{
if (CompressedBytesRead != null)
{
@@ -149,7 +149,7 @@ namespace SharpCompress.Archive
}
}
void IStreamListener.FireFilePartExtractionBegin(string name, long size, long compressedSize)
void IExtractionListener.FireFilePartExtractionBegin(string name, long size, long compressedSize)
{
if (FilePartExtractionBegin != null)
{
@@ -175,7 +175,7 @@ namespace SharpCompress.Archive
/// <returns></returns>
public IReader ExtractAllEntries()
{
EnsureEntriesLoaded();
((IArchiveExtractionListener)this).EnsureEntriesLoaded();
return CreateReaderForSolidExtraction();
}
@@ -197,7 +197,7 @@ namespace SharpCompress.Archive
{
get
{
EnsureEntriesLoaded();
((IArchiveExtractionListener)this).EnsureEntriesLoaded();
return Entries.All(x => x.IsComplete);
}
}

View File

@@ -1,18 +1,16 @@
using System.IO;
using System.Linq;
using SharpCompress.Common;
using SharpCompress.Common.GZip;
namespace SharpCompress.Archive.GZip
{
public class GZipArchiveEntry : GZipEntry, IArchiveEntry
{
private readonly GZipArchive archive;
internal GZipArchiveEntry(GZipArchive archive, GZipFilePart part)
: base(part)
{
this.archive = archive;
Archive = archive;
}
public virtual Stream OpenEntryStream()
@@ -21,15 +19,7 @@ namespace SharpCompress.Archive.GZip
}
#region IArchiveEntry Members
public void WriteTo(Stream streamToWriteTo)
{
if (IsEncrypted)
{
throw new PasswordProtectedException("Entry is password protected and cannot be extracted.");
}
this.Extract(archive, streamToWriteTo);
}
public IArchive Archive { get; private set; }
public bool IsComplete
{

View File

@@ -1,10 +1,39 @@
using System.IO;
using SharpCompress.Common;
using SharpCompress.IO;
namespace SharpCompress.Archive
{
public static class IArchiveEntryExtensions
{
public static void WriteTo(this IArchiveEntry archiveEntry, Stream streamToWriteTo)
{
if (archiveEntry.Archive.IsSolid)
{
throw new InvalidFormatException("Cannot use Archive random access on SOLID Rar files.");
}
if (archiveEntry.IsEncrypted)
{
throw new PasswordProtectedException("Entry is password protected and cannot be extracted.");
}
if (archiveEntry.IsDirectory)
{
throw new ExtractionException("Entry is a file directory and cannot be extracted.");
}
var streamListener = archiveEntry.Archive as IArchiveExtractionListener;
streamListener.EnsureEntriesLoaded();
streamListener.FireEntryExtractionBegin(archiveEntry);
streamListener.FireFilePartExtractionBegin(archiveEntry.FilePath, archiveEntry.Size, archiveEntry.CompressedSize);
using (Stream s = new ListeningStream(streamListener, archiveEntry.OpenEntryStream()))
{
s.TransferTo(streamToWriteTo);
}
streamListener.FireEntryExtractionEnd(archiveEntry);
}
#if !PORTABLE && !NETFX_CORE
/// <summary>
/// Extract to specific directory, retaining filename
@@ -12,7 +41,7 @@ namespace SharpCompress.Archive
public static void WriteToDirectory(this IArchiveEntry entry, string destinationDirectory,
ExtractOptions options = ExtractOptions.Overwrite)
{
string destinationFileName = string.Empty;
string destinationFileName;
string file = Path.GetFileName(entry.FilePath);
@@ -50,9 +79,7 @@ namespace SharpCompress.Archive
fm = FileMode.CreateNew;
}
using (FileStream fs = File.Open(destinationFileName, fm))
// using (Stream entryStream = entry.OpenEntryStream())
{
//entryStream.TransferTo(fs);
entry.WriteTo(fs);
}
}

View File

@@ -11,11 +11,11 @@ namespace SharpCompress.Archive
/// </summary>
Stream OpenEntryStream();
void WriteTo(Stream stream);
/// <summary>
/// The archive can find all the parts of the archive needed to extract this entry.
/// </summary>
bool IsComplete { get; }
IArchive Archive { get; }
}
}

View File

@@ -0,0 +1,11 @@
using SharpCompress.Common;
namespace SharpCompress.Archive
{
internal interface IArchiveExtractionListener : IExtractionListener
{
void EnsureEntriesLoaded();
void FireEntryExtractionBegin(IArchiveEntry entry);
void FireEntryExtractionEnd(IArchiveEntry entry);
}
}

View File

@@ -19,13 +19,5 @@ namespace SharpCompress.Archive.Rar
{
return archive.Volumes.First().IsMultiVolume;
}
/// <summary>
/// RarArchive is SOLID (this means the Archive saved bytes by reusing information which helps for archives containing many small files).
/// </summary>
public static bool IsSolidArchive(this RarArchive archive)
{
return archive.IsSolid;
}
}
}

View File

@@ -11,11 +11,12 @@ namespace SharpCompress.Archive.Rar
public class RarArchiveEntry : RarEntry, IArchiveEntry
{
private readonly ICollection<RarFilePart> parts;
private readonly RarArchive archive;
internal RarArchiveEntry(RarArchive archive, IEnumerable<RarFilePart> parts)
{
this.parts = parts.ToList();
Archive = archive;
this.archive = archive;
}
public override CompressionType CompressionType
@@ -23,11 +24,17 @@ namespace SharpCompress.Archive.Rar
get { return CompressionType.Rar; }
}
private RarArchive Archive { get; set; }
public IArchive Archive
{
get
{
return archive;
}
}
internal override IEnumerable<FilePart> Parts
{
get { return parts.Cast<FilePart>(); }
get { return parts; }
}
internal override FileHeader FileHeader
@@ -41,8 +48,7 @@ namespace SharpCompress.Archive.Rar
{
CheckIncomplete();
return parts.Select(fp => fp.FileHeader)
.Where(fh => !fh.FileFlags.HasFlag(FileFlags.SPLIT_AFTER))
.Single().FileCRC;
.Single(fh => !fh.FileFlags.HasFlag(FileFlags.SPLIT_AFTER)).FileCRC;
}
}
@@ -67,22 +73,8 @@ namespace SharpCompress.Archive.Rar
public Stream OpenEntryStream()
{
return new RarStream(Archive.Unpack, FileHeader,
new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>(), Archive));
}
public void WriteTo(Stream streamToWriteTo)
{
CheckIncomplete();
if (Archive.IsSolidArchive())
{
throw new InvalidFormatException("Cannot use Archive random access on SOLID Rar files.");
}
if (IsEncrypted)
{
throw new PasswordProtectedException("Entry is password protected and cannot be extracted.");
}
this.Extract(Archive, streamToWriteTo);
return new RarStream(archive.Unpack, FileHeader,
new MultiVolumeReadOnlyStream(Parts.Cast<RarFilePart>(), archive));
}
public bool IsComplete

View File

@@ -1,32 +1,21 @@
using System.IO;
using SharpCompress.Common;
using SharpCompress.Common.SevenZip;
namespace SharpCompress.Archive.SevenZip
{
public class SevenZipArchiveEntry : SevenZipEntry, IArchiveEntry
{
private SevenZipArchive archive;
internal SevenZipArchiveEntry(SevenZipArchive archive, SevenZipFilePart part)
: base(part)
{
this.archive = archive;
Archive = archive;
}
public Stream OpenEntryStream()
{
return FilePart.GetCompressedStream();
}
public void WriteTo(Stream stream)
{
if (IsEncrypted)
{
throw new PasswordProtectedException("Entry is password protected and cannot be extracted.");
}
this.Extract(archive, stream);
}
public IArchive Archive { get; private set; }
public bool IsComplete
{

View File

@@ -7,12 +7,10 @@ namespace SharpCompress.Archive.Tar
{
public class TarArchiveEntry : TarEntry, IArchiveEntry
{
private readonly TarArchive archive;
internal TarArchiveEntry(TarArchive archive, TarFilePart part, CompressionType compressionType)
: base(part, compressionType)
{
this.archive = archive;
Archive = archive;
}
public virtual Stream OpenEntryStream()
@@ -21,15 +19,7 @@ namespace SharpCompress.Archive.Tar
}
#region IArchiveEntry Members
public void WriteTo(Stream streamToWriteTo)
{
if (IsEncrypted)
{
throw new PasswordProtectedException("Entry is password protected and cannot be extracted.");
}
this.Extract(archive, streamToWriteTo);
}
public IArchive Archive { get; private set; }
public bool IsComplete
{

View File

@@ -6,12 +6,10 @@ namespace SharpCompress.Archive.Zip
{
public class ZipArchiveEntry : ZipEntry, IArchiveEntry
{
private readonly ZipArchive archive;
internal ZipArchiveEntry(ZipArchive archive, SeekableZipFilePart part)
: base(part)
{
this.archive = archive;
Archive = archive;
}
public virtual Stream OpenEntryStream()
@@ -21,10 +19,7 @@ namespace SharpCompress.Archive.Zip
#region IArchiveEntry Members
public void WriteTo(Stream streamToWriteTo)
{
this.Extract(archive, streamToWriteTo);
}
public IArchive Archive { get; private set; }
public bool IsComplete
{

View File

@@ -1,6 +1,6 @@
namespace SharpCompress.Common
{
internal interface IStreamListener
internal interface IExtractionListener
{
void FireFilePartExtractionBegin(string name, long size, long compressedSize);
void FireCompressedBytesRead(long currentPartCompressedBytes, long compressedReadBytes);

View File

@@ -15,12 +15,12 @@ namespace SharpCompress.Compressor.Rar
private IEnumerator<RarFilePart> filePartEnumerator;
private Stream currentStream;
private readonly IStreamListener streamListener;
private readonly IExtractionListener streamListener;
private long currentPartTotalReadBytes;
private long currentEntryTotalReadBytes;
internal MultiVolumeReadOnlyStream(IEnumerable<RarFilePart> parts, IStreamListener streamListener)
internal MultiVolumeReadOnlyStream(IEnumerable<RarFilePart> parts, IExtractionListener streamListener)
{
this.streamListener = streamListener;

View File

@@ -6,9 +6,9 @@ namespace SharpCompress.IO
internal class ListeningStream : Stream
{
private long currentEntryTotalReadBytes;
private IStreamListener listener;
private IExtractionListener listener;
public ListeningStream(IStreamListener listener, Stream stream)
public ListeningStream(IExtractionListener listener, Stream stream)
{
Stream = stream;
this.listener = listener;

View File

@@ -4,7 +4,6 @@ using System.IO;
using System.Linq;
using SharpCompress.Common;
#if PORTABLE
using SharpCompress.Common.Rar.Headers;
#endif
@@ -14,7 +13,7 @@ namespace SharpCompress.Reader
/// <summary>
/// A generic push reader that reads unseekable comrpessed streams.
/// </summary>
public abstract class AbstractReader<TEntry, TVolume> : IReader, IStreamListener
public abstract class AbstractReader<TEntry, TVolume> : IReader, IExtractionListener
where TEntry : Entry
where TVolume : Volume
{
@@ -199,7 +198,7 @@ namespace SharpCompress.Reader
get { return Entry; }
}
void IStreamListener.FireCompressedBytesRead(long currentPartCompressedBytes, long compressedReadBytes)
void IExtractionListener.FireCompressedBytesRead(long currentPartCompressedBytes, long compressedReadBytes)
{
if (CompressedBytesRead != null)
{
@@ -211,7 +210,7 @@ namespace SharpCompress.Reader
}
}
void IStreamListener.FireFilePartExtractionBegin(string name, long size, long compressedSize)
void IExtractionListener.FireFilePartExtractionBegin(string name, long size, long compressedSize)
{
if (FilePartExtractionBegin != null)
{

View File

@@ -117,6 +117,7 @@
<Compile Include="Common\CompressionType.cs" />
<Compile Include="Common\FilePartExtractionBeginEventArgs.cs" />
<Compile Include="Common\GenericVolume.cs" />
<Compile Include="Archive\IArchiveExtractionListener.cs" />
<Compile Include="Common\IncompleteArchiveException.cs" />
<Compile Include="Common\MultiVolumeExtractionException.cs" />
<Compile Include="Common\PasswordProtectedException.cs" />
@@ -266,7 +267,7 @@
<Compile Include="Common\InvalidFormatException.cs" />
<Compile Include="IO\ReadOnlySubStream.cs" />
<Compile Include="IO\StreamingMode.cs" />
<Compile Include="Common\IStreamListener.cs" />
<Compile Include="Common\IExtractionListener.cs" />
<Compile Include="Common\MultipartStreamRequiredException.cs" />
<Compile Include="LazyReadOnlyCollection.cs" />
<Compile Include="Archive\Rar\RarArchive.Extensions.cs" />

View File

@@ -454,27 +454,6 @@ namespace SharpCompress
return true;
}
internal static void Extract<TEntry, TVolume>(this TEntry entry,
AbstractArchive<TEntry, TVolume> archive, Stream streamToWriteTo)
where TEntry : IArchiveEntry
where TVolume : IVolume
{
if (entry.IsDirectory)
{
throw new ExtractionException("Entry is a file directory and cannot be extracted.");
}
archive.EnsureEntriesLoaded();
archive.FireEntryExtractionBegin(entry);
((IStreamListener)archive).FireFilePartExtractionBegin(entry.FilePath, entry.Size, entry.CompressedSize);
using (Stream s = new ListeningStream(archive, entry.OpenEntryStream()))
{
s.TransferTo(streamToWriteTo);
}
archive.FireEntryExtractionEnd(entry);
}
#if PORTABLE || NETFX_CORE
public static void CopyTo(this byte[] array, byte[] destination, int index)
{