in src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs [502:594]
internal void WriteEntryFooter(Stream stream)
{
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();
}
}
else if (curMethod == CompressionMethod.Stored)
{
// This is done by Finish() for Deflated entries, but we need to do it
// ourselves for Stored ones
base.GetAuthCodeIfAES();
}
// Write the AES Authentication Code (a hash of the compressed and encrypted data)
if (curEntry.AESKeySize > 0)
{
stream.Write(AESAuthCode, 0, 10);
// Always use 0 as CRC for AE-2 format
curEntry.Crc = 0;
}
else
{
if (curEntry.Crc < 0)
{
curEntry.Crc = crc.Value;
}
else if (curEntry.Crc != crc.Value)
{
throw new ZipException($"crc was {crc.Value}, but {curEntry.Crc} was expected");
}
}
if (curEntry.Size < 0)
{
curEntry.Size = size;
}
else if (curEntry.Size != size)
{
throw new ZipException($"size was {size}, but {curEntry.Size} was expected");
}
if (curEntry.CompressedSize < 0)
{
curEntry.CompressedSize = csize;
}
else if (curEntry.CompressedSize != csize)
{
throw new ZipException($"compressed size was {csize}, but {curEntry.CompressedSize} expected");
}
offset += csize;
if (curEntry.IsCrypted)
{
curEntry.CompressedSize += curEntry.EncryptionOverheadSize;
}
// Add data descriptor if flagged as required
if ((curEntry.Flags & 8) != 0)
{
stream.WriteLEInt(ZipConstants.DataDescriptorSignature);
stream.WriteLEInt(unchecked((int)curEntry.Crc));
if (curEntry.LocalHeaderRequiresZip64)
{
stream.WriteLELong(curEntry.CompressedSize);
stream.WriteLELong(curEntry.Size);
offset += ZipConstants.Zip64DataDescriptorSize;
}
else
{
stream.WriteLEInt((int)curEntry.CompressedSize);
stream.WriteLEInt((int)curEntry.Size);
offset += ZipConstants.DataDescriptorSize;
}
}
}