/// <summary> /// Starts a new Zip entry. It automatically closes the previous /// entry if present. /// All entry elements bar name are optional, but must be correct if present. /// If the compression method is stored and the output is not patchable /// the compression for that entry is automatically changed to deflate level 0 /// </summary> /// <param name="entry"> /// the entry. /// </param> /// <exception cref="System.ArgumentNullException"> /// if entry passed is null. /// </exception> /// <exception cref="System.IO.IOException"> /// if an I/O error occured. /// </exception> /// <exception cref="System.InvalidOperationException"> /// if stream was finished /// </exception> /// <exception cref="ZipException"> /// Too many entries in the Zip file<br/> /// Entry name is too long<br/> /// Finish has already been called<br/> /// </exception> public void PutNextEntry(ZipEntry entry) { if (entry == null) { throw new ArgumentNullException("entry"); } if (entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (curEntry != null) { CloseEntry(); } if (entries.Count == int.MaxValue) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod method = entry.CompressionMethod; int compressionLevel = defaultCompressionLevel; // Clear flags that the library manages internally entry.Flags &= (int) GeneralBitFlags.UnicodeText; patchEntryHeader = false; bool headerInfoAvailable; // No need to compress - definitely no data. if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0; method = CompressionMethod.Stored; headerInfoAvailable = true; } else { headerInfoAvailable = (entry.Size >= 0) && entry.HasCrc; // Switch to deflation if storing isnt possible. if (method == CompressionMethod.Stored) { if (!headerInfoAvailable) { if (!CanPatchEntries) { // Can't patch entries so storing is not possible. method = CompressionMethod.Deflated; compressionLevel = 0; } } else // entry.size must be > 0 { entry.CompressedSize = entry.Size; headerInfoAvailable = entry.HasCrc; } } } if (headerInfoAvailable == false) { if (CanPatchEntries == false) { // Only way to record size and compressed size is to append a data descriptor // after compressed data. // Stored entries of this form have already been converted to deflating. entry.Flags |= 8; } else { patchEntryHeader = true; } } if (Password != null) { entry.IsCrypted = true; if (entry.Crc < 0) { // Need to append a data descriptor as the crc isnt available for use // with encryption, the date is used instead. Setting the flag // indicates this to the decompressor. entry.Flags |= 8; } } entry.Offset = offset; entry.CompressionMethod = method; curMethod = method; sizePatchPos = -1; if ((useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic))) { entry.ForceZip64(); } // Write the local file header WriteLeInt(ZipConstants.LocalHeaderSignature); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((byte) entry.CompressionMethodForHeader); WriteLeInt((int) entry.DosTime); // TODO: Refactor header writing. Its done in several places. if (headerInfoAvailable) { WriteLeInt((int) entry.Crc); if (entry.LocalHeaderRequiresZip64) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(entry.IsCrypted ? (int) entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int) entry.CompressedSize); WriteLeInt((int) entry.Size); } } else { if (patchEntryHeader) { crcPatchPos = baseOutputStream_.Position; } WriteLeInt(0); // Crc if (patchEntryHeader) { sizePatchPos = baseOutputStream_.Position; } // For local header both sizes appear in Zip64 Extended Information if (entry.LocalHeaderRequiresZip64 || patchEntryHeader) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(0); // Compressed size WriteLeInt(0); // Uncompressed size } } byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xFFFF) { throw new ZipException("Entry name too long."); } var ed = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { ed.StartNewEntry(); if (headerInfoAvailable) { ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); } else { ed.AddLeLong(-1); ed.AddLeLong(-1); } ed.AddNewEntry(1); if (!ed.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (patchEntryHeader) { sizePatchPos = ed.CurrentReadIndex; } } else { ed.Delete(1); } #if !NET_1_1 && !NETCF_2_0 if (entry.AESKeySize > 0) { AddExtraDataAES(entry, ed); } #endif byte[] extra = ed.GetEntryData(); WriteLeShort(name.Length); WriteLeShort(extra.Length); if (name.Length > 0) { baseOutputStream_.Write(name, 0, name.Length); } if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { sizePatchPos += baseOutputStream_.Position; } if (extra.Length > 0) { baseOutputStream_.Write(extra, 0, extra.Length); } offset += ZipConstants.LocalHeaderBaseSize + name.Length + extra.Length; // Fix offsetOfCentraldir for AES if (entry.AESKeySize > 0) offset += entry.AESOverheadSize; // Activate the entry. curEntry = entry; crc.Reset(); if (method == CompressionMethod.Deflated) { deflater_.Reset(); deflater_.SetLevel(compressionLevel); } size = 0; if (entry.IsCrypted) { #if !NET_1_1 && !NETCF_2_0 if (entry.AESKeySize > 0) { WriteAESHeader(entry); } else #endif { if (entry.Crc < 0) { // so testing Zip will says its ok WriteEncryptionHeader(entry.DosTime << 16); } else { WriteEncryptionHeader(entry.Crc); } } } }
/// <summary> /// Starts a new Zip entry. It automatically closes the previous /// entry if present. /// All entry elements bar name are optional, but must be correct if present. /// If the compression method is stored and the output is not patchable /// the compression for that entry is automatically changed to deflate level 0 /// </summary> /// <param name="entry"> /// the entry. /// </param> /// <exception cref="System.ArgumentNullException"> /// if entry passed is null. /// </exception> /// <exception cref="System.IO.IOException"> /// if an I/O error occured. /// </exception> /// <exception cref="System.InvalidOperationException"> /// if stream was finished /// </exception> /// <exception cref="ZipException"> /// Too many entries in the Zip file<br/> /// Entry name is too long<br/> /// Finish has already been called<br/> /// </exception> public void PutNextEntry(ZipEntry entry) { if (entry == null) { throw new ArgumentNullException("entry"); } if (entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (curEntry != null) { CloseEntry(); } if (entries.Count == int.MaxValue) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod method = entry.CompressionMethod; int compressionLevel = defaultCompressionLevel; // Clear flags that the library manages internally entry.Flags &= (int)GeneralBitFlags.UnicodeText; patchEntryHeader = false; bool headerInfoAvailable; // No need to compress - definitely no data. if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0; method = CompressionMethod.Stored; headerInfoAvailable = true; } else { headerInfoAvailable = (entry.Size >= 0) && entry.HasCrc; // Switch to deflation if storing isnt possible. if (method == CompressionMethod.Stored) { if (!headerInfoAvailable) { if (!CanPatchEntries) { // Can't patch entries so storing is not possible. method = CompressionMethod.Deflated; compressionLevel = 0; } } else // entry.size must be > 0 { entry.CompressedSize = entry.Size; headerInfoAvailable = entry.HasCrc; } } } if (headerInfoAvailable == false) { if (CanPatchEntries == false) { // Only way to record size and compressed size is to append a data descriptor // after compressed data. // Stored entries of this form have already been converted to deflating. entry.Flags |= 8; } else { patchEntryHeader = true; } } if (Password != null) { entry.IsCrypted = true; if (entry.Crc < 0) { // Need to append a data descriptor as the crc isnt available for use // with encryption, the date is used instead. Setting the flag // indicates this to the decompressor. entry.Flags |= 8; } } entry.Offset = offset; entry.CompressionMethod = method; curMethod = method; sizePatchPos = -1; if ((useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic))) { entry.ForceZip64(); } // Write the local file header WriteLeInt(ZipConstants.LocalHeaderSignature); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((byte)entry.CompressionMethodForHeader); WriteLeInt((int)entry.DosTime); // TODO: Refactor header writing. Its done in several places. if (headerInfoAvailable) { WriteLeInt((int)entry.Crc); if (entry.LocalHeaderRequiresZip64) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize); WriteLeInt((int)entry.Size); } } else { if (patchEntryHeader) { crcPatchPos = baseOutputStream_.Position; } WriteLeInt(0); // Crc if (patchEntryHeader) { sizePatchPos = baseOutputStream_.Position; } // For local header both sizes appear in Zip64 Extended Information if (entry.LocalHeaderRequiresZip64 || patchEntryHeader) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(0); // Compressed size WriteLeInt(0); // Uncompressed size } } byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xFFFF) { throw new ZipException("Entry name too long."); } var ed = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { ed.StartNewEntry(); if (headerInfoAvailable) { ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); } else { ed.AddLeLong(-1); ed.AddLeLong(-1); } ed.AddNewEntry(1); if (!ed.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (patchEntryHeader) { sizePatchPos = ed.CurrentReadIndex; } } else { ed.Delete(1); } #if !NET_1_1 && !NETCF_2_0 if (entry.AESKeySize > 0) { AddExtraDataAES(entry, ed); } #endif byte[] extra = ed.GetEntryData(); WriteLeShort(name.Length); WriteLeShort(extra.Length); if (name.Length > 0) { baseOutputStream_.Write(name, 0, name.Length); } if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { sizePatchPos += baseOutputStream_.Position; } if (extra.Length > 0) { baseOutputStream_.Write(extra, 0, extra.Length); } offset += ZipConstants.LocalHeaderBaseSize + name.Length + extra.Length; // Fix offsetOfCentraldir for AES if (entry.AESKeySize > 0) { offset += entry.AESOverheadSize; } // Activate the entry. curEntry = entry; crc.Reset(); if (method == CompressionMethod.Deflated) { deflater_.Reset(); deflater_.SetLevel(compressionLevel); } size = 0; if (entry.IsCrypted) { #if !NET_1_1 && !NETCF_2_0 if (entry.AESKeySize > 0) { WriteAESHeader(entry); } else #endif { if (entry.Crc < 0) { // so testing Zip will says its ok WriteEncryptionHeader(entry.DosTime << 16); } else { WriteEncryptionHeader(entry.Crc); } } } }
public void EntryWithNoDataAndZip64() { MemoryStream msw = new MemoryStreamWithoutSeek(); ZipOutputStream outStream = new ZipOutputStream(msw); outStream.IsStreamOwner = false; ZipEntry ze = new ZipEntry("Striped Marlin"); ze.ForceZip64(); ze.Size = 0; outStream.PutNextEntry(ze); outStream.CloseEntry(); outStream.Finish(); outStream.Close(); Assert.IsTrue(ZipTesting.TestArchive(msw.ToArray())); }
internal void PutNextEntry(Stream stream, ZipEntry entry, long streamOffset = 0) { if (entry == null) { throw new ArgumentNullException(nameof(entry)); } if (entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (entries.Count == int.MaxValue) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod method = entry.CompressionMethod; // Check that the compression is one that we support if (method != CompressionMethod.Deflated && method != CompressionMethod.Stored) { throw new NotImplementedException("Compression method not supported"); } // A password must have been set in order to add AES encrypted entries if (entry.AESKeySize > 0 && string.IsNullOrEmpty(this.Password)) { throw new InvalidOperationException("The Password property must be set before AES encrypted entries can be added"); } int compressionLevel = defaultCompressionLevel; // Clear flags that the library manages internally entry.Flags &= (int)GeneralBitFlags.UnicodeText; patchEntryHeader = false; bool headerInfoAvailable; // No need to compress - definitely no data. if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0; method = CompressionMethod.Stored; headerInfoAvailable = true; } else { headerInfoAvailable = (entry.Size >= 0) && entry.HasCrc && entry.CompressedSize >= 0; // Switch to deflation if storing isnt possible. if (method == CompressionMethod.Stored) { if (!headerInfoAvailable) { if (!CanPatchEntries) { // Can't patch entries so storing is not possible. method = CompressionMethod.Deflated; compressionLevel = 0; } } else // entry.size must be > 0 { entry.CompressedSize = entry.Size; headerInfoAvailable = entry.HasCrc; } } } if (headerInfoAvailable == false) { if (CanPatchEntries == false) { // Only way to record size and compressed size is to append a data descriptor // after compressed data. // Stored entries of this form have already been converted to deflating. entry.Flags |= 8; } else { patchEntryHeader = true; } } if (Password != null) { entry.IsCrypted = true; if (entry.Crc < 0) { // Need to append a data descriptor as the crc isnt available for use // with encryption, the date is used instead. Setting the flag // indicates this to the decompressor. entry.Flags |= 8; } } entry.Offset = offset; entry.CompressionMethod = (CompressionMethod)method; curMethod = method; if ((useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic))) { entry.ForceZip64(); } // Apply any required transforms to the entry name TransformEntryName(entry); // Write the local file header offset += ZipFormat.WriteLocalHeader(stream, entry, out var entryPatchData, headerInfoAvailable, patchEntryHeader, streamOffset, _stringCodec); patchData = entryPatchData; // Fix offsetOfCentraldir for AES if (entry.AESKeySize > 0) { offset += entry.AESOverheadSize; } // Activate the entry. curEntry = entry; crc.Reset(); if (method == CompressionMethod.Deflated) { deflater_.Reset(); deflater_.SetLevel(compressionLevel); } size = 0; }
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 == 0) { 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) { entry.CompressedSize = entry.Size; hasCrc = entry.HasCrc; } else if (!base.CanPatchEntries) { compressionMethod = CompressionMethod.Deflated; defaultCompressionLevel = 0; } } } 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(0); this.WriteLeInt(0); } else { this.WriteLeInt(-1); this.WriteLeInt(-1); } } 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.Delete(1); } else { 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; } } 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); } } }
public void PutNextEntry(ZipEntry entry) { 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 == 2147483647) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod compressionMethod = entry.CompressionMethod; int level = this.defaultCompressionLevel; entry.Flags &= 2048; this.patchEntryHeader = false; bool flag; if (entry.Size == 0L) { entry.CompressedSize = entry.Size; entry.Crc = 0L; compressionMethod = CompressionMethod.Stored; flag = true; } else { flag = (entry.Size >= 0L && entry.HasCrc); if (compressionMethod == CompressionMethod.Stored) { if (!flag) { if (!base.CanPatchEntries) { compressionMethod = CompressionMethod.Deflated; level = 0; } } else { entry.CompressedSize = entry.Size; flag = entry.HasCrc; } } } if (!flag) { 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_ == UseZip64.On || (entry.Size < 0L && this.useZip64_ == UseZip64.Dynamic)) { entry.ForceZip64(); } this.WriteLeInt(67324752); this.WriteLeShort(entry.Version); this.WriteLeShort(entry.Flags); this.WriteLeShort((int)((byte)compressionMethod)); this.WriteLeInt((int)entry.DosTime); if (flag) { 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 = this.baseOutputStream_.Position; } this.WriteLeInt(0); if (this.patchEntryHeader) { this.sizePatchPos = this.baseOutputStream_.Position; } if (entry.LocalHeaderRequiresZip64 || this.patchEntryHeader) { this.WriteLeInt(-1); this.WriteLeInt(-1); } else { this.WriteLeInt(0); this.WriteLeInt(0); } } byte[] array = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (array.Length > 65535) { throw new ZipException("Entry name too long."); } ZipExtraData zipExtraData = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { zipExtraData.StartNewEntry(); if (flag) { zipExtraData.AddLeLong(entry.Size); zipExtraData.AddLeLong(entry.CompressedSize); } else { zipExtraData.AddLeLong(-1L); zipExtraData.AddLeLong(-1L); } zipExtraData.AddNewEntry(1); if (!zipExtraData.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (this.patchEntryHeader) { this.sizePatchPos = (long)zipExtraData.CurrentReadIndex; } } else { zipExtraData.Delete(1); } byte[] entryData = zipExtraData.GetEntryData(); this.WriteLeShort(array.Length); this.WriteLeShort(entryData.Length); if (array.Length > 0) { this.baseOutputStream_.Write(array, 0, array.Length); } if (entry.LocalHeaderRequiresZip64 && this.patchEntryHeader) { this.sizePatchPos += this.baseOutputStream_.Position; } if (entryData.Length > 0) { this.baseOutputStream_.Write(entryData, 0, entryData.Length); } this.offset += (long)(30 + array.Length + entryData.Length); this.curEntry = entry; this.crc.Reset(); if (compressionMethod == CompressionMethod.Deflated) { this.deflater_.Reset(); this.deflater_.SetLevel(level); } this.size = 0L; if (entry.IsCrypted) { if (entry.Crc < 0L) { this.WriteEncryptionHeader(entry.DosTime << 16); return; } this.WriteEncryptionHeader(entry.Crc); } }
public void PutNextEntry(ZipEntry entry) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (entry == null) { throw new ArgumentNullException("entry"); } if (entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (curEntry != null) { CloseEntry(); } if (entries.get_Count() == 2147483647) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod compressionMethod = entry.CompressionMethod; int level = defaultCompressionLevel; entry.Flags &= 2048; patchEntryHeader = false; bool flag; if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0L; compressionMethod = CompressionMethod.Stored; flag = true; } else { flag = entry.Size >= 0 && entry.HasCrc; if (compressionMethod == CompressionMethod.Stored) { if (!flag) { if (!base.CanPatchEntries) { compressionMethod = CompressionMethod.Deflated; level = 0; } } else { entry.CompressedSize = entry.Size; flag = entry.HasCrc; } } } if (!flag) { if (!base.CanPatchEntries) { entry.Flags |= 8; } else { patchEntryHeader = true; } } if (base.Password != null) { entry.IsCrypted = true; if (entry.Crc < 0) { entry.Flags |= 8; } } entry.Offset = offset; entry.CompressionMethod = compressionMethod; curMethod = compressionMethod; sizePatchPos = -1L; if (useZip64_ == UseZip64.On || (entry.Size < 0 && useZip64_ == UseZip64.Dynamic)) { entry.ForceZip64(); } WriteLeInt(67324752); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((byte)entry.CompressionMethodForHeader); WriteLeInt((int)entry.DosTime); if (flag) { WriteLeInt((int)entry.Crc); if (entry.LocalHeaderRequiresZip64) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt((int)(entry.IsCrypted ? ((int)entry.CompressedSize + 12) : entry.CompressedSize)); WriteLeInt((int)entry.Size); } } else { if (patchEntryHeader) { crcPatchPos = baseOutputStream_.get_Position(); } WriteLeInt(0); if (patchEntryHeader) { sizePatchPos = baseOutputStream_.get_Position(); } if (entry.LocalHeaderRequiresZip64 || patchEntryHeader) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(0); WriteLeInt(0); } } byte[] array = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (array.Length > 65535) { throw new ZipException("Entry name too long."); } ZipExtraData zipExtraData = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { zipExtraData.StartNewEntry(); if (flag) { zipExtraData.AddLeLong(entry.Size); zipExtraData.AddLeLong(entry.CompressedSize); } else { zipExtraData.AddLeLong(-1L); zipExtraData.AddLeLong(-1L); } zipExtraData.AddNewEntry(1); if (!zipExtraData.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (patchEntryHeader) { sizePatchPos = zipExtraData.CurrentReadIndex; } } else { zipExtraData.Delete(1); } byte[] entryData = zipExtraData.GetEntryData(); WriteLeShort(array.Length); WriteLeShort(entryData.Length); if (array.Length > 0) { baseOutputStream_.Write(array, 0, array.Length); } if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { sizePatchPos += baseOutputStream_.get_Position(); } if (entryData.Length > 0) { baseOutputStream_.Write(entryData, 0, entryData.Length); } offset += 30 + array.Length + entryData.Length; if (entry.AESKeySize > 0) { offset += entry.AESOverheadSize; } curEntry = entry; crc.Reset(); if (compressionMethod == CompressionMethod.Deflated) { deflater_.Reset(); deflater_.SetLevel(level); } size = 0L; if (entry.IsCrypted) { if (entry.Crc < 0) { WriteEncryptionHeader(entry.DosTime << 16); } else { WriteEncryptionHeader(entry.Crc); } } }
public void PutNextEntry(ZipEntry entry) { if ( entry == null ) { throw new ArgumentNullException("entry"); } if (entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (curEntry != null) { CloseEntry(); } if (entries.Count == int.MaxValue) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod method = entry.CompressionMethod; int compressionLevel = defaultCompressionLevel; entry.Flags &= (int)GeneralBitFlags.UnicodeText; patchEntryHeader = false; bool headerInfoAvailable; if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0; method = CompressionMethod.Stored; headerInfoAvailable = true; } else { headerInfoAvailable = (entry.Size >= 0) && entry.HasCrc; if (method == CompressionMethod.Stored) { if (!headerInfoAvailable) { if (!CanPatchEntries) { method = CompressionMethod.Deflated; compressionLevel = 0; } } else { entry.CompressedSize = entry.Size; headerInfoAvailable = entry.HasCrc; } } } if (headerInfoAvailable == false) { if (CanPatchEntries == false) { entry.Flags |= 8; } else { patchEntryHeader = true; } } if (Password != null) { entry.IsCrypted = true; if (entry.Crc < 0) { entry.Flags |= 8; } } entry.Offset = offset; entry.CompressionMethod = (CompressionMethod)method; curMethod = method; sizePatchPos = -1; if ( (useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic)) ) { entry.ForceZip64(); } WriteLeInt(ZipConstants.LocalHeaderSignature); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((byte)method); WriteLeInt((int)entry.DosTime); if (headerInfoAvailable == true) { WriteLeInt((int)entry.Crc); if ( entry.LocalHeaderRequiresZip64 ) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize); WriteLeInt((int)entry.Size); } } else { if (patchEntryHeader == true) { crcPatchPos = baseOutputStream_.Position; } WriteLeInt(0); if ( patchEntryHeader ) { sizePatchPos = baseOutputStream_.Position; } if ( entry.LocalHeaderRequiresZip64 || patchEntryHeader ) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(0); WriteLeInt(0); } } byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xFFFF) { throw new ZipException("Entry name too long."); } ZipExtraData ed = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { ed.StartNewEntry(); if (headerInfoAvailable) { ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); } else { ed.AddLeLong(-1); ed.AddLeLong(-1); } ed.AddNewEntry(1); if ( !ed.Find(1) ) { throw new ZipException("Internal error cant find extra data"); } if ( patchEntryHeader ) { sizePatchPos = ed.CurrentReadIndex; } } else { ed.Delete(1); } byte[] extra = ed.GetEntryData(); WriteLeShort(name.Length); WriteLeShort(extra.Length); if ( name.Length > 0 ) { baseOutputStream_.Write(name, 0, name.Length); } if ( entry.LocalHeaderRequiresZip64 && patchEntryHeader ) { sizePatchPos += baseOutputStream_.Position; } if ( extra.Length > 0 ) { baseOutputStream_.Write(extra, 0, extra.Length); } offset += ZipConstants.LocalHeaderBaseSize + name.Length + extra.Length; curEntry = entry; crc.Reset(); if (method == CompressionMethod.Deflated) { deflater_.Reset(); deflater_.SetLevel(compressionLevel); } size = 0; if (entry.IsCrypted == true) { if (entry.Crc < 0) { WriteEncryptionHeader(entry.DosTime << 16); } else { WriteEncryptionHeader(entry.Crc); } } }
public void PutNextEntry(ZipEntry entry) { if (entry == null) { throw new ArgumentNullException("entry"); } if (entries == null) { throw new InvalidOperationException("ZipOutputStream was finished"); } if (curEntry != null) { CloseEntry(); } if (entries.Count == int.MaxValue) { throw new ZipException("Too many entries for Zip file"); } CompressionMethod method = entry.CompressionMethod; int compressionLevel = defaultCompressionLevel; entry.Flags &= (int)GeneralBitFlags.UnicodeText; patchEntryHeader = false; bool headerInfoAvailable; if (entry.Size == 0) { entry.CompressedSize = entry.Size; entry.Crc = 0; method = CompressionMethod.Stored; headerInfoAvailable = true; } else { headerInfoAvailable = (entry.Size >= 0) && entry.HasCrc; if (method == CompressionMethod.Stored) { if (!headerInfoAvailable) { if (!CanPatchEntries) { method = CompressionMethod.Deflated; compressionLevel = 0; } } else { entry.CompressedSize = entry.Size; headerInfoAvailable = entry.HasCrc; } } } if (headerInfoAvailable == false) { if (CanPatchEntries == false) { entry.Flags |= 8; } else { patchEntryHeader = true; } } if (Password != null) { entry.IsCrypted = true; if (entry.Crc < 0) { entry.Flags |= 8; } } entry.Offset = offset; entry.CompressionMethod = (CompressionMethod)method; curMethod = method; sizePatchPos = -1; if ((useZip64_ == UseZip64.On) || ((entry.Size < 0) && (useZip64_ == UseZip64.Dynamic))) { entry.ForceZip64(); } WriteLeInt(ZipConstants.LocalHeaderSignature); WriteLeShort(entry.Version); WriteLeShort(entry.Flags); WriteLeShort((byte)method); WriteLeInt((int)entry.DosTime); if (headerInfoAvailable == true) { WriteLeInt((int)entry.Crc); if (entry.LocalHeaderRequiresZip64) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize); WriteLeInt((int)entry.Size); } } else { if (patchEntryHeader == true) { crcPatchPos = baseOutputStream_.Position; } WriteLeInt(0); if (patchEntryHeader) { sizePatchPos = baseOutputStream_.Position; } if (entry.LocalHeaderRequiresZip64 || patchEntryHeader) { WriteLeInt(-1); WriteLeInt(-1); } else { WriteLeInt(0); WriteLeInt(0); } } byte[] name = ZipConstants.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xFFFF) { throw new ZipException("Entry name too long."); } ZipExtraData ed = new ZipExtraData(entry.ExtraData); if (entry.LocalHeaderRequiresZip64) { ed.StartNewEntry(); if (headerInfoAvailable) { ed.AddLeLong(entry.Size); ed.AddLeLong(entry.CompressedSize); } else { ed.AddLeLong(-1); ed.AddLeLong(-1); } ed.AddNewEntry(1); if (!ed.Find(1)) { throw new ZipException("Internal error cant find extra data"); } if (patchEntryHeader) { sizePatchPos = ed.CurrentReadIndex; } } else { ed.Delete(1); } byte[] extra = ed.GetEntryData(); WriteLeShort(name.Length); WriteLeShort(extra.Length); if (name.Length > 0) { baseOutputStream_.Write(name, 0, name.Length); } if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) { sizePatchPos += baseOutputStream_.Position; } if (extra.Length > 0) { baseOutputStream_.Write(extra, 0, extra.Length); } offset += ZipConstants.LocalHeaderBaseSize + name.Length + extra.Length; curEntry = entry; crc.Reset(); if (method == CompressionMethod.Deflated) { deflater_.Reset(); deflater_.SetLevel(compressionLevel); } size = 0; if (entry.IsCrypted == true) { if (entry.Crc < 0) { WriteEncryptionHeader(entry.DosTime << 16); } else { WriteEncryptionHeader(entry.Crc); } } }
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); } } }