diff --git a/.gitignore b/.gitignore
index 71f2a07a..2d1bf74c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ _ReSharper.SharpCompress/
bin/
*.suo
TestArchives/Scratch/
+TestArchives/Scratch2/
diff --git a/SharpCompress/Archive/GZip/GZipArchiveEntry.cs b/SharpCompress/Archive/GZip/GZipArchiveEntry.cs
index 6f1aa028..f6a7ce22 100644
--- a/SharpCompress/Archive/GZip/GZipArchiveEntry.cs
+++ b/SharpCompress/Archive/GZip/GZipArchiveEntry.cs
@@ -17,7 +17,7 @@ namespace SharpCompress.Archive.GZip
public virtual Stream OpenEntryStream()
{
- return Parts.Single().GetStream();
+ return Parts.Single().GetCompressedStream();
}
#region IArchiveEntry Members
diff --git a/SharpCompress/Archive/Rar/FileInfoRarFilePart.cs b/SharpCompress/Archive/Rar/FileInfoRarFilePart.cs
index 5c58d686..22d75a9b 100644
--- a/SharpCompress/Archive/Rar/FileInfoRarFilePart.cs
+++ b/SharpCompress/Archive/Rar/FileInfoRarFilePart.cs
@@ -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;
diff --git a/SharpCompress/Archive/Rar/SeekableStreamFilePart.cs b/SharpCompress/Archive/Rar/SeekableStreamFilePart.cs
index 02e8f030..eaff37c2 100644
--- a/SharpCompress/Archive/Rar/SeekableStreamFilePart.cs
+++ b/SharpCompress/Archive/Rar/SeekableStreamFilePart.cs
@@ -18,7 +18,7 @@ namespace SharpCompress.Archive.Rar
private set;
}
- internal override Stream GetStream()
+ internal override Stream GetCompressedStream()
{
Stream.Position = FileHeader.DataStartPosition;
return Stream;
diff --git a/SharpCompress/Archive/SevenZip/SevenZipArchiveEntry.cs b/SharpCompress/Archive/SevenZip/SevenZipArchiveEntry.cs
index 1177e112..fff4644b 100644
--- a/SharpCompress/Archive/SevenZip/SevenZipArchiveEntry.cs
+++ b/SharpCompress/Archive/SevenZip/SevenZipArchiveEntry.cs
@@ -17,7 +17,7 @@ namespace SharpCompress.Archive.SevenZip
public Stream OpenEntryStream()
{
- return Parts.Single().GetStream();
+ return Parts.Single().GetCompressedStream();
}
public void WriteTo(Stream stream)
diff --git a/SharpCompress/Archive/Tar/TarArchiveEntry.cs b/SharpCompress/Archive/Tar/TarArchiveEntry.cs
index f462e41e..d3f0ac72 100644
--- a/SharpCompress/Archive/Tar/TarArchiveEntry.cs
+++ b/SharpCompress/Archive/Tar/TarArchiveEntry.cs
@@ -16,7 +16,7 @@ namespace SharpCompress.Archive.Tar
public virtual Stream OpenEntryStream()
{
- return Parts.Single().GetStream();
+ return Parts.Single().GetCompressedStream();
}
#region IArchiveEntry Members
diff --git a/SharpCompress/Archive/Zip/ZipArchiveEntry.cs b/SharpCompress/Archive/Zip/ZipArchiveEntry.cs
index ea52408c..1acd6a1a 100644
--- a/SharpCompress/Archive/Zip/ZipArchiveEntry.cs
+++ b/SharpCompress/Archive/Zip/ZipArchiveEntry.cs
@@ -16,7 +16,7 @@ namespace SharpCompress.Archive.Zip
public virtual Stream OpenEntryStream()
{
- return Parts.Single().GetStream();
+ return Parts.Single().GetCompressedStream();
}
#region IArchiveEntry Members
diff --git a/SharpCompress/Common/Entry.cs b/SharpCompress/Common/Entry.cs
index c60ecdb9..7637a36a 100644
--- a/SharpCompress/Common/Entry.cs
+++ b/SharpCompress/Common/Entry.cs
@@ -5,6 +5,8 @@ namespace SharpCompress.Common
{
public abstract class Entry : SharpCompress.Common.IEntry
{
+ internal bool IsSolid { get; set; }
+
///
/// The File's 32 bit CRC Hash
///
diff --git a/SharpCompress/Common/FilePart.cs b/SharpCompress/Common/FilePart.cs
index 6adc6db3..29d7b9fe 100644
--- a/SharpCompress/Common/FilePart.cs
+++ b/SharpCompress/Common/FilePart.cs
@@ -9,6 +9,7 @@ namespace SharpCompress.Common
get;
}
- internal abstract Stream GetStream();
+ internal abstract Stream GetCompressedStream();
+ internal abstract Stream GetRawStream();
}
}
diff --git a/SharpCompress/Common/GZip/GZipFilePart.cs b/SharpCompress/Common/GZip/GZipFilePart.cs
index db79efa0..b1025c0a 100644
--- a/SharpCompress/Common/GZip/GZipFilePart.cs
+++ b/SharpCompress/Common/GZip/GZipFilePart.cs
@@ -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();
@@ -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();
diff --git a/SharpCompress/Common/Rar/RarFilePart.cs b/SharpCompress/Common/Rar/RarFilePart.cs
index 4d62042f..2b7aa27d 100644
--- a/SharpCompress/Common/Rar/RarFilePart.cs
+++ b/SharpCompress/Common/Rar/RarFilePart.cs
@@ -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;
+ }
}
}
diff --git a/SharpCompress/Common/SevenZip/SevenZipFilePart.cs b/SharpCompress/Common/SevenZip/SevenZipFilePart.cs
index 5a881106..5cd02bc1 100644
--- a/SharpCompress/Common/SevenZip/SevenZipFilePart.cs
+++ b/SharpCompress/Common/SevenZip/SevenZipFilePart.cs
@@ -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
diff --git a/SharpCompress/Common/Tar/TarFilePart.cs b/SharpCompress/Common/Tar/TarFilePart.cs
index 51ddce26..7fd69c3c 100644
--- a/SharpCompress/Common/Tar/TarFilePart.cs
+++ b/SharpCompress/Common/Tar/TarFilePart.cs
@@ -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;
+ }
}
}
diff --git a/SharpCompress/Common/Zip/SeekableZipFilePart.cs b/SharpCompress/Common/Zip/SeekableZipFilePart.cs
index e40e600f..72035742 100644
--- a/SharpCompress/Common/Zip/SeekableZipFilePart.cs
+++ b/SharpCompress/Common/Zip/SeekableZipFilePart.cs
@@ -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
diff --git a/SharpCompress/Common/Zip/StreamingZipFilePart.cs b/SharpCompress/Common/Zip/StreamingZipFilePart.cs
index 849998e2..26ae58f4 100644
--- a/SharpCompress/Common/Zip/StreamingZipFilePart.cs
+++ b/SharpCompress/Common/Zip/StreamingZipFilePart.cs
@@ -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();
diff --git a/SharpCompress/Common/Zip/ZipFilePart.cs b/SharpCompress/Common/Zip/ZipFilePart.cs
index f69a190d..99057598 100644
--- a/SharpCompress/Common/Zip/ZipFilePart.cs
+++ b/SharpCompress/Common/Zip/ZipFilePart.cs
@@ -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
diff --git a/SharpCompress/Compressor/Rar/MultiVolumeReadOnlyStream.cs b/SharpCompress/Compressor/Rar/MultiVolumeReadOnlyStream.cs
index 0b51e0de..28c0425e 100644
--- a/SharpCompress/Compressor/Rar/MultiVolumeReadOnlyStream.cs
+++ b/SharpCompress/Compressor/Rar/MultiVolumeReadOnlyStream.cs
@@ -55,7 +55,7 @@ namespace SharpCompress.Compressor.Rar
{
currentStream.Dispose();
}
- currentStream = filePartEnumerator.Current.GetStream();
+ currentStream = filePartEnumerator.Current.GetCompressedStream();
currentPartTotalReadBytes = 0;
diff --git a/SharpCompress/Reader/AbstractReader.cs b/SharpCompress/Reader/AbstractReader.cs
index a19255be..62880144 100644
--- a/SharpCompress/Reader/AbstractReader.cs
+++ b/SharpCompress/Reader/AbstractReader.cs
@@ -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
diff --git a/SharpCompress/Reader/Rar/NonSeekableStreamFilePart.cs b/SharpCompress/Reader/Rar/NonSeekableStreamFilePart.cs
index c40edf39..c2c43977 100644
--- a/SharpCompress/Reader/Rar/NonSeekableStreamFilePart.cs
+++ b/SharpCompress/Reader/Rar/NonSeekableStreamFilePart.cs
@@ -11,7 +11,7 @@ namespace SharpCompress.Reader.Rar
{
}
- internal override Stream GetStream()
+ internal override Stream GetCompressedStream()
{
return FileHeader.PackedStream;
}
diff --git a/SharpCompress/Reader/Rar/RarReaderEntry.cs b/SharpCompress/Reader/Rar/RarReaderEntry.cs
index 53e392a3..810a1c6f 100644
--- a/SharpCompress/Reader/Rar/RarReaderEntry.cs
+++ b/SharpCompress/Reader/Rar/RarReaderEntry.cs
@@ -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 Parts