2022-06-19 22:05:52 +02:00
|
|
|
using System.IO;
|
2015-12-30 11:19:42 +00:00
|
|
|
using SharpCompress.Common.Zip.Headers;
|
2016-09-26 11:49:49 +01:00
|
|
|
using SharpCompress.Compressors.Deflate;
|
2015-12-30 11:19:42 +00:00
|
|
|
using SharpCompress.IO;
|
|
|
|
|
|
|
|
|
|
namespace SharpCompress.Common.Zip
|
|
|
|
|
{
|
2020-05-23 16:27:55 -07:00
|
|
|
internal sealed class StreamingZipFilePart : ZipFilePart
|
2015-12-30 11:19:42 +00:00
|
|
|
{
|
2020-05-23 16:27:55 -07:00
|
|
|
private Stream? _decompressionStream;
|
2015-12-30 11:19:42 +00:00
|
|
|
|
2022-12-20 13:45:47 +00:00
|
|
|
internal StreamingZipFilePart(ZipFileEntry header, Stream stream) : base(header, stream) { }
|
2015-12-30 11:19:42 +00:00
|
|
|
|
|
|
|
|
protected override Stream CreateBaseStream()
|
|
|
|
|
{
|
|
|
|
|
return Header.PackedStream;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal override Stream GetCompressedStream()
|
|
|
|
|
{
|
|
|
|
|
if (!Header.HasData)
|
|
|
|
|
{
|
|
|
|
|
return Stream.Null;
|
|
|
|
|
}
|
2022-12-20 13:45:47 +00:00
|
|
|
_decompressionStream = CreateDecompressionStream(
|
|
|
|
|
GetCryptoStream(CreateBaseStream()),
|
|
|
|
|
Header.CompressionMethod
|
|
|
|
|
);
|
2015-12-30 11:19:42 +00:00
|
|
|
if (LeaveStreamOpen)
|
|
|
|
|
{
|
2022-06-19 22:05:52 +02:00
|
|
|
return NonDisposingStream.Create(_decompressionStream);
|
2015-12-30 11:19:42 +00:00
|
|
|
}
|
2018-05-06 08:59:00 +01:00
|
|
|
return _decompressionStream;
|
2015-12-30 11:19:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal BinaryReader FixStreamedFileLocation(ref RewindableStream rewindableStream)
|
|
|
|
|
{
|
|
|
|
|
if (Header.IsDirectory)
|
|
|
|
|
{
|
|
|
|
|
return new BinaryReader(rewindableStream);
|
|
|
|
|
}
|
2017-07-17 11:05:21 -04:00
|
|
|
if (Header.HasData && !Skipped)
|
2015-12-30 11:19:42 +00:00
|
|
|
{
|
2020-05-23 16:27:55 -07:00
|
|
|
_decompressionStream ??= GetCompressedStream();
|
2021-01-09 13:33:34 +00:00
|
|
|
|
2022-12-20 13:45:47 +00:00
|
|
|
if (Header.CompressionMethod != ZipCompressionMethod.None)
|
2022-07-28 20:36:28 +02:00
|
|
|
{
|
|
|
|
|
_decompressionStream.Skip();
|
2015-12-30 11:19:42 +00:00
|
|
|
|
2022-08-04 21:22:31 +02:00
|
|
|
// If we had TotalIn / TotalOut we could have used them
|
|
|
|
|
Header.CompressedSize = _decompressionStream.Position;
|
|
|
|
|
|
2022-07-28 20:36:28 +02:00
|
|
|
if (_decompressionStream is DeflateStream deflateStream)
|
|
|
|
|
{
|
|
|
|
|
rewindableStream.Rewind(deflateStream.InputBuffer);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2015-12-30 11:19:42 +00:00
|
|
|
{
|
2022-07-28 20:36:28 +02:00
|
|
|
// We would need to search for the magic word
|
2022-07-28 23:03:06 +02:00
|
|
|
rewindableStream.Position -= 4;
|
|
|
|
|
var pos = rewindableStream.Position;
|
2022-12-20 13:45:47 +00:00
|
|
|
while (Utility.Find(rewindableStream, new byte[] { 0x50, 0x4b, 0x07, 0x08 }))
|
2022-07-28 23:03:06 +02:00
|
|
|
{
|
|
|
|
|
// We should probably check CRC32 for positive matching as well
|
|
|
|
|
var size = rewindableStream.Position - pos;
|
|
|
|
|
var br = new BinaryReader(rewindableStream);
|
|
|
|
|
br.ReadUInt32();
|
|
|
|
|
br.ReadUInt32(); // CRC32
|
|
|
|
|
var compressed_size = br.ReadUInt32();
|
|
|
|
|
var uncompressed_size = br.ReadUInt32();
|
2022-08-04 21:22:31 +02:00
|
|
|
var uncompressed_64bit = br.ReadInt64();
|
|
|
|
|
|
|
|
|
|
long test_64bit = (long)uncompressed_size << 32 | (long)compressed_size;
|
|
|
|
|
|
2022-12-20 13:45:47 +00:00
|
|
|
if (test_64bit == size && test_64bit == uncompressed_64bit)
|
2022-08-04 21:22:31 +02:00
|
|
|
{
|
|
|
|
|
Header.CompressedSize = test_64bit;
|
|
|
|
|
Header.UncompressedSize = uncompressed_64bit;
|
|
|
|
|
rewindableStream.Position -= 24;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-20 13:45:47 +00:00
|
|
|
if (compressed_size == size && compressed_size == uncompressed_size)
|
2022-07-28 23:03:06 +02:00
|
|
|
{
|
2022-08-04 21:22:31 +02:00
|
|
|
Header.CompressedSize = compressed_size;
|
|
|
|
|
Header.UncompressedSize = uncompressed_size;
|
|
|
|
|
rewindableStream.Position -= 24;
|
2022-07-28 23:03:06 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2022-08-04 21:22:31 +02:00
|
|
|
rewindableStream.Position -= 20;
|
2022-07-28 23:03:06 +02:00
|
|
|
}
|
2015-12-30 11:19:42 +00:00
|
|
|
}
|
2022-07-28 20:36:28 +02:00
|
|
|
|
2017-07-17 11:05:21 -04:00
|
|
|
Skipped = true;
|
2015-12-30 11:19:42 +00:00
|
|
|
}
|
|
|
|
|
var reader = new BinaryReader(rewindableStream);
|
2018-05-06 08:59:00 +01:00
|
|
|
_decompressionStream = null;
|
2015-12-30 11:19:42 +00:00
|
|
|
return reader;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-19 22:05:52 +02:00
|
|
|
}
|