Skip to content

Commit

Permalink
Merge pull request #682 from adamhathcock/RarFileVolIdx_RarArcVer_GzCrc
Browse files Browse the repository at this point in the history
  • Loading branch information
adamhathcock committed Jul 16, 2022
2 parents 4c46cd7 + 574a093 commit c73a8cb
Show file tree
Hide file tree
Showing 28 changed files with 231 additions and 70 deletions.
3 changes: 2 additions & 1 deletion src/SharpCompress/Archives/GZip/GZipArchive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ internal GZipArchive(SourceStream srcStream)
protected override IEnumerable<GZipVolume> LoadVolumes(SourceStream srcStream)
{
srcStream.LoadAllParts();
return srcStream.Streams.Select(a => new GZipVolume(a, ReaderOptions));
int idx = 0;
return srcStream.Streams.Select(a => new GZipVolume(a, ReaderOptions, idx++));
}
public static bool IsGZipFile(string filePath)
{
Expand Down
6 changes: 3 additions & 3 deletions src/SharpCompress/Archives/Rar/FileInfoRarArchiveVolume.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using SharpCompress.Common.Rar;
Expand All @@ -13,8 +13,8 @@ namespace SharpCompress.Archives.Rar
/// </summary>
internal class FileInfoRarArchiveVolume : RarVolume
{
internal FileInfoRarArchiveVolume(FileInfo fileInfo, ReaderOptions options)
: base(StreamingMode.Seekable, fileInfo.OpenRead(), FixOptions(options))
internal FileInfoRarArchiveVolume(FileInfo fileInfo, ReaderOptions options, int index = 0)
: base(StreamingMode.Seekable, fileInfo.OpenRead(), FixOptions(options), index)
{
FileInfo = fileInfo;
FileParts = GetVolumeFileParts().ToArray().ToReadOnly();
Expand Down
4 changes: 2 additions & 2 deletions src/SharpCompress/Archives/Rar/FileInfoRarFilePart.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using System.IO;
using System.IO;
using SharpCompress.Common.Rar.Headers;

namespace SharpCompress.Archives.Rar
{
internal sealed class FileInfoRarFilePart : SeekableFilePart
{
internal FileInfoRarFilePart(FileInfoRarArchiveVolume volume, string? password, MarkHeader mh, FileHeader fh, FileInfo fi)
: base(mh, fh, volume.Stream, password)
: base(mh, fh, volume.Index, volume.Stream, password)
{
FileInfo = fi;
}
Expand Down
8 changes: 6 additions & 2 deletions src/SharpCompress/Archives/Rar/RarArchive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,17 @@ protected override IEnumerable<RarVolume> LoadVolumes(SourceStream srcStream)
{
base.SrcStream.LoadAllParts(); //request all streams
Stream[] streams = base.SrcStream.Streams.ToArray();
int idx = 0;
if (streams.Length > 1 && IsRarFile(streams[1], ReaderOptions)) //test part 2 - true = multipart not split
{
base.SrcStream.IsVolumes = true;
streams[1].Position = 0;
base.SrcStream.Position = 0;

return srcStream.Streams.Select(a => new StreamRarArchiveVolume(a, ReaderOptions));
return srcStream.Streams.Select(a => new StreamRarArchiveVolume(a, ReaderOptions, idx++));
}
else //split mode or single file
return new StreamRarArchiveVolume(base.SrcStream, ReaderOptions).AsEnumerable();
return new StreamRarArchiveVolume(base.SrcStream, ReaderOptions, idx++).AsEnumerable();
}

protected override IReader CreateReaderForSolidExtraction()
Expand All @@ -58,6 +59,9 @@ protected override IReader CreateReaderForSolidExtraction()

public override bool IsSolid => Volumes.First().IsSolidArchive;

public virtual int MinVersion => Volumes.First().MinVersion;
public virtual int MaxVersion => Volumes.First().MaxVersion;

#region Creation
/// <summary>
/// Constructor with a FileInfo object to an existing file.
Expand Down
2 changes: 1 addition & 1 deletion src/SharpCompress/Archives/Rar/RarArchiveEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,4 @@ private void CheckIncomplete()
}
}
}
}
}
8 changes: 4 additions & 4 deletions src/SharpCompress/Archives/Rar/SeekableFilePart.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.IO;
using System.IO;
using SharpCompress.Common.Rar;
using SharpCompress.Common.Rar.Headers;

Expand All @@ -9,8 +9,8 @@ internal class SeekableFilePart : RarFilePart
private readonly Stream stream;
private readonly string? password;

internal SeekableFilePart(MarkHeader mh, FileHeader fh, Stream stream, string? password)
: base(mh, fh)
internal SeekableFilePart(MarkHeader mh, FileHeader fh, int index, Stream stream, string? password)
: base(mh, fh, index)
{
this.stream = stream;
this.password = password;
Expand All @@ -28,4 +28,4 @@ internal override Stream GetCompressedStream()

internal override string FilePartName => "Unknown Stream - File Entry: " + FileHeader.FileName;
}
}
}
10 changes: 5 additions & 5 deletions src/SharpCompress/Archives/Rar/StreamRarArchiveVolume.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using SharpCompress.Common.Rar;
using SharpCompress.Common.Rar.Headers;
Expand All @@ -9,8 +9,8 @@ namespace SharpCompress.Archives.Rar
{
internal class StreamRarArchiveVolume : RarVolume
{
internal StreamRarArchiveVolume(Stream stream, ReaderOptions options)
: base(StreamingMode.Seekable, stream, options)
internal StreamRarArchiveVolume(Stream stream, ReaderOptions options, int index = 0)
: base(StreamingMode.Seekable, stream, options, index)
{
}

Expand All @@ -21,7 +21,7 @@ internal override IEnumerable<RarFilePart> ReadFileParts()

internal override RarFilePart CreateFilePart(MarkHeader markHeader, FileHeader fileHeader)
{
return new SeekableFilePart(markHeader, fileHeader, Stream, ReaderOptions.Password);
return new SeekableFilePart(markHeader, fileHeader, this.Index, Stream, ReaderOptions.Password);
}
}
}
}
3 changes: 2 additions & 1 deletion src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ internal SevenZipArchive(SourceStream srcStream)
protected override IEnumerable<SevenZipVolume> LoadVolumes(SourceStream srcStream)
{
base.SrcStream.LoadAllParts(); //request all streams
return new SevenZipVolume(srcStream, ReaderOptions).AsEnumerable(); //simple single volume or split, multivolume not supported
int idx = 0;
return new SevenZipVolume(srcStream, ReaderOptions, idx++).AsEnumerable(); //simple single volume or split, multivolume not supported
}

public static bool IsSevenZipFile(string filePath)
Expand Down
3 changes: 2 additions & 1 deletion src/SharpCompress/Archives/Tar/TarArchive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ public static bool IsTarFile(Stream stream)
protected override IEnumerable<TarVolume> LoadVolumes(SourceStream srcStream)
{
base.SrcStream.LoadAllParts(); //request all streams
return new TarVolume(srcStream, ReaderOptions).AsEnumerable(); //simple single volume or split, multivolume not supported
int idx = 0;
return new TarVolume(srcStream, ReaderOptions, idx++).AsEnumerable(); //simple single volume or split, multivolume not supported
}

/// <summary>
Expand Down
5 changes: 3 additions & 2 deletions src/SharpCompress/Archives/Zip/ZipArchive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ protected override IEnumerable<ZipVolume> LoadVolumes(SourceStream srcStream)
base.SrcStream.Position = 0;

List<Stream> streams = base.SrcStream.Streams.ToList();
int idx = 0;
if (streams.Count > 1) //test part 2 - true = multipart not split
{
streams[1].Position += 4; //skip the POST_DATA_DESCRIPTOR to prevent an exception
Expand All @@ -182,12 +183,12 @@ protected override IEnumerable<ZipVolume> LoadVolumes(SourceStream srcStream)
streams.Add(tmp);

//streams[0].Position = 4; //skip the POST_DATA_DESCRIPTOR to prevent an exception
return streams.Select(a => new ZipVolume(a, ReaderOptions));
return streams.Select(a => new ZipVolume(a, ReaderOptions, idx++));
}
}

//split mode or single file
return new ZipVolume(base.SrcStream, ReaderOptions).AsEnumerable();
return new ZipVolume(base.SrcStream, ReaderOptions, idx++).AsEnumerable();
}

internal ZipArchive()
Expand Down
5 changes: 4 additions & 1 deletion src/SharpCompress/Common/Entry.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SharpCompress.Common
{
Expand Down Expand Up @@ -70,6 +71,8 @@ public abstract class Entry : IEntry
/// </summary>
public abstract bool IsSplitAfter { get; }

public int VolumeIndexFirst => this.Parts?.FirstOrDefault()?.Index ?? 0;
public int VolumeIndexLast => this.Parts?.LastOrDefault()?.Index ?? 0;
/// <inheritdoc/>
public override string ToString() => Key;

Expand Down
3 changes: 2 additions & 1 deletion src/SharpCompress/Common/FilePart.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.IO;
using System.IO;

namespace SharpCompress.Common
{
Expand All @@ -12,6 +12,7 @@ protected FilePart(ArchiveEncoding archiveEncoding)
internal ArchiveEncoding ArchiveEncoding { get; }

internal abstract string FilePartName { get; }
public int Index { get; set; }

internal abstract Stream GetCompressedStream();
internal abstract Stream? GetRawStream();
Expand Down
10 changes: 5 additions & 5 deletions src/SharpCompress/Common/GZip/GZipFilePart.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
Expand Down Expand Up @@ -31,8 +31,8 @@ internal GZipFilePart(Stream stream, ArchiveEncoding archiveEncoding)
internal long EntryStartPosition { get; }

internal DateTime? DateModified { get; private set; }
internal int? Crc { get; private set; }
internal int? UncompressedSize { get; private set; }
internal uint? Crc { get; private set; }
internal uint? UncompressedSize { get; private set; }

internal override string FilePartName => _name!;

Expand All @@ -52,8 +52,8 @@ private void ReadTrailer()
Span<byte> trailer = stackalloc byte[8];
int n = _stream.Read(trailer);

Crc = BinaryPrimitives.ReadInt32LittleEndian(trailer);
UncompressedSize = BinaryPrimitives.ReadInt32LittleEndian(trailer.Slice(4));
Crc = BinaryPrimitives.ReadUInt32LittleEndian(trailer);
UncompressedSize = BinaryPrimitives.ReadUInt32LittleEndian(trailer.Slice(4));
}

private void ReadAndValidateGzipHeader()
Expand Down
8 changes: 4 additions & 4 deletions src/SharpCompress/Common/GZip/GZipVolume.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using System.IO;
using System.IO;
using SharpCompress.Readers;

namespace SharpCompress.Common.GZip
{
public class GZipVolume : Volume
{
public GZipVolume(Stream stream, ReaderOptions options)
: base(stream, options)
public GZipVolume(Stream stream, ReaderOptions options, int index = 0)
: base(stream, options, index)
{
}

Expand All @@ -20,4 +20,4 @@ public GZipVolume(FileInfo fileInfo, ReaderOptions options)

public override bool IsMultiVolume => true;
}
}
}
7 changes: 5 additions & 2 deletions src/SharpCompress/Common/IEntry.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System;
using System.Collections.Generic;

namespace SharpCompress.Common
{
Expand All @@ -15,9 +16,11 @@ public interface IEntry
bool IsEncrypted { get; }
bool IsSplitAfter { get; }
bool IsSolid { get; }
int VolumeIndexFirst { get; }
int VolumeIndexLast { get; }
DateTime? LastAccessedTime { get; }
DateTime? LastModifiedTime { get; }
long Size { get; }
int? Attrib { get; }
}
}
}
7 changes: 5 additions & 2 deletions src/SharpCompress/Common/IVolume.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System;
using System;

namespace SharpCompress.Common
{
public interface IVolume : IDisposable
{
int Index { get; }

string FileName { get; }
}
}
}
7 changes: 4 additions & 3 deletions src/SharpCompress/Common/Rar/RarFilePart.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.IO;
using System.IO;
using SharpCompress.Common.Rar.Headers;

namespace SharpCompress.Common.Rar
Expand All @@ -8,11 +8,12 @@ namespace SharpCompress.Common.Rar
/// </summary>
internal abstract class RarFilePart : FilePart
{
internal RarFilePart(MarkHeader mh, FileHeader fh)
internal RarFilePart(MarkHeader mh, FileHeader fh, int index)
: base(fh.ArchiveEncoding)
{
MarkHeader = mh;
FileHeader = fh;
Index = index;
}

internal MarkHeader MarkHeader { get; }
Expand All @@ -24,4 +25,4 @@ internal RarFilePart(MarkHeader mh, FileHeader fh)
return null;
}
}
}
}
43 changes: 39 additions & 4 deletions src/SharpCompress/Common/Rar/RarVolume.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand All @@ -14,9 +14,10 @@ namespace SharpCompress.Common.Rar
public abstract class RarVolume : Volume
{
private readonly RarHeaderFactory _headerFactory;
internal int _maxCompressionAlgorithm;

internal RarVolume(StreamingMode mode, Stream stream, ReaderOptions options)
: base(stream, options)
internal RarVolume(StreamingMode mode, Stream stream, ReaderOptions options, int index = 0)
: base(stream, options, index)
{
_headerFactory = new RarHeaderFactory(mode, options);
}
Expand Down Expand Up @@ -51,6 +52,8 @@ internal IEnumerable<RarFilePart> GetVolumeFileParts()
case HeaderType.File:
{
var fh = (FileHeader)header;
if (_maxCompressionAlgorithm < fh.CompressionAlgorithm)
_maxCompressionAlgorithm = fh.CompressionAlgorithm;
yield return CreateFilePart(lastMarkHeader!, fh);
}
break;
Expand Down Expand Up @@ -110,5 +113,37 @@ public bool IsSolidArchive
return ArchiveHeader.IsSolid;
}
}

public int MinVersion
{
get
{
EnsureArchiveHeaderLoaded();
if (_maxCompressionAlgorithm >= 50)
return 5; //5-6
else if (_maxCompressionAlgorithm >= 29)
return 3; //3-4
else if (_maxCompressionAlgorithm >= 20)
return 2; //2
else
return 1;
}
}

public int MaxVersion
{
get
{
EnsureArchiveHeaderLoaded();
if (_maxCompressionAlgorithm >= 50)
return 6; //5-6
else if (_maxCompressionAlgorithm >= 29)
return 4; //3-4
else if (_maxCompressionAlgorithm >= 20)
return 2; //2
else
return 1;
}
}
}
}
}
Loading

0 comments on commit c73a8cb

Please sign in to comment.