Class: Archive::Zip::Codec::Store::Decompress
- Inherits:
-
Object
- Object
- Archive::Zip::Codec::Store::Decompress
- Includes:
- IO::Like
- Defined in:
- lib/archive/zip/codec/store.rb
Overview
Archive::Zip::Codec::Store::Decompress is a readable, IO-like wrapper around a readable, IO-like object which provides a CRC32 checksum of the data read through it as well as the count of the total amount of data. A close method is also provided which can optionally close the delegate object. In addition a convenience method is provided for generating DataDescriptor objects based on the data which is passed through this object.
Instances of this class should only be accessed via the Archive::Zip::Codec::Store#decompressor method.
Class Method Summary collapse
-
.open(io) ⇒ Object
Creates a new instance of this class with the given arguments using #new and then passes the instance to the given block.
Instance Method Summary collapse
-
#close(close_delegate = true) ⇒ Object
Closes this object so that further read operations will fail.
-
#data_descriptor ⇒ Object
Returns an instance of Archive::Zip::DataDescriptor with information regarding the data which has passed through this object from the delegate object.
-
#initialize(io) ⇒ Decompress
constructor
Creates a new instance of this class using io as a data source.
-
#unbuffered_read(length) ⇒ Object
private
Returns at most length bytes from the delegate object.
-
#unbuffered_seek(offset, whence = IO::SEEK_SET) ⇒ Object
private
Allows resetting this object and the delegate object back to the beginning of the stream or reporting the current position in the stream.
Constructor Details
#initialize(io) ⇒ Decompress
Creates a new instance of this class using io as a data source. io must be readable and provide a read method as an IO instance would or errors will be raised when performing read operations.
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.
Due to certain optimizations within IO::Like#seek and if there is data in the read buffer, the seek method can be used to seek forward from the current stream position up to the end of the buffer. Unless it is known definitively how much data is in the buffer, it is best to avoid relying on this behavior.
If io 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.
Any other seeking attempts, will raise Errno::EINVAL exceptions.
The fill_size attribute is set to 0
by default under the assumption that io is already buffered.
167 168 169 170 171 172 173 |
# File 'lib/archive/zip/codec/store.rb', line 167 def initialize(io) @io = io @crc32 = 0 @uncompressed_size = 0 # Assume that the delegate IO object is already buffered. self.fill_size = 0 end |
Class Method Details
.open(io) ⇒ Object
Creates a new instance of this class with the given arguments using #new and then passes the instance to the given block. The #close method is guaranteed to be called after the block completes.
Equivalent to #new if no block is given.
133 134 135 136 137 138 139 140 141 142 |
# File 'lib/archive/zip/codec/store.rb', line 133 def self.open(io) unstore_io = new(io) return unstore_io unless block_given? begin yield(unstore_io) ensure unstore_io.close unless unstore_io.closed? end end |
Instance Method Details
#close(close_delegate = true) ⇒ Object
Closes this object so that further read operations will fail. If close_delegate is true
, the delegate object used as a data source will also be closed using its close method.
178 179 180 181 182 |
# File 'lib/archive/zip/codec/store.rb', line 178 def close(close_delegate = true) super() @io.close if close_delegate nil end |
#data_descriptor ⇒ Object
Returns an instance of Archive::Zip::DataDescriptor with information regarding the data which has passed through this object from the delegate object. It is recommended to call the close method before calling this in order to ensure that no further read operations change the state of this object.
189 190 191 192 193 194 195 |
# File 'lib/archive/zip/codec/store.rb', line 189 def data_descriptor DataDescriptor.new( @crc32, @uncompressed_size, @uncompressed_size ) end |
#unbuffered_read(length) ⇒ Object (private)
Returns at most length bytes from the delegate object. Updates the uncompressed_size and crc32 attributes as a side effect.
201 202 203 204 205 206 207 208 |
# File 'lib/archive/zip/codec/store.rb', line 201 def unbuffered_read(length) buffer = @io.read(length) raise EOFError, 'end of file reached' if buffer.nil? @uncompressed_size += buffer.length @crc32 = Zlib.crc32(buffer, @crc32) buffer end |
#unbuffered_seek(offset, whence = IO::SEEK_SET) ⇒ Object (private)
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.
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/archive/zip/codec/store.rb', line 217 def unbuffered_seek(offset, whence = IO::SEEK_SET) unless offset == 0 && ((whence == IO::SEEK_SET && @io.respond_to?(:rewind)) || whence == IO::SEEK_CUR) then raise Errno::EINVAL end case whence when IO::SEEK_SET @io.rewind @crc32 = 0 @uncompressed_size = 0 when IO::SEEK_CUR @uncompressed_size end end |