Beispiel #1
0
 public void PutNextEntry(ZipEntry entry)
 {
     bool hasCrc;
     if (entry == null)
     {
         throw new ArgumentNullException("entry");
     }
     if (entries == null)
     {
         throw new InvalidOperationException("ZipOutputStream was finished");
     }
     if (curEntry != null)
     {
         CloseEntry();
     }
     if (entries.Count == 0x7fffffff)
     {
         throw new ZipException("Too many entries for Zip file");
     }
     CompressionMethod compressionMethod = entry.CompressionMethod;
     int compressionLevel = defaultCompressionLevel;
     entry.Flags &= 0x800;
     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;
         if (compressionMethod == CompressionMethod.Stored)
         {
             if (!hasCrc)
             {
                 if (!CanPatchEntries)
                 {
                     compressionMethod = CompressionMethod.Deflated;
                     compressionLevel = 0;
                 }
             }
             else
             {
                 entry.CompressedSize = entry.Size;
                 hasCrc = entry.HasCrc;
             }
         }
     }
     if (!hasCrc)
     {
         if (!CanPatchEntries)
         {
             entry.Flags |= 8;
         }
         else
         {
             patchEntryHeader = true;
         }
     }
     if (Password != null)
     {
         entry.IsCrypted = true;
         if (entry.Crc < 0L)
         {
             entry.Flags |= 8;
         }
     }
     entry.Offset = offset;
     entry.CompressionMethod = compressionMethod;
     curMethod = compressionMethod;
     sizePatchPos = -1L;
     if ((useZip64_ == UseZip64.On) || ((entry.Size < 0L) && (useZip64_ == UseZip64.Dynamic)))
     {
         entry.ForceZip64();
     }
     WriteLeInt(0x4034b50);
     WriteLeShort(entry.Version);
     WriteLeShort(entry.Flags);
     WriteLeShort((byte)entry.CompressionMethodForHeader);
     WriteLeInt((int)entry.DosTime);
     if (hasCrc)
     {
         WriteLeInt((int)entry.Crc);
         if (entry.LocalHeaderRequiresZip64)
         {
             WriteLeInt(-1);
             WriteLeInt(-1);
         }
         else
         {
             WriteLeInt(entry.IsCrypted ? (((int)entry.CompressedSize) + 12) : ((int)entry.CompressedSize));
             WriteLeInt((int)entry.Size);
         }
     }
     else
     {
         if (patchEntryHeader)
         {
             crcPatchPos = baseOutputStream_.Position;
         }
         WriteLeInt(0);
         if (patchEntryHeader)
         {
             sizePatchPos = baseOutputStream_.Position;
         }
         if (entry.LocalHeaderRequiresZip64 || patchEntryHeader)
         {
             WriteLeInt(-1);
             WriteLeInt(-1);
         }
         else
         {
             WriteLeInt(0);
             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 (patchEntryHeader)
         {
             sizePatchPos = extraData.CurrentReadIndex;
         }
     }
     else
     {
         extraData.Delete(1);
     }
     if (entry.AESKeySize > 0)
     {
         AddExtraDataAES(entry, extraData);
     }
     byte[] entryData = extraData.GetEntryData();
     WriteLeShort(buffer.Length);
     WriteLeShort(entryData.Length);
     if (buffer.Length > 0)
     {
         baseOutputStream_.Write(buffer, 0, buffer.Length);
     }
     if (entry.LocalHeaderRequiresZip64 && patchEntryHeader)
     {
         sizePatchPos += baseOutputStream_.Position;
     }
     if (entryData.Length > 0)
     {
         baseOutputStream_.Write(entryData, 0, entryData.Length);
     }
     offset += (30 + buffer.Length) + entryData.Length;
     if (entry.AESKeySize > 0)
     {
         offset += entry.AESOverheadSize;
     }
     curEntry = entry;
     crc.Reset();
     if (compressionMethod == CompressionMethod.Deflated)
     {
         deflater_.Reset();
         deflater_.SetLevel(compressionLevel);
     }
     size = 0L;
     if (entry.IsCrypted)
     {
         if (entry.AESKeySize > 0)
         {
             WriteAESHeader(entry);
         }
         else if (entry.Crc < 0L)
         {
             WriteEncryptionHeader(entry.DosTime << 0x10);
         }
         else
         {
             WriteEncryptionHeader(entry.Crc);
         }
     }
 }