Class: Omnizip::Zip::OutputStream
- Inherits:
-
Object
- Object
- Omnizip::Zip::OutputStream
- Includes:
- Formats::Zip::Constants
- Defined in:
- lib/omnizip/zip/output_stream.rb
Overview
Rubyzip-compatible OutputStream class Provides streaming write API for ZIP archives
Constant Summary
Constants included from Formats::Zip::Constants
Formats::Zip::Constants::ATTR_ARCHIVE, Formats::Zip::Constants::ATTR_DIRECTORY, Formats::Zip::Constants::CENTRAL_DIRECTORY_SIGNATURE, Formats::Zip::Constants::COMPRESSION_BZIP2, Formats::Zip::Constants::COMPRESSION_DEFLATE, Formats::Zip::Constants::COMPRESSION_DEFLATE64, Formats::Zip::Constants::COMPRESSION_IMPLODED, Formats::Zip::Constants::COMPRESSION_LZMA, Formats::Zip::Constants::COMPRESSION_PPMD, Formats::Zip::Constants::COMPRESSION_REDUCED_1, Formats::Zip::Constants::COMPRESSION_REDUCED_2, Formats::Zip::Constants::COMPRESSION_REDUCED_3, Formats::Zip::Constants::COMPRESSION_REDUCED_4, Formats::Zip::Constants::COMPRESSION_SHRUNK, Formats::Zip::Constants::COMPRESSION_STORE, Formats::Zip::Constants::COMPRESSION_ZSTANDARD, Formats::Zip::Constants::DATA_DESCRIPTOR_SIGNATURE, Formats::Zip::Constants::END_OF_CENTRAL_DIRECTORY_SIGNATURE, Formats::Zip::Constants::FLAG_DATA_DESCRIPTOR, Formats::Zip::Constants::FLAG_ENCRYPTED, Formats::Zip::Constants::FLAG_STRONG_ENCRYPTION, Formats::Zip::Constants::FLAG_UTF8, Formats::Zip::Constants::LOCAL_FILE_HEADER_SIGNATURE, Formats::Zip::Constants::MAX_COMMENT_LENGTH, Formats::Zip::Constants::UNIX_DIR_PERMISSIONS, Formats::Zip::Constants::UNIX_EXTRA_FIELD_TAG, Formats::Zip::Constants::UNIX_FILE_PERMISSIONS, Formats::Zip::Constants::UNIX_SYMLINK_PERMISSIONS, Formats::Zip::Constants::VERSION_BZIP2, Formats::Zip::Constants::VERSION_DEFAULT, Formats::Zip::Constants::VERSION_DEFLATE, Formats::Zip::Constants::VERSION_LZMA, Formats::Zip::Constants::VERSION_MADE_BY_UNIX, Formats::Zip::Constants::VERSION_MADE_BY_WINDOWS, Formats::Zip::Constants::VERSION_ZIP64, Formats::Zip::Constants::ZIP64_END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE, Formats::Zip::Constants::ZIP64_END_OF_CENTRAL_DIRECTORY_SIGNATURE, Formats::Zip::Constants::ZIP64_EXTRA_FIELD_TAG, Formats::Zip::Constants::ZIP64_LIMIT
Class Method Summary collapse
-
.open(file_path) {|stream| ... } ⇒ OutputStream
Open a new output stream.
Instance Method Summary collapse
-
#close ⇒ Object
Close the stream.
-
#close_entry ⇒ Object
Close current entry.
-
#closed? ⇒ Boolean
Check if stream is closed.
-
#comment ⇒ Object
Get archive comment.
-
#comment=(comment) ⇒ Object
Set archive comment.
-
#initialize(file_path_or_io) ⇒ OutputStream
constructor
Initialize output stream.
-
#print(*args) ⇒ Object
Print data to current entry.
-
#put_next_entry(name, time: Time.now, comment: "", compression: :deflate, level: 6) ⇒ Object
Start a new entry.
-
#puts(*args) ⇒ Object
Put data to current entry.
-
#write(data) ⇒ Object
(also: #<<)
Write data to current entry.
Constructor Details
#initialize(file_path_or_io) ⇒ OutputStream
Initialize output stream
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/omnizip/zip/output_stream.rb', line 32 def initialize(file_path_or_io) if file_path_or_io.is_a?(String) @file_path = file_path_or_io @io = ::File.open(file_path_or_io, "wb") @owns_io = true else @io = file_path_or_io @owns_io = false end @entries = [] @current_entry = nil @current_entry_data = nil @closed = false end |
Class Method Details
.open(file_path) {|stream| ... } ⇒ OutputStream
Open a new output stream
16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/omnizip/zip/output_stream.rb', line 16 def self.open(file_path, &block) stream = new(file_path) if block begin yield(stream) ensure stream.close end else stream end end |
Instance Method Details
#close ⇒ Object
Close the stream
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/omnizip/zip/output_stream.rb', line 139 def close return if @closed close_entry if @current_entry # Write central directory central_directory_offset = @io.pos write_central_directory central_directory_size = @io.pos - central_directory_offset # Write end of central directory write_end_of_central_directory(central_directory_offset, central_directory_size) @io.close if @owns_io @closed = true end |
#close_entry ⇒ Object
Close current entry
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/omnizip/zip/output_stream.rb', line 96 def close_entry return unless @current_entry # Compress data if needed compressed_data = compress_entry_data # Calculate CRC32 crc32 = @current_entry[:directory] ? 0 : calculate_crc32(@current_entry_data) # Write compressed data @io.write(compressed_data) unless @current_entry[:directory] # Update entry info @current_entry.merge!({ crc32: crc32, compressed_size: compressed_data.bytesize, uncompressed_size: @current_entry_data.bytesize, }) # Update local file header with correct sizes current_pos = @io.pos @io.seek(@current_entry[:offset], ::IO::SEEK_SET) write_local_file_header @io.seek(current_pos, ::IO::SEEK_SET) # Save entry for central directory @entries << @current_entry @current_entry = nil @current_entry_data = nil end |
#closed? ⇒ Boolean
Check if stream is closed
158 159 160 |
# File 'lib/omnizip/zip/output_stream.rb', line 158 def closed? @closed end |
#comment ⇒ Object
Get archive comment
134 135 136 |
# File 'lib/omnizip/zip/output_stream.rb', line 134 def comment @comment || "" end |
#comment=(comment) ⇒ Object
Set archive comment
129 130 131 |
# File 'lib/omnizip/zip/output_stream.rb', line 129 def comment=(comment) @comment = comment end |
#print(*args) ⇒ Object
Print data to current entry
86 87 88 |
# File 'lib/omnizip/zip/output_stream.rb', line 86 def print(*args) write(args.join) end |
#put_next_entry(name, time: Time.now, comment: "", compression: :deflate, level: 6) ⇒ Object
Start a new entry
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/omnizip/zip/output_stream.rb', line 54 def put_next_entry(name, time: Time.now, comment: "", compression: :deflate, level: 6) close_entry if @current_entry @current_entry = { name: name, time: time, comment: comment, compression: compression_method_for(compression), level: level, offset: @io.pos, directory: name.end_with?("/"), } @current_entry_data = String.new(encoding: Encoding::BINARY) # Write placeholder local file header (will update later) write_local_file_header_placeholder self end |
#puts(*args) ⇒ Object
Put data to current entry
91 92 93 |
# File 'lib/omnizip/zip/output_stream.rb', line 91 def puts(*args) args.each { |arg| write("#{arg}\n") } end |
#write(data) ⇒ Object Also known as: <<
Write data to current entry
77 78 79 80 81 82 |
# File 'lib/omnizip/zip/output_stream.rb', line 77 def write(data) raise "No entry started. Call put_next_entry first" unless @current_entry @current_entry_data << data.b self end |