Class: Archive::Zip::Codec::Deflate::Writer
- Inherits:
-
IO::LikeHelpers::DelegatedIO
- Object
- IO::LikeHelpers::DelegatedIO
- Archive::Zip::Codec::Deflate::Writer
- Defined in:
- lib/archive/zip/codec/deflate/writer.rb
Overview
Archive::Zip::Codec::Deflate#compressor method.
Instance Attribute Summary collapse
-
#crc32 ⇒ Object
readonly
The CRC32 checksum of the uncompressed data written using this object.
Instance Method Summary collapse
-
#close ⇒ Object
Closes the writer by finishing the compressed data and flushing it to the delegate.
-
#compressed_size ⇒ Object
Returns the number of bytes of compressed data produced so far.
-
#data_descriptor ⇒ Object
Returns an instance of Archive::Zip::DataDescriptor with information regarding the data which has passed through this object to the delegate object.
-
#initialize(delegate, autoclose: true, level: Zlib::DEFAULT_COMPRESSION, mem_level: nil, strategy: nil) ⇒ Writer
constructor
Creates a new instance of this class.
-
#seek(amount, whence = IO::SEEK_SET) ⇒ Object
Allows resetting this object and the delegate object back to the beginning of the stream or reporting the current position in the stream.
-
#uncompressed_size ⇒ Object
Returns the number of bytes sent to be compressed so far.
- #write(buffer, length: buffer.bytesize) ⇒ Object
Constructor Details
#initialize(delegate, autoclose: true, level: Zlib::DEFAULT_COMPRESSION, mem_level: nil, strategy: nil) ⇒ Writer
Creates a new instance of this class. delegate must respond to the write method as an instance of IO would. level, mem_level, and strategy are all passed directly to Zlib::Deflate.new().
The following descriptions of level, mem_level, and strategy are based upon or pulled largely verbatim from descriptions found in zlib.h version 1.2.3 with changes made to account for different parameter names and to improve readability. Some of the statements concerning default settings or value ranges may not be accurate depending on the version of the zlib library used by a given Ruby interpreter.
The level parameter must be nil
, Zlib::DEFAULT_COMPRESSION, or between 0
and 9
: 1
gives best speed, 9
gives best compression, 0
gives no compression at all (the input data is simply copied a block at a time). Zlib::DEFAULT_COMPRESSION requests a default compromise between speed and compression (currently equivalent to level 6
). If unspecified or nil
, level defaults to Zlib::DEFAULT_COMPRESSION.
The mem_level parameter specifies how much memory should be allocated for the internal compression state. A value of 1
uses minimum memory but is slow and reduces compression ratio; a value of 9
uses maximum memory for optimal speed. The default value is 8
if unspecified or nil
.
The strategy parameter is used to tune the compression algorithm. It only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. The default value is Zlib::DEFAULT_STRATEGY if unspecified or nil
.
Use the value Zlib::DEFAULT_STRATEGY for normal data, Zlib::FILTERED for data produced by a filter (or predictor), Zlib::HUFFMAN_ONLY to force Huffman encoding only (no string match), Zlib::RLE to limit match distances to 1 (run-length encoding), or Zlib::FIXED to simplify decoder requirements.
The effect of Zlib::FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between Zlib::DEFAULT_STRATEGY and Zlib::HUFFMAN_ONLY. Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better.
Zlib::RLE is designed to be almost as fast as Zlib::HUFFMAN_ONLY, but give better compression for PNG image data.
Zlib::FIXED prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications.
This class has extremely limited seek capabilities. It is possible to seek with an offset of 0
and a whence of IO::SEEK_CUR
. As a result, the pos and tell methods also work as expected.
If delegate also responds to rewind, then the rewind method of this class can be used to reset the whole stream back to the beginning. Using seek of this class to seek directly to offset 0
using IO::SEEK_SET
for whence will also work in this case.
NOTE: Due to limitations in Ruby’s finalization capabilities, the #close method is not automatically called when this object is garbage collected. Make sure to call #close when finished with this object.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/archive/zip/codec/deflate/writer.rb', line 80 def initialize( delegate, autoclose: true, level: Zlib::DEFAULT_COMPRESSION, mem_level: nil, strategy: nil ) super(delegate, autoclose: autoclose) @deflater = Zlib::Deflate.new(level, -Zlib::MAX_WBITS, mem_level, strategy) self.deflate_buffer = '' @crc32 = 0 @compressed_size = nil @uncompressed_size = nil end |
Instance Attribute Details
#crc32 ⇒ Object (readonly)
The CRC32 checksum of the uncompressed data written using this object.
NOTE: Anything still in the internal write buffer has not been processed, so calling #flush prior to examining this attribute may be necessary for an accurate computation.
122 123 124 |
# File 'lib/archive/zip/codec/deflate/writer.rb', line 122 def crc32 @crc32 end |
Instance Method Details
#close ⇒ Object
Closes the writer by finishing the compressed data and flushing it to the delegate.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/archive/zip/codec/deflate/writer.rb', line 98 def close return nil if closed? result = flush return result if Symbol === result unless @deflater.finished? self.deflate_buffer = @deflater.finish result = flush return result if Symbol === result end @compressed_size = @deflater.total_out @uncompressed_size = @deflater.total_in @deflater.close super end |
#compressed_size ⇒ Object
Returns the number of bytes of compressed data produced so far.
NOTE: This value is only updated when both the internal write buffer is flushed and there is enough data to produce a compressed block. It does not necessarily reflect the amount of data written to the delegate until this stream is closed however. Until then the only guarantee is that the value will be greater than or equal to 0
.
131 132 133 |
# File 'lib/archive/zip/codec/deflate/writer.rb', line 131 def compressed_size @deflater.closed? ? @compressed_size : @deflater.total_out end |
#data_descriptor ⇒ Object
Returns an instance of Archive::Zip::DataDescriptor with information regarding the data which has passed through this object to the delegate object. The close or flush methods should be called before using this method in order to ensure that any possibly buffered data is flushed to the delegate object; otherwise, the contents of the data descriptor may be inaccurate.
149 150 151 |
# File 'lib/archive/zip/codec/deflate/writer.rb', line 149 def data_descriptor DataDescriptor.new(crc32, compressed_size, uncompressed_size) end |
#seek(amount, whence = IO::SEEK_SET) ⇒ Object
Allows resetting this object and the delegate object back to the beginning of the stream or reporting the current position in the stream.
Raises Errno::EINVAL unless offset is 0
and whence is either IO::SEEK_SET or IO::SEEK_CUR. Raises Errno::EINVAL if whence is IO::SEEK_SEK and the delegate object does not respond to the rewind method.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/archive/zip/codec/deflate/writer.rb', line 160 def seek(amount, whence = IO::SEEK_SET) assert_open raise Errno::ESPIPE if amount != 0 || whence == IO::SEEK_END case whence when IO::SEEK_SET result = super return result if Symbol === result @deflater.reset self.deflate_buffer = '' @crc32 = 0 result when IO::SEEK_CUR @deflater.total_in else raise Errno::EINVAL end end |
#uncompressed_size ⇒ Object
Returns the number of bytes sent to be compressed so far.
NOTE: This value is only updated when the internal write buffer is flushed.
139 140 141 |
# File 'lib/archive/zip/codec/deflate/writer.rb', line 139 def uncompressed_size @deflater.closed? ? @uncompressed_size : @deflater.total_in end |
#write(buffer, length: buffer.bytesize) ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/archive/zip/codec/deflate/writer.rb', line 179 def write(buffer, length: buffer.bytesize) # First try to write out the contents of the deflate buffer because if # that raises a failure we can let that pass up the call stack without # having polluted the deflater instance. result = flush return result if Symbol === result buffer = buffer[0, length] unless length == buffer.bytesize self.deflate_buffer = @deflater.deflate(buffer) @crc32 = Zlib.crc32(buffer, @crc32) length end |