public void CloseEntry() { if (_curEntry == null) { throw new InvalidOperationException("No open entry"); } long compressedSize = _size; if (_curMethod == CompressionMethod.Deflated) { if (_size >= 0L) { Finish(); compressedSize = Deflater.TotalOut; } else { Deflater.Reset(); } } if (_curEntry.AesKeySize > 0) { BaseOutputStream.Write(AesAuthCode, 0, 10); } if (_curEntry.Size < 0L) { _curEntry.Size = _size; } else if (_curEntry.Size != _size) { throw new ZipException(string.Concat("size was ", _size, ", but I expected ", _curEntry.Size)); } if (_curEntry.CompressedSize < 0L) { _curEntry.CompressedSize = compressedSize; } else if (_curEntry.CompressedSize != compressedSize) { throw new ZipException(string.Concat("compressed size was ", compressedSize, ", but I expected ", _curEntry.CompressedSize)); } if (_curEntry.Crc < 0L) { _curEntry.Crc = _crc.Value; } else if (_curEntry.Crc != _crc.Value) { throw new ZipException(string.Concat("crc was ", _crc.Value, ", but I expected ", _curEntry.Crc)); } _offset += compressedSize; if (_curEntry.IsCrypted) { if (_curEntry.AesKeySize > 0) { _curEntry.CompressedSize += _curEntry.AesOverheadSize; } else { _curEntry.CompressedSize += 12L; } } if (_patchEntryHeader) { _patchEntryHeader = false; long position = BaseOutputStream.Position; BaseOutputStream.Seek(_crcPatchPos, SeekOrigin.Begin); WriteLeInt((int)_curEntry.Crc); if (_curEntry.LocalHeaderRequiresZip64) { if (_sizePatchPos == -1L) { throw new ZipException("Entry requires zip64 but this has been turned off"); } BaseOutputStream.Seek(_sizePatchPos, SeekOrigin.Begin); WriteLeLong(_curEntry.Size); WriteLeLong(_curEntry.CompressedSize); } else { WriteLeInt((int)_curEntry.CompressedSize); WriteLeInt((int)_curEntry.Size); } BaseOutputStream.Seek(position, SeekOrigin.Begin); } if ((_curEntry.Flags & 8) != 0) { WriteLeInt(ZipConstants.DataDescriptorSignature); WriteLeInt((int)_curEntry.Crc); if (_curEntry.LocalHeaderRequiresZip64) { WriteLeLong(_curEntry.CompressedSize); WriteLeLong(_curEntry.Size); _offset += 0x18L; } else { WriteLeInt((int)_curEntry.CompressedSize); WriteLeInt((int)_curEntry.Size); _offset += 0x10L; } } _entries.Add(_curEntry); _curEntry = null; }
/// <summary> /// Closes the current entry, updating header and footer information as required /// </summary> /// <exception cref="System.IO.IOException"> /// An I/O error occurs. /// </exception> /// <exception cref="System.InvalidOperationException"> /// No entry is active. /// </exception> public void CloseEntry() { if (curEntry == null) { throw new InvalidOperationException("No open entry"); } long csize = size; // First finish the deflater, if appropriate if (curMethod == CompressionMethod.Deflated) { if (size >= 0) { base.Finish(); csize = Deflater.TotalOut; } else { Deflater.Reset(); } } if (curEntry.Size < 0) { curEntry.Size = size; } else if (curEntry.Size != size) { throw new ZipException("size was " + size + ", but I expected " + curEntry.Size); } if (curEntry.CompressedSize < 0) { curEntry.CompressedSize = csize; } else if (curEntry.CompressedSize != csize) { throw new ZipException("compressed size was " + csize + ", but I expected " + curEntry.CompressedSize); } if (curEntry.Crc < 0) { curEntry.Crc = crc.Value; } else if (curEntry.Crc != crc.Value) { throw new ZipException("crc was " + crc.Value + ", but I expected " + curEntry.Crc); } offset += csize; if (curEntry.IsCrypted) { if (curEntry.AESKeySize > 0) { curEntry.CompressedSize += curEntry.AESOverheadSize; } else { curEntry.CompressedSize += ZipConstants.CryptoHeaderSize; } } // Patch the header if possible if (patchEntryHeader) { patchEntryHeader = false; long curPos = BaseOutputStream.Position; BaseOutputStream.Seek(crcPatchPos, SeekOrigin.Begin); WriteLeInt((int)curEntry.Crc); if (curEntry.LocalHeaderRequiresZip64) { if (sizePatchPos == -1) { throw new ZipException("Entry requires zip64 but this has been turned off"); } BaseOutputStream.Seek(sizePatchPos, SeekOrigin.Begin); WriteLeLong(curEntry.Size); WriteLeLong(curEntry.CompressedSize); } else { WriteLeInt((int)curEntry.CompressedSize); WriteLeInt((int)curEntry.Size); } BaseOutputStream.Seek(curPos, SeekOrigin.Begin); } // Add data descriptor if flagged as required if ((curEntry.Flags & 8) != 0) { WriteLeInt(ZipConstants.DataDescriptorSignature); WriteLeInt(unchecked ((int)curEntry.Crc)); if (curEntry.LocalHeaderRequiresZip64) { WriteLeLong(curEntry.CompressedSize); WriteLeLong(curEntry.Size); offset += ZipConstants.Zip64DataDescriptorSize; } else { WriteLeInt((int)curEntry.CompressedSize); WriteLeInt((int)curEntry.Size); offset += ZipConstants.DataDescriptorSize; } } entries.Add(curEntry); curEntry = null; }