using System;
using System.IO;
#if GZIP
using SharpCompress.Archive.GZip;
#endif
#if RAR
using SharpCompress.Archive.Rar;
#endif
#if SEVENZIP
using SharpCompress.Archive.SevenZip;
#endif
#if TAR
using SharpCompress.Archive.Tar;
#endif
using SharpCompress.Archive.Zip;
using SharpCompress.Common;
namespace SharpCompress.Archive
{
internal class ArchiveFactory
{
///
/// Opens an Archive for random access
///
///
///
///
public static IArchive Open(Stream stream, Options options = Options.KeepStreamsOpen)
{
stream.CheckNotNull("stream");
if (!stream.CanRead || !stream.CanSeek)
{
throw new ArgumentException("Stream should be readable and seekable");
}
if (ZipArchive.IsZipFile(stream, null))
{
stream.Seek(0, SeekOrigin.Begin);
return ZipArchive.Open(stream, options, null);
}
#if RAR
stream.Seek(0, SeekOrigin.Begin);
if (RarArchive.IsRarFile(stream, Options.LookForHeader | Options.KeepStreamsOpen))
{
stream.Seek(0, SeekOrigin.Begin);
return RarArchive.Open(stream, options);
}
#endif
#if TAR
stream.Seek(0, SeekOrigin.Begin);
if (TarArchive.IsTarFile(stream))
{
stream.Seek(0, SeekOrigin.Begin);
return TarArchive.Open(stream, options);
}
#endif
#if SEVENZIP
stream.Seek(0, SeekOrigin.Begin);
if (SevenZipArchive.IsSevenZipFile(stream))
{
stream.Seek(0, SeekOrigin.Begin);
return SevenZipArchive.Open(stream, options);
}
#endif
#if GZIP
stream.Seek(0, SeekOrigin.Begin);
if (GZipArchive.IsGZipFile(stream))
{
stream.Seek(0, SeekOrigin.Begin);
return GZipArchive.Open(stream, options);
}
#endif
throw new InvalidOperationException("Cannot determine compressed stream type. Supported Archive Formats: Zip, GZip, Tar, Rar, 7Zip");
}
public static IArchive Create(ArchiveType type)
{
switch (type)
{
case ArchiveType.Zip:
{
return ZipArchive.Create();
}
#if TAR
case ArchiveType.Tar:
{
return TarArchive.Create();
}
#endif
default:
{
throw new NotSupportedException("Cannot create Archives of type: " + type);
}
}
}
#if !PORTABLE && !NETFX_CORE
///
/// Constructor expects a filepath to an existing file.
///
///
public static IArchive Open(string filePath)
{
return Open(filePath, Options.None);
}
///
/// Constructor with a FileInfo object to an existing file.
///
///
public static IArchive Open(FileInfo fileInfo)
{
return Open(fileInfo, Options.None);
}
///
/// Constructor expects a filepath to an existing file.
///
///
///
public static IArchive Open(string filePath, Options options)
{
filePath.CheckNotNullOrEmpty("filePath");
return Open(new FileInfo(filePath), options);
}
///
/// Constructor with a FileInfo object to an existing file.
///
///
///
public static IArchive Open(FileInfo fileInfo, Options options)
{
fileInfo.CheckNotNull("fileInfo");
using (var stream = fileInfo.OpenRead())
{
if (ZipArchive.IsZipFile(stream, null))
{
stream.Dispose();
return ZipArchive.Open(fileInfo, options, null);
}
#if RAR
stream.Seek(0, SeekOrigin.Begin);
if (RarArchive.IsRarFile(stream, Options.LookForHeader | Options.KeepStreamsOpen))
{
stream.Dispose();
return RarArchive.Open(fileInfo, options);
}
#endif
#if TAR
stream.Seek(0, SeekOrigin.Begin);
if (TarArchive.IsTarFile(stream))
{
stream.Dispose();
return TarArchive.Open(fileInfo, options);
}
#endif
#if SEVENZIP
stream.Seek(0, SeekOrigin.Begin);
if (SevenZipArchive.IsSevenZipFile(stream))
{
stream.Dispose();
return SevenZipArchive.Open(fileInfo, options);
}
#endif
#if GZIP
stream.Seek(0, SeekOrigin.Begin);
if (GZipArchive.IsGZipFile(stream))
{
stream.Dispose();
return GZipArchive.Open(fileInfo, options);
}
#endif
throw new InvalidOperationException("Cannot determine compressed stream type.");
}
}
///
/// Extract to specific directory, retaining filename
///
public static void WriteToDirectory(string sourceArchive, string destinationDirectory,
ExtractOptions options = ExtractOptions.Overwrite)
{
using (IArchive archive = Open(sourceArchive))
{
foreach (IArchiveEntry entry in archive.Entries)
{
entry.WriteToDirectory(destinationDirectory, options);
}
}
}
#endif
}
}