123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using SharpCompress.Common.Rar.Headers;
- using SharpCompress.IO;
- using SharpCompress.Readers;
- namespace SharpCompress.Common.Rar
- {
- /// <summary>
- /// A RarArchiveVolume is a single rar file that may or may not be a split RarArchive. A Rar Archive is one to many Rar Parts
- /// </summary>
- public abstract class RarVolume : Volume
- {
- private readonly RarHeaderFactory _headerFactory;
- internal RarVolume(StreamingMode mode, Stream stream, ReaderOptions options)
- : base(stream, options)
- {
- _headerFactory = new RarHeaderFactory(mode, options);
- }
- internal ArchiveHeader ArchiveHeader { get; private set; }
- internal StreamingMode Mode => _headerFactory.StreamingMode;
- internal abstract IEnumerable<RarFilePart> ReadFileParts();
- internal abstract RarFilePart CreateFilePart(MarkHeader markHeader, FileHeader fileHeader);
- internal IEnumerable<RarFilePart> GetVolumeFileParts()
- {
- MarkHeader lastMarkHeader = null;
- foreach (var header in _headerFactory.ReadHeaders(Stream))
- {
- switch (header.HeaderType)
- {
- case HeaderType.Mark:
- {
- lastMarkHeader = header as MarkHeader;
- }
- break;
- case HeaderType.Archive:
- {
- ArchiveHeader = header as ArchiveHeader;
- }
- break;
- case HeaderType.File:
- {
- var fh = header as FileHeader;
- yield return CreateFilePart(lastMarkHeader, fh);
- }
- break;
- }
- }
- }
- private void EnsureArchiveHeaderLoaded()
- {
- if (ArchiveHeader == null)
- {
- if (Mode == StreamingMode.Streaming)
- {
- throw new InvalidOperationException("ArchiveHeader should never been null in a streaming read.");
- }
- // we only want to load the archive header to avoid overhead but have to do the nasty thing and reset the stream
- GetVolumeFileParts().First();
- Stream.Position = 0;
- }
- }
- /// <summary>
- /// RarArchive is the first volume of a multi-part archive.
- /// Only Rar 3.0 format and higher
- /// </summary>
- public override bool IsFirstVolume
- {
- get
- {
- EnsureArchiveHeaderLoaded();
- return ArchiveHeader.IsFirstVolume;
- }
- }
- /// <summary>
- /// RarArchive is part of a multi-part archive.
- /// </summary>
- public override bool IsMultiVolume
- {
- get
- {
- EnsureArchiveHeaderLoaded();
- return ArchiveHeader.IsVolume;
- }
- }
- /// <summary>
- /// RarArchive is SOLID (this means the Archive saved bytes by reusing information which helps for archives containing many small files).
- /// Currently, SharpCompress cannot decompress SOLID archives.
- /// </summary>
- public bool IsSolidArchive
- {
- get
- {
- EnsureArchiveHeaderLoaded();
- return ArchiveHeader.IsSolid;
- }
- }
- }
- }
|