using System.Collections.Generic; using System.IO; using System.Linq; using SharpCompress.Common; using SharpCompress.Common.Rar; namespace SharpCompress.Reader.Rar { internal class MultiVolumeRarReader : RarReader { private readonly IEnumerator streams; private Stream tempStream; internal MultiVolumeRarReader(IEnumerable streams, Options options) : base(options) { this.streams = streams.GetEnumerator(); } internal override void ValidateArchive(RarVolume archive) { } internal override Stream RequestInitialStream() { if (streams.MoveNext()) { return streams.Current; } throw new MultiVolumeExtractionException("No stream provided when requested by MultiVolumeRarReader"); } internal override bool NextEntryForCurrentStream() { if (!base.NextEntryForCurrentStream()) { //if we're got another stream to try to process then do so if (streams.MoveNext() && LoadStreamForReading(streams.Current)) { return true; } return false; } return true; } protected override IEnumerable CreateFilePartEnumerableForCurrentEntry() { var enumerator = new MultiVolumeStreamEnumerator(this, streams, tempStream); tempStream = null; return enumerator; } private class MultiVolumeStreamEnumerator : IEnumerable, IEnumerator { private readonly MultiVolumeRarReader reader; private readonly IEnumerator nextReadableStreams; private Stream tempStream; private bool isFirst = true; internal MultiVolumeStreamEnumerator(MultiVolumeRarReader r, IEnumerator nextReadableStreams, Stream tempStream) { reader = r; this.nextReadableStreams = nextReadableStreams; this.tempStream = tempStream; } public IEnumerator GetEnumerator() { return this; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this; } public FilePart Current { get; private set; } public void Dispose() { } object System.Collections.IEnumerator.Current { get { return Current; } } public bool MoveNext() { if (isFirst) { Current = reader.Entry.Parts.First(); isFirst = false; //first stream already to go return true; } if (!reader.Entry.IsSplit) { return false; } if (tempStream != null) { reader.LoadStreamForReading(tempStream); tempStream = null; } else if (!nextReadableStreams.MoveNext()) { throw new MultiVolumeExtractionException("No stream provided when requested by MultiVolumeRarReader"); } else { reader.LoadStreamForReading(nextReadableStreams.Current); } Current = reader.Entry.Parts.First(); return true; } public void Reset() { } } } }