Esempio n. 1
0
        public Stream WriteToStream(string entryPath, ZipWriterEntryOptions options)
        {
            var compression = ToZipCompressionMethod(options.CompressionType ?? compressionType);

            entryPath = NormalizeFilename(entryPath);
            options.ModificationDateTime = options.ModificationDateTime ?? DateTime.Now;
            options.EntryComment         = options.EntryComment ?? string.Empty;
            var entry = new ZipCentralDirectoryEntry(compression, entryPath, (ulong)streamPosition, WriterOptions.ArchiveEncoding)
            {
                Comment          = options.EntryComment,
                ModificationTime = options.ModificationDateTime
            };

            // Use the archive default setting for zip64 and allow overrides
            var useZip64 = isZip64;

            if (options.EnableZip64.HasValue)
            {
                useZip64 = options.EnableZip64.Value;
            }

            var headersize = (uint)WriteHeader(entryPath, options, entry, useZip64);

            streamPosition += headersize;
            return(new ZipWritingStream(this, OutputStream, entry, compression,
                                        options.DeflateCompressionLevel ?? compressionLevel));
        }
Esempio n. 2
0
 public void Write(string entryPath, Stream source, ZipWriterEntryOptions zipWriterEntryOptions)
 {
     using (Stream output = WriteToStream(entryPath, zipWriterEntryOptions))
     {
         source.TransferTo(output);
     }
 }
Esempio n. 3
0
        public Stream WriteToStream(string entryPath, ZipWriterEntryOptions options)
        {
            bool isDirectory = entryPath.EndsWith("/");

            entryPath = NormalizeFilename(entryPath);
            if (isDirectory)
            {
                entryPath += "/";
            }
            options.ModificationDateTime = options.ModificationDateTime ?? DateTime.Now;
            options.EntryComment         = options.EntryComment ?? string.Empty;
            var entry = new ZipCentralDirectoryEntry
            {
                Comment          = options.EntryComment,
                FileName         = entryPath,
                ModificationTime = options.ModificationDateTime,
                HeaderOffset     = (uint)streamPosition
            };

            var headersize = (uint)WriteHeader(entryPath, options);

            streamPosition += headersize;
            return(new ZipWritingStream(this, OutputStream, entry,
                                        ToZipCompressionMethod(options.CompressionType ?? compressionType),
                                        options.DeflateCompressionLevel ?? compressionLevel));
        }
Esempio n. 4
0
        private int WriteHeader(string filename, ZipWriterEntryOptions zipWriterEntryOptions, ZipCentralDirectoryEntry entry, bool useZip64)
        {
            // We err on the side of caution until the zip specification clarifies how to support this
            if (!OutputStream.CanSeek && useZip64)
            {
                throw new NotSupportedException("Zip64 extensions are not supported on non-seekable streams");
            }

            var explicitZipCompressionInfo = ToZipCompressionMethod(zipWriterEntryOptions.CompressionType ?? compressionType);

            byte[] encodedFilename = WriterOptions.ArchiveEncoding.Encode(filename);

            Span <byte> intBuf = stackalloc byte[4];

            BinaryPrimitives.WriteUInt32LittleEndian(intBuf, ZipHeaderFactory.ENTRY_HEADER_BYTES);
            OutputStream.Write(intBuf);
            if (explicitZipCompressionInfo == ZipCompressionMethod.Deflate)
            {
                if (OutputStream.CanSeek && useZip64)
                {
                    OutputStream.Write(stackalloc byte[] { 45, 0 }); //smallest allowed version for zip64
Esempio n. 5
0
        private int WriteHeader(string filename, ZipWriterEntryOptions zipWriterEntryOptions)
        {
            var explicitZipCompressionInfo = ToZipCompressionMethod(zipWriterEntryOptions.CompressionType ?? compressionType);

            byte[] encodedFilename = ArchiveEncoding.Default.GetBytes(filename);

            OutputStream.Write(DataConverter.LittleEndian.GetBytes(ZipHeaderFactory.ENTRY_HEADER_BYTES), 0, 4);
            if (explicitZipCompressionInfo == ZipCompressionMethod.Deflate)
            {
                OutputStream.Write(new byte[] { 20, 0 }, 0, 2); //older version which is more compatible
            }
            else
            {
                OutputStream.Write(new byte[] { 63, 0 }, 0, 2); //version says we used PPMd or LZMA
            }
            HeaderFlags flags = ArchiveEncoding.Default == Encoding.UTF8 ? HeaderFlags.UTF8 : 0;

            if (!OutputStream.CanSeek)
            {
                flags |= HeaderFlags.UsePostDataDescriptor;
                if (explicitZipCompressionInfo == ZipCompressionMethod.LZMA)
                {
                    flags |= HeaderFlags.Bit1; // eos marker
                }
            }
            OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)flags), 0, 2);
            OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)explicitZipCompressionInfo), 0, 2); // zipping method
            OutputStream.Write(DataConverter.LittleEndian.GetBytes(zipWriterEntryOptions.ModificationDateTime.DateTimeToDosTime()), 0, 4);

            // zipping date and time
            OutputStream.Write(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 12);

            // unused CRC, un/compressed size, updated later
            OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)encodedFilename.Length), 0, 2); // filename length
            OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)0), 0, 2);                      // extra length
            OutputStream.Write(encodedFilename, 0, encodedFilename.Length);

            return(6 + 2 + 2 + 4 + 12 + 2 + 2 + encodedFilename.Length);
        }
Esempio n. 6
0
        private int WriteHeader(string filename, ZipWriterEntryOptions zipWriterEntryOptions, ZipCentralDirectoryEntry entry, bool useZip64)
        {
            // We err on the side of caution until the zip specification clarifies how to support this
            if (!OutputStream.CanSeek && useZip64)
            {
                throw new NotSupportedException("Zip64 extensions are not supported on non-seekable streams");
            }

            var explicitZipCompressionInfo = ToZipCompressionMethod(zipWriterEntryOptions.CompressionType ?? compressionType);

            byte[] encodedFilename = WriterOptions.ArchiveEncoding.Encode(filename);

            OutputStream.Write(DataConverter.LittleEndian.GetBytes(ZipHeaderFactory.ENTRY_HEADER_BYTES), 0, 4);
            if (explicitZipCompressionInfo == ZipCompressionMethod.Deflate)
            {
                if (OutputStream.CanSeek && useZip64)
                {
                    OutputStream.Write(new byte[] { 45, 0 }, 0, 2); //smallest allowed version for zip64
                }
                else
                {
                    OutputStream.Write(new byte[] { 20, 0 }, 0, 2); //older version which is more compatible
                }
            }
            else
            {
                OutputStream.Write(new byte[] { 63, 0 }, 0, 2); //version says we used PPMd or LZMA
            }
            HeaderFlags flags = Equals(WriterOptions.ArchiveEncoding.GetEncoding(), Encoding.UTF8) ? HeaderFlags.UTF8 : 0;

            if (!OutputStream.CanSeek)
            {
                flags |= HeaderFlags.UsePostDataDescriptor;

                if (explicitZipCompressionInfo == ZipCompressionMethod.LZMA)
                {
                    flags |= HeaderFlags.Bit1; // eos marker
                }
            }
            OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)flags), 0, 2);
            OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)explicitZipCompressionInfo), 0, 2); // zipping method
            OutputStream.Write(DataConverter.LittleEndian.GetBytes(zipWriterEntryOptions.ModificationDateTime.DateTimeToDosTime()), 0, 4);

            // zipping date and time
            OutputStream.Write(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 12);

            // unused CRC, un/compressed size, updated later
            OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)encodedFilename.Length), 0, 2); // filename length

            var extralength = 0;

            if (OutputStream.CanSeek && useZip64)
            {
                extralength = 2 + 2 + 8 + 8;
            }

            OutputStream.Write(DataConverter.LittleEndian.GetBytes((ushort)extralength), 0, 2); // extra length
            OutputStream.Write(encodedFilename, 0, encodedFilename.Length);

            if (extralength != 0)
            {
                OutputStream.Write(new byte[extralength], 0, extralength); // reserve space for zip64 data
                entry.Zip64HeaderOffset = (ushort)(6 + 2 + 2 + 4 + 12 + 2 + 2 + encodedFilename.Length);
            }

            return(6 + 2 + 2 + 4 + 12 + 2 + 2 + encodedFilename.Length + extralength);
        }