Example #1
0
        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;
        }
Example #2
0
        /// <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;
        }