public void PutNextEntry(ZipEntry entry)
{
bool hasCrc;
if (entry == null)
{
throw new ArgumentNullException("entry");
}
if (this.entries == null)
{
throw new InvalidOperationException("ZipOutputStream was finished");
}
if (this.curEntry != null)
{
this.CloseEntry();
}
if (this.entries.Count == 0x7fffffff)
{
throw new ZipException("Too many entries for Zip file");
}
CompressionMethod compressionMethod = entry.CompressionMethod;
int defaultCompressionLevel = this.defaultCompressionLevel;
entry.Flags &= 0x800;
this.patchEntryHeader = false;
if (entry.Size == 0L)
{
entry.CompressedSize = entry.Size;
entry.Crc = 0L;
compressionMethod = CompressionMethod.Stored;
hasCrc = true;
}
else
{
hasCrc = ((entry.Size >= 0L) && entry.HasCrc) && (entry.CompressedSize >= 0L);
if (compressionMethod == CompressionMethod.Stored)
{
if (!hasCrc)
{
if (!base.CanPatchEntries)
{
compressionMethod = CompressionMethod.Deflated;
defaultCompressionLevel = 0;
}
}
else
{
entry.CompressedSize = entry.Size;
hasCrc = entry.HasCrc;
}
}
}
if (!hasCrc)
{
if (!base.CanPatchEntries)
{
entry.Flags |= 8;
}
else
{
this.patchEntryHeader = true;
}
}
if (base.Password != null)
{
entry.IsCrypted = true;
if (entry.Crc < 0L)
{
entry.Flags |= 8;
}
}
entry.Offset = this.offset;
entry.CompressionMethod = compressionMethod;
this.curMethod = compressionMethod;
this.sizePatchPos = -1L;
if ((this.useZip64_ == ICSharpCode.SharpZipLib.Zip.UseZip64.On) || ((entry.Size < 0L) && (this.useZip64_ == ICSharpCode.SharpZipLib.Zip.UseZip64.Dynamic)))
{
entry.ForceZip64();
}
this.WriteLeInt(0x4034b50);
this.WriteLeShort(entry.Version);
this.WriteLeShort(entry.Flags);
this.WriteLeShort((byte) entry.CompressionMethodForHeader);
this.WriteLeInt((int) entry.DosTime);
if (hasCrc)
{
this.WriteLeInt((int) entry.Crc);
if (entry.LocalHeaderRequiresZip64)
{
this.WriteLeInt(-1);
this.WriteLeInt(-1);
}
else
{
this.WriteLeInt(entry.IsCrypted ? (((int) entry.CompressedSize) + 12) : ((int) entry.CompressedSize));
this.WriteLeInt((int) entry.Size);
}
}
else
{
if (this.patchEntryHeader)
{
this.crcPatchPos = base.baseOutputStream_.Position;
}
this.WriteLeInt(0);
if (this.patchEntryHeader)
{
this.sizePatchPos = base.baseOutputStream_.Position;
}
if (entry.LocalHeaderRequiresZip64 || this.patchEntryHeader)
{
this.WriteLeInt(-1);
this.WriteLeInt(-1);
}
else
{
this.WriteLeInt(0);
this.WriteLeInt(0);
}
}
byte[] buffer = ZipConstants.ConvertToArray(entry.Flags, entry.Name);
if (buffer.Length > 0xffff)
{
throw new ZipException("Entry name too long.");
}
ZipExtraData extraData = new ZipExtraData(entry.ExtraData);
if (entry.LocalHeaderRequiresZip64)
{
extraData.StartNewEntry();
if (hasCrc)
{
extraData.AddLeLong(entry.Size);
extraData.AddLeLong(entry.CompressedSize);
}
else
{
extraData.AddLeLong(-1L);
extraData.AddLeLong(-1L);
}
extraData.AddNewEntry(1);
if (!extraData.Find(1))
{
throw new ZipException("Internal error cant find extra data");
}
if (this.patchEntryHeader)
{
this.sizePatchPos = extraData.CurrentReadIndex;
}
}
else
{
extraData.Delete(1);
}
if (entry.AESKeySize > 0)
{
AddExtraDataAES(entry, extraData);
}
byte[] entryData = extraData.GetEntryData();
this.WriteLeShort(buffer.Length);
this.WriteLeShort(entryData.Length);
if (buffer.Length > 0)
{
base.baseOutputStream_.Write(buffer, 0, buffer.Length);
}
if (entry.LocalHeaderRequiresZip64 && this.patchEntryHeader)
{
this.sizePatchPos += base.baseOutputStream_.Position;
}
if (entryData.Length > 0)
{
base.baseOutputStream_.Write(entryData, 0, entryData.Length);
}
this.offset += (30 + buffer.Length) + entryData.Length;
if (entry.AESKeySize > 0)
{
this.offset += entry.AESOverheadSize;
}
this.curEntry = entry;
this.crc.Reset();
if (compressionMethod == CompressionMethod.Deflated)
{
base.deflater_.Reset();
base.deflater_.SetLevel(defaultCompressionLevel);
}
this.size = 0L;
if (entry.IsCrypted)
{
if (entry.AESKeySize > 0)
{
this.WriteAESHeader(entry);
}
else if (entry.Crc < 0L)
{
this.WriteEncryptionHeader(entry.DosTime << 0x10);
}
else
{
this.WriteEncryptionHeader(entry.Crc);
}
}
}