/// <summary> /// Decompresses bytes for one file from an archive or archive chain, /// checking the crc at the end. /// </summary> private void UnpackFileBytes( IUnpackStreamContext streamContext, string fileName, long compressedSize, long uncompressedSize, uint crc, Stream fileStream, Converter <Stream, Stream> compressionStreamCreator, ref Stream archiveStream) { CrcStream crcStream = new CrcStream(fileStream); ConcatStream concatStream = new ConcatStream( delegate(ConcatStream s) { this.currentArchiveBytesProcessed = s.Source.Position; streamContext.CloseArchiveReadStream( this.currentArchiveNumber, String.Empty, s.Source); this.currentArchiveNumber--; this.OnProgress(ArchiveProgressType.FinishArchive); this.currentArchiveNumber += 2; this.currentArchiveName = null; this.currentArchiveBytesProcessed = 0; this.currentArchiveTotalBytes = 0; s.Source = this.OpenArchive(streamContext, this.currentArchiveNumber); FileStream archiveFileStream = s.Source as FileStream; this.currentArchiveName = (archiveFileStream != null ? Path.GetFileName(archiveFileStream.Name) : null); this.currentArchiveTotalBytes = s.Source.Length; this.currentArchiveNumber--; this.OnProgress(ArchiveProgressType.StartArchive); this.currentArchiveNumber++; }); concatStream.Source = archiveStream; concatStream.SetLength(compressedSize); Stream decompressionStream = compressionStreamCreator(concatStream); try { byte[] buf = new byte[4096]; long bytesRemaining = uncompressedSize; int counter = 0; while (bytesRemaining > 0) { int count = (int)Math.Min(buf.Length, bytesRemaining); count = decompressionStream.Read(buf, 0, count); crcStream.Write(buf, 0, count); bytesRemaining -= count; this.fileBytesProcessed += count; this.currentFileBytesProcessed += count; this.currentArchiveBytesProcessed = concatStream.Source.Position; if (++counter % 16 == 0) // Report every 64K { this.currentArchiveNumber--; this.OnProgress(ArchiveProgressType.PartialFile); this.currentArchiveNumber++; } } } finally { archiveStream = concatStream.Source; } crcStream.Flush(); if (crcStream.Crc != crc) { throw new ZipException("CRC check failed for file: " + fileName); } }
/// <summary> /// Decompresses bytes for one file from an archive or archive chain, /// checking the crc at the end. /// </summary> private void UnpackFileBytes( IUnpackStreamContext streamContext, string fileName, long compressedSize, long uncompressedSize, uint crc, Stream fileStream, Converter<Stream, Stream> compressionStreamCreator, ref Stream archiveStream) { CrcStream crcStream = new CrcStream(fileStream); ConcatStream concatStream = new ConcatStream( delegate(ConcatStream s) { this.currentArchiveBytesProcessed = s.Source.Position; streamContext.CloseArchiveReadStream( this.currentArchiveNumber, String.Empty, s.Source); this.currentArchiveNumber--; this.OnProgress(ArchiveProgressType.FinishArchive); this.currentArchiveNumber += 2; this.currentArchiveName = null; this.currentArchiveBytesProcessed = 0; this.currentArchiveTotalBytes = 0; s.Source = this.OpenArchive(streamContext, this.currentArchiveNumber); FileStream archiveFileStream = s.Source as FileStream; this.currentArchiveName = (archiveFileStream != null ? Path.GetFileName(archiveFileStream.Name) : null); this.currentArchiveTotalBytes = s.Source.Length; this.currentArchiveNumber--; this.OnProgress(ArchiveProgressType.StartArchive); this.currentArchiveNumber++; }); concatStream.Source = archiveStream; concatStream.SetLength(compressedSize); Stream decompressionStream = compressionStreamCreator(concatStream); try { byte[] buf = new byte[4096]; long bytesRemaining = uncompressedSize; int counter = 0; while (bytesRemaining > 0) { int count = (int) Math.Min(buf.Length, bytesRemaining); count = decompressionStream.Read(buf, 0, count); crcStream.Write(buf, 0, count); bytesRemaining -= count; this.fileBytesProcessed += count; this.currentFileBytesProcessed += count; this.currentArchiveBytesProcessed = concatStream.Source.Position; if (++counter % 16 == 0) // Report every 64K { this.currentArchiveNumber--; this.OnProgress(ArchiveProgressType.PartialFile); this.currentArchiveNumber++; } } } finally { archiveStream = concatStream.Source; } crcStream.Flush(); if (crcStream.Crc != crc) { throw new ZipException("CRC check failed for file: " + fileName); } }