mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-24 16:05:27 +00:00
zip/gzip skipping now doesn't involve decompression https://github.com/simmotech/sharpcompress
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,3 +4,4 @@ _ReSharper.SharpCompress/
|
||||
bin/
|
||||
*.suo
|
||||
TestArchives/Scratch/
|
||||
TestArchives/Scratch2/
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace SharpCompress.Archive.GZip
|
||||
|
||||
public virtual Stream OpenEntryStream()
|
||||
{
|
||||
return Parts.Single().GetStream();
|
||||
return Parts.Single().GetCompressedStream();
|
||||
}
|
||||
|
||||
#region IArchiveEntry Members
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace SharpCompress.Archive.Rar
|
||||
private set;
|
||||
}
|
||||
|
||||
internal override Stream GetStream()
|
||||
internal override Stream GetCompressedStream()
|
||||
{
|
||||
var stream = volume.Stream;
|
||||
stream.Position = FileHeader.DataStartPosition;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace SharpCompress.Archive.Rar
|
||||
private set;
|
||||
}
|
||||
|
||||
internal override Stream GetStream()
|
||||
internal override Stream GetCompressedStream()
|
||||
{
|
||||
Stream.Position = FileHeader.DataStartPosition;
|
||||
return Stream;
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace SharpCompress.Archive.SevenZip
|
||||
|
||||
public Stream OpenEntryStream()
|
||||
{
|
||||
return Parts.Single().GetStream();
|
||||
return Parts.Single().GetCompressedStream();
|
||||
}
|
||||
|
||||
public void WriteTo(Stream stream)
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace SharpCompress.Archive.Tar
|
||||
|
||||
public virtual Stream OpenEntryStream()
|
||||
{
|
||||
return Parts.Single().GetStream();
|
||||
return Parts.Single().GetCompressedStream();
|
||||
}
|
||||
|
||||
#region IArchiveEntry Members
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace SharpCompress.Archive.Zip
|
||||
|
||||
public virtual Stream OpenEntryStream()
|
||||
{
|
||||
return Parts.Single().GetStream();
|
||||
return Parts.Single().GetCompressedStream();
|
||||
}
|
||||
|
||||
#region IArchiveEntry Members
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace SharpCompress.Common
|
||||
{
|
||||
public abstract class Entry : SharpCompress.Common.IEntry
|
||||
{
|
||||
internal bool IsSolid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The File's 32 bit CRC Hash
|
||||
/// </summary>
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace SharpCompress.Common
|
||||
get;
|
||||
}
|
||||
|
||||
internal abstract Stream GetStream();
|
||||
internal abstract Stream GetCompressedStream();
|
||||
internal abstract Stream GetRawStream();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,12 @@ namespace SharpCompress.Common.GZip
|
||||
internal class GZipFilePart : FilePart
|
||||
{
|
||||
private string name;
|
||||
private Stream stream;
|
||||
private readonly Stream stream;
|
||||
|
||||
internal GZipFilePart(Stream stream)
|
||||
{
|
||||
ReadAndValidateGzipHeader(stream);
|
||||
this.stream = new DeflateStream(stream, CompressionMode.Decompress, CompressionLevel.Default, false);
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
internal DateTime? DateModified { get; private set; }
|
||||
@@ -24,15 +24,18 @@ namespace SharpCompress.Common.GZip
|
||||
get { return name; }
|
||||
}
|
||||
|
||||
internal override Stream GetStream()
|
||||
internal override Stream GetCompressedStream()
|
||||
{
|
||||
return new DeflateStream(stream, CompressionMode.Decompress, CompressionLevel.Default, false);
|
||||
}
|
||||
|
||||
internal override Stream GetRawStream()
|
||||
{
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
private void ReadAndValidateGzipHeader(Stream stream)
|
||||
{
|
||||
int totalBytesRead = 0;
|
||||
// read the header on the first read
|
||||
byte[] header = new byte[10];
|
||||
int n = stream.Read(header, 0, header.Length);
|
||||
@@ -49,19 +52,18 @@ namespace SharpCompress.Common.GZip
|
||||
|
||||
Int32 timet = BitConverter.ToInt32(header, 4);
|
||||
DateModified = TarHeader.Epoch.AddSeconds(timet);
|
||||
totalBytesRead += n;
|
||||
if ((header[3] & 0x04) == 0x04)
|
||||
{
|
||||
// read and discard extra field
|
||||
n = stream.Read(header, 0, 2); // 2-byte length field
|
||||
totalBytesRead += n;
|
||||
|
||||
Int16 extraLength = (Int16)(header[0] + header[1] * 256);
|
||||
byte[] extra = new byte[extraLength];
|
||||
n = stream.Read(extra, 0, extra.Length);
|
||||
if (n != extraLength)
|
||||
{
|
||||
throw new ZlibException("Unexpected end-of-file reading GZIP header.");
|
||||
totalBytesRead += n;
|
||||
}
|
||||
}
|
||||
if ((header[3] & 0x08) == 0x08)
|
||||
name = ReadZeroTerminatedString(stream);
|
||||
@@ -72,7 +74,7 @@ namespace SharpCompress.Common.GZip
|
||||
}
|
||||
|
||||
|
||||
private string ReadZeroTerminatedString(Stream stream)
|
||||
private static string ReadZeroTerminatedString(Stream stream)
|
||||
{
|
||||
byte[] buf1 = new byte[1];
|
||||
var list = new System.Collections.Generic.List<byte>();
|
||||
@@ -82,13 +84,16 @@ namespace SharpCompress.Common.GZip
|
||||
// workitem 7740
|
||||
int n = stream.Read(buf1, 0, 1);
|
||||
if (n != 1)
|
||||
{
|
||||
throw new ZlibException("Unexpected EOF reading GZIP header.");
|
||||
}
|
||||
if (buf1[0] == 0)
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (buf1[0] == 0)
|
||||
done = true;
|
||||
else
|
||||
list.Add(buf1[0]);
|
||||
list.Add(buf1[0]);
|
||||
}
|
||||
} while (!done);
|
||||
byte[] a = list.ToArray();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using SharpCompress.Common.Rar.Headers;
|
||||
using System.IO;
|
||||
using SharpCompress.Common.Rar.Headers;
|
||||
|
||||
namespace SharpCompress.Common.Rar
|
||||
{
|
||||
@@ -24,5 +25,10 @@ namespace SharpCompress.Common.Rar
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
internal override Stream GetRawStream()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace SharpCompress.Common.SevenZip
|
||||
get { return Header.Name; }
|
||||
}
|
||||
|
||||
internal override Stream GetStream()
|
||||
internal override Stream GetCompressedStream()
|
||||
{
|
||||
if (!Header.HasStream)
|
||||
{
|
||||
@@ -36,6 +36,11 @@ namespace SharpCompress.Common.SevenZip
|
||||
return new ReadOnlySubStream(stream, (long)Header.Size);
|
||||
}
|
||||
|
||||
internal override Stream GetRawStream()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public CompressionType CompressionType
|
||||
{
|
||||
get
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace SharpCompress.Common.Tar
|
||||
get { return Header.Name; }
|
||||
}
|
||||
|
||||
internal override Stream GetStream()
|
||||
internal override Stream GetCompressedStream()
|
||||
{
|
||||
if (seekableStream != null)
|
||||
{
|
||||
@@ -29,5 +29,10 @@ namespace SharpCompress.Common.Tar
|
||||
}
|
||||
return Header.PackedStream;
|
||||
}
|
||||
|
||||
internal override Stream GetRawStream()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,14 +14,14 @@ namespace SharpCompress.Common.Zip
|
||||
this.headerFactory = headerFactory;
|
||||
}
|
||||
|
||||
internal override Stream GetStream()
|
||||
internal override Stream GetCompressedStream()
|
||||
{
|
||||
if (!isLocalHeaderLoaded)
|
||||
{
|
||||
LoadLocalHeader();
|
||||
isLocalHeaderLoaded = true;
|
||||
}
|
||||
return base.GetStream();
|
||||
return base.GetCompressedStream();
|
||||
}
|
||||
|
||||
internal string Comment
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace SharpCompress.Common.Zip
|
||||
return Header.PackedStream;
|
||||
}
|
||||
|
||||
internal override Stream GetStream()
|
||||
internal override Stream GetCompressedStream()
|
||||
{
|
||||
if (!Header.HasData)
|
||||
{
|
||||
@@ -43,7 +43,7 @@ namespace SharpCompress.Common.Zip
|
||||
{
|
||||
if (decompressionStream == null)
|
||||
{
|
||||
decompressionStream = GetStream();
|
||||
decompressionStream = GetCompressedStream();
|
||||
}
|
||||
decompressionStream.SkipAll();
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace SharpCompress.Common.Zip
|
||||
get { return Header.Name; }
|
||||
}
|
||||
|
||||
internal override Stream GetStream()
|
||||
internal override Stream GetCompressedStream()
|
||||
{
|
||||
if (!Header.HasData)
|
||||
{
|
||||
@@ -43,6 +43,15 @@ namespace SharpCompress.Common.Zip
|
||||
return decompressionStream;
|
||||
}
|
||||
|
||||
internal override Stream GetRawStream()
|
||||
{
|
||||
if (!Header.HasData)
|
||||
{
|
||||
return Stream.Null;
|
||||
}
|
||||
return CreateBaseStream();
|
||||
}
|
||||
|
||||
protected abstract Stream CreateBaseStream();
|
||||
|
||||
protected bool LeaveStreamOpen
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace SharpCompress.Compressor.Rar
|
||||
{
|
||||
currentStream.Dispose();
|
||||
}
|
||||
currentStream = filePartEnumerator.Current.GetStream();
|
||||
currentStream = filePartEnumerator.Current.GetCompressedStream();
|
||||
|
||||
currentPartTotalReadBytes = 0;
|
||||
|
||||
|
||||
@@ -136,12 +136,28 @@ namespace SharpCompress.Reader
|
||||
}
|
||||
}
|
||||
|
||||
internal void Skip()
|
||||
readonly byte[] skipBuffer = new byte[4096];
|
||||
|
||||
private void Skip()
|
||||
{
|
||||
var buffer = new byte[4096];
|
||||
using (Stream s = OpenEntryStream())
|
||||
if (!Entry.IsSolid)
|
||||
{
|
||||
while (s.Read(buffer, 0, buffer.Length) > 0)
|
||||
var rawStream = Entry.Parts.First().GetRawStream();
|
||||
|
||||
if (rawStream != null)
|
||||
{
|
||||
var bytesToAdvance = Entry.CompressedSize;
|
||||
for (var i = 0; i < bytesToAdvance / skipBuffer.Length; i++)
|
||||
{
|
||||
rawStream.Read(skipBuffer, 0, skipBuffer.Length);
|
||||
}
|
||||
rawStream.Read(skipBuffer, 0, (int)(bytesToAdvance % skipBuffer.Length));
|
||||
return;
|
||||
}
|
||||
}
|
||||
using (var s = OpenEntryStream())
|
||||
{
|
||||
while (s.Read(skipBuffer, 0, skipBuffer.Length) > 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -183,7 +199,7 @@ namespace SharpCompress.Reader
|
||||
|
||||
protected virtual EntryStream GetEntryStream()
|
||||
{
|
||||
return new EntryStream(Entry.Parts.First().GetStream());
|
||||
return new EntryStream(Entry.Parts.First().GetCompressedStream());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace SharpCompress.Reader.Rar
|
||||
{
|
||||
}
|
||||
|
||||
internal override Stream GetStream()
|
||||
internal override Stream GetCompressedStream()
|
||||
{
|
||||
return FileHeader.PackedStream;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@ namespace SharpCompress.Reader.Rar
|
||||
IsSolid = solid;
|
||||
}
|
||||
|
||||
internal bool IsSolid { get; private set; }
|
||||
|
||||
internal RarFilePart Part { get; private set; }
|
||||
|
||||
internal override IEnumerable<FilePart> Parts
|
||||
|
||||
Reference in New Issue
Block a user