public bool ExtractFile(ZipFileEntry _zfe, Stream _stream)
{
if (!_stream.CanWrite)
throw new InvalidOperationException("Stream cannot be written");
// check signature
byte[] signature = new byte[4];
this.ZipFileStream.Seek(_zfe.HeaderOffset, SeekOrigin.Begin);
this.ZipFileStream.Read(signature, 0, 4);
if (BitConverter.ToUInt32(signature, 0) != 0x04034b50)
return false;
// Select input stream for inflating or just reading
Stream inStream;
if (_zfe.Method == Compression.Store)
inStream = this.ZipFileStream;
else if (_zfe.Method == Compression.Deflate)
inStream = new DeflateStream(this.ZipFileStream, CompressionMode.Decompress, true);
else
return false;
// Buffered copy
byte[] buffer = new byte[16384];
this.ZipFileStream.Seek(_zfe.FileOffset, SeekOrigin.Begin);
uint bytesPending = _zfe.FileSize;
uint crc32 = 0 ^ 0xffffffff;
while (bytesPending > 0)
{
int bytesRead = inStream.Read(buffer, 0, (int)Math.Min(bytesPending, buffer.Length));
_stream.Write(buffer, 0, bytesRead);
for (uint i = 0; i < bytesRead; i++)
{
crc32 = ZipStorer.CrcTable[(crc32 ^ buffer[i]) & 0xFF] ^ (crc32 >> 8);
}
bytesPending -= (uint)bytesRead;
}
_stream.Flush();
crc32 ^= 0xffffffff;
if (_zfe.Method == Compression.Deflate)
inStream.Dispose();
return crc32 == _zfe.Crc32;
}