D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
opt
/
td-agent
/
embedded
/
lib
/
ruby
/
gems
/
2.1.0
/
gems
/
rubyzip-1.1.7
/
lib
/
zip
/
Filename :
input_stream.rb
back
Copy
module Zip # InputStream is the basic class for reading zip entries in a # zip file. It is possible to create a InputStream object directly, # passing the zip file name to the constructor, but more often than not # the InputStream will be obtained from a File (perhaps using the # ZipFileSystem interface) object for a particular entry in the zip # archive. # # A InputStream inherits IOExtras::AbstractInputStream in order # to provide an IO-like interface for reading from a single zip # entry. Beyond methods for mimicking an IO-object it contains # the method get_next_entry for iterating through the entries of # an archive. get_next_entry returns a Entry object that describes # the zip entry the InputStream is currently reading from. # # Example that creates a zip archive with ZipOutputStream and reads it # back again with a InputStream. # # require 'zip' # # Zip::OutputStream.open("my.zip") do |io| # # io.put_next_entry("first_entry.txt") # io.write "Hello world!" # # io.put_next_entry("adir/first_entry.txt") # io.write "Hello again!" # end # # # Zip::InputStream.open("my.zip") do |io| # # while (entry = io.get_next_entry) # puts "Contents of #{entry.name}: '#{io.read}'" # end # end # # java.util.zip.ZipInputStream is the original inspiration for this # class. class InputStream include ::Zip::IOExtras::AbstractInputStream # Opens the indicated zip file. An exception is thrown # if the specified offset in the specified filename is # not a local zip entry header. # # @param context [String||IO||StringIO] file path or IO/StringIO object # @param offset [Integer] offset in the IO/StringIO def initialize(context, offset = 0, decrypter = nil) super() @archive_io = get_io(context, offset) @decompressor = ::Zip::NullDecompressor @decrypter = decrypter || ::Zip::NullDecrypter.new @current_entry = nil end def close @archive_io.close end # Returns a Entry object. It is necessary to call this # method on a newly created InputStream before reading from # the first entry in the archive. Returns nil when there are # no more entries. def get_next_entry @archive_io.seek(@current_entry.next_header_offset, IO::SEEK_SET) if @current_entry open_entry end # Rewinds the stream to the beginning of the current entry def rewind return if @current_entry.nil? @lineno = 0 @pos = 0 @archive_io.seek(@current_entry.local_header_offset, IO::SEEK_SET) open_entry end # Modeled after IO.sysread def sysread(number_of_bytes = nil, buf = nil) @decompressor.sysread(number_of_bytes, buf) end def eof @output_buffer.empty? && @decompressor.eof end alias :eof? :eof class << self # Same as #initialize but if a block is passed the opened # stream is passed to the block and closed when the block # returns. def open(filename_or_io, offset = 0, decrypter = nil) zio = self.new(filename_or_io, offset, decrypter) return zio unless block_given? begin yield zio ensure zio.close if zio end end def open_buffer(filename_or_io, offset = 0) puts "open_buffer is deprecated!!! Use open instead!" self.open(filename_or_io, offset) end end protected def get_io(io_or_file, offset = 0) case io_or_file when IO, StringIO io = io_or_file.dup io.seek(offset, ::IO::SEEK_SET) io else file = ::File.open(io_or_file, 'rb') file.seek(offset, ::IO::SEEK_SET) file end end def open_entry @current_entry = ::Zip::Entry.read_local_entry(@archive_io) if @current_entry and @current_entry.gp_flags & 1 == 1 and @decrypter.is_a? NullEncrypter raise Error, 'password required to decode zip file' end @decompressor = get_decompressor flush @current_entry end def get_decompressor case when @current_entry.nil? ::Zip::NullDecompressor when @current_entry.compression_method == ::Zip::Entry::STORED ::Zip::PassThruDecompressor.new(@archive_io, @current_entry.size) when @current_entry.compression_method == ::Zip::Entry::DEFLATED header = @archive_io.read(@decrypter.header_bytesize) @decrypter.reset!(header) ::Zip::Inflater.new(@archive_io, @decrypter) else raise ::Zip::CompressionMethodError, "Unsupported compression method #{@current_entry.compression_method}" end end def produce_input @decompressor.produce_input end def input_finished? @decompressor.input_finished? end end end # Copyright (C) 2002, 2003 Thomas Sondergaard # rubyzip is free software; you can redistribute it and/or # modify it under the terms of the ruby license.