using System.Collections.Generic; using System.IO; using System.Linq; using SharpCompress.Common; using SharpCompress.Common.Rar; using SharpCompress.Compressors.Rar; namespace SharpCompress.Readers.Rar { /// /// This class faciliates Reading a Rar Archive in a non-seekable forward-only manner /// public abstract class RarReader : AbstractReader { private RarVolume volume; internal Lazy UnpackV2017 { get; } = new Lazy(() => new SharpCompress.Compressors.Rar.UnpackV2017.Unpack()); internal Lazy UnpackV1 { get; } = new Lazy(() => new SharpCompress.Compressors.Rar.UnpackV1.Unpack()); internal RarReader(ReaderOptions options) : base(options, ArchiveType.Rar) { } internal abstract void ValidateArchive(RarVolume archive); public override RarVolume Volume => volume; /// /// Opens a RarReader for Non-seeking usage with a single volume /// /// /// /// public static RarReader Open(Stream stream, ReaderOptions options = null) { stream.CheckNotNull("stream"); return new SingleVolumeRarReader(stream, options ?? new ReaderOptions()); } /// /// Opens a RarReader for Non-seeking usage with multiple volumes /// /// /// /// public static RarReader Open(IEnumerable streams, ReaderOptions options = null) { streams.CheckNotNull("streams"); return new MultiVolumeRarReader(streams, options ?? new ReaderOptions()); } protected override IEnumerable GetEntries(Stream stream) { volume = new RarReaderVolume(stream, Options); foreach (RarFilePart fp in volume.ReadFileParts()) { ValidateArchive(volume); yield return new RarReaderEntry(volume.IsSolidArchive, fp); } } protected virtual IEnumerable CreateFilePartEnumerableForCurrentEntry() { return Entry.Parts; } protected override EntryStream GetEntryStream() { var stream = new MultiVolumeReadOnlyStream(CreateFilePartEnumerableForCurrentEntry().Cast(), this); if (Entry.IsRarV3) { return CreateEntryStream(new RarCrcStream(UnpackV1.Value, Entry.FileHeader, stream)); } return CreateEntryStream(new RarCrcStream(UnpackV2017.Value, Entry.FileHeader, stream)); } } }