using System.Collections.Generic; using System.IO; using System.Linq; using SharpCompress.Common; using SharpCompress.Common.Rar; using SharpCompress.Common.Rar.Headers; using SharpCompress.Compressors.Rar; using SharpCompress.Readers; using SharpCompress.Readers.Rar; namespace SharpCompress.Archives.Rar { public class RarArchive : AbstractArchive { internal Lazy UnpackV2017 { get; } = new Lazy(() => new SharpCompress.Compressors.Rar.UnpackV2017.Unpack()); internal Lazy UnpackV1 { get; } = new Lazy(() => new SharpCompress.Compressors.Rar.UnpackV1.Unpack()); #if !NO_FILE /// /// Constructor with a FileInfo object to an existing file. /// /// /// internal RarArchive(FileInfo fileInfo, ReaderOptions options) : base(ArchiveType.Rar, fileInfo, options) { } protected override IEnumerable LoadVolumes(FileInfo file) { return RarArchiveVolumeFactory.GetParts(file, ReaderOptions); } #endif /// /// Takes multiple seekable Streams for a multi-part archive /// /// /// internal RarArchive(IEnumerable streams, ReaderOptions options) : base(ArchiveType.Rar, streams, options) { } protected override IEnumerable LoadEntries(IEnumerable volumes) { return RarArchiveEntryFactory.GetEntries(this, volumes); } protected override IEnumerable LoadVolumes(IEnumerable streams) { return RarArchiveVolumeFactory.GetParts(streams, ReaderOptions); } protected override IReader CreateReaderForSolidExtraction() { var stream = Volumes.First().Stream; stream.Position = 0; return RarReader.Open(stream, ReaderOptions); } public override bool IsSolid => Volumes.First().IsSolidArchive; #region Creation #if !NO_FILE /// /// Constructor with a FileInfo object to an existing file. /// /// /// public static RarArchive Open(string filePath, ReaderOptions options = null) { filePath.CheckNotNullOrEmpty("filePath"); return new RarArchive(new FileInfo(filePath), options ?? new ReaderOptions()); } /// /// Constructor with a FileInfo object to an existing file. /// /// /// public static RarArchive Open(FileInfo fileInfo, ReaderOptions options = null) { fileInfo.CheckNotNull("fileInfo"); return new RarArchive(fileInfo, options ?? new ReaderOptions()); } #endif /// /// Takes a seekable Stream as a source /// /// /// public static RarArchive Open(Stream stream, ReaderOptions options = null) { stream.CheckNotNull("stream"); return Open(stream.AsEnumerable(), options ?? new ReaderOptions()); } /// /// Takes multiple seekable Streams for a multi-part archive /// /// /// public static RarArchive Open(IEnumerable streams, ReaderOptions options = null) { streams.CheckNotNull("streams"); return new RarArchive(streams, options ?? new ReaderOptions()); } #if !NO_FILE public static bool IsRarFile(string filePath) { return IsRarFile(new FileInfo(filePath)); } public static bool IsRarFile(FileInfo fileInfo) { if (!fileInfo.Exists) { return false; } using (Stream stream = fileInfo.OpenRead()) { return IsRarFile(stream); } } #endif public static bool IsRarFile(Stream stream, ReaderOptions options = null) { try { MarkHeader.Read(stream, true, false); return true; } catch { return false; } } #endregion } }