hotplate 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/Rakefile +1 -0
- data/bin/toast +2 -0
- data/hotplate.gemspec +30 -0
- data/lib/hotplate/cli/build.rb +51 -0
- data/lib/hotplate/cli/init.rb +64 -0
- data/lib/hotplate/cli/main.rb +39 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/README.md +271 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/Rakefile +19 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/TODO +15 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/central_directory.rb +208 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/compressor.rb +10 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/constants.rb +63 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/crypto/encryption.rb +11 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/crypto/null_encryption.rb +45 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/crypto/traditional_encryption.rb +99 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/decompressor.rb +13 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/deflater.rb +32 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/dos_time.rb +49 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/entry.rb +696 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/entry_set.rb +86 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/errors.rb +16 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/extra_field/generic.rb +43 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/extra_field/ntfs.rb +92 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/extra_field/old_unix.rb +45 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/extra_field/universal_time.rb +47 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/extra_field/unix.rb +38 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/extra_field/zip64.rb +67 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/extra_field/zip64_placeholder.rb +16 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/extra_field.rb +101 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/file.rb +436 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/filesystem.rb +626 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/inflater.rb +66 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/input_stream.rb +164 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/ioextras/abstract_input_stream.rb +115 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/ioextras/abstract_output_stream.rb +45 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/ioextras.rb +38 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/null_compressor.rb +15 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/null_decompressor.rb +27 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/null_input_stream.rb +10 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/output_stream.rb +190 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/pass_thru_compressor.rb +23 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/pass_thru_decompressor.rb +41 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/streamable_directory.rb +15 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/streamable_stream.rb +56 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip/version.rb +3 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/lib/zip.rb +63 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/samples/example.rb +91 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/samples/example_filesystem.rb +33 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/samples/example_recursive.rb +48 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/samples/gtkRubyzip.rb +86 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/samples/qtzip.rb +101 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/samples/write_simple.rb +13 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/samples/zipfind.rb +74 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/basic_zip_file_test.rb +64 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/central_directory_entry_test.rb +73 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/central_directory_test.rb +104 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/crypto/null_encryption_test.rb +53 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/crypto/traditional_encryption_test.rb +80 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/WarnInvalidDate.zip +0 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/file1.txt +46 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/file1.txt.deflatedData +0 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/file2.txt +1504 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/globTest/foo/bar/baz/foo.txt +0 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/globTest/foo.txt +0 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/globTest/food.txt +0 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/globTest.zip +0 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/mimetype +1 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/notzippedruby.rb +7 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/ntfs.zip +0 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/rubycode.zip +0 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/rubycode2.zip +0 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/testDirectory.bin +0 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/zip64-sample.zip +0 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/zipWithDirs.zip +0 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/data/zipWithEncryption.zip +0 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/deflater_test.rb +67 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/encryption_test.rb +42 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/entry_set_test.rb +138 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/entry_test.rb +165 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/errors_test.rb +36 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/extra_field_test.rb +78 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/file_extract_directory_test.rb +56 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/file_extract_test.rb +90 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/file_split_test.rb +60 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/file_test.rb +559 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/filesystem/dir_iterator_test.rb +62 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/filesystem/directory_test.rb +131 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/filesystem/file_mutating_test.rb +100 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/filesystem/file_nonmutating_test.rb +514 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/filesystem/file_stat_test.rb +66 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/gentestfiles.rb +134 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/inflater_test.rb +14 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/input_stream_test.rb +170 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/ioextras/abstract_input_stream_test.rb +103 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/ioextras/abstract_output_stream_test.rb +106 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/ioextras/fake_io_test.rb +18 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/local_entry_test.rb +156 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/output_stream_test.rb +129 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/pass_thru_compressor_test.rb +31 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/pass_thru_decompressor_test.rb +15 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/settings_test.rb +92 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/test_helper.rb +228 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/unicode_file_names_and_comments_test.rb +52 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/zip64_full_test.rb +53 -0
- data/lib/hotplate/gems/rubyzip-1.1.7/test/zip64_support_test.rb +15 -0
- data/lib/hotplate/java/build.gradle +38 -0
- data/lib/hotplate/java/gradle/wrapper/gradle-wrapper.jar +0 -0
- data/lib/hotplate/java/gradle/wrapper/gradle-wrapper.properties +6 -0
- data/lib/hotplate/java/gradlew +164 -0
- data/lib/hotplate/java/gradlew.bat +90 -0
- data/lib/hotplate/java/template.java +25 -0
- data/lib/hotplate/version.rb +3 -0
- data/lib/hotplate.rb +2 -0
- metadata +186 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
module Zip
|
|
2
|
+
# InputStream is the basic class for reading zip entries in a
|
|
3
|
+
# zip file. It is possible to create a InputStream object directly,
|
|
4
|
+
# passing the zip file name to the constructor, but more often than not
|
|
5
|
+
# the InputStream will be obtained from a File (perhaps using the
|
|
6
|
+
# ZipFileSystem interface) object for a particular entry in the zip
|
|
7
|
+
# archive.
|
|
8
|
+
#
|
|
9
|
+
# A InputStream inherits IOExtras::AbstractInputStream in order
|
|
10
|
+
# to provide an IO-like interface for reading from a single zip
|
|
11
|
+
# entry. Beyond methods for mimicking an IO-object it contains
|
|
12
|
+
# the method get_next_entry for iterating through the entries of
|
|
13
|
+
# an archive. get_next_entry returns a Entry object that describes
|
|
14
|
+
# the zip entry the InputStream is currently reading from.
|
|
15
|
+
#
|
|
16
|
+
# Example that creates a zip archive with ZipOutputStream and reads it
|
|
17
|
+
# back again with a InputStream.
|
|
18
|
+
#
|
|
19
|
+
# require 'zip'
|
|
20
|
+
#
|
|
21
|
+
# Zip::OutputStream.open("my.zip") do |io|
|
|
22
|
+
#
|
|
23
|
+
# io.put_next_entry("first_entry.txt")
|
|
24
|
+
# io.write "Hello world!"
|
|
25
|
+
#
|
|
26
|
+
# io.put_next_entry("adir/first_entry.txt")
|
|
27
|
+
# io.write "Hello again!"
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
#
|
|
31
|
+
# Zip::InputStream.open("my.zip") do |io|
|
|
32
|
+
#
|
|
33
|
+
# while (entry = io.get_next_entry)
|
|
34
|
+
# puts "Contents of #{entry.name}: '#{io.read}'"
|
|
35
|
+
# end
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# java.util.zip.ZipInputStream is the original inspiration for this
|
|
39
|
+
# class.
|
|
40
|
+
|
|
41
|
+
class InputStream
|
|
42
|
+
include ::Zip::IOExtras::AbstractInputStream
|
|
43
|
+
|
|
44
|
+
# Opens the indicated zip file. An exception is thrown
|
|
45
|
+
# if the specified offset in the specified filename is
|
|
46
|
+
# not a local zip entry header.
|
|
47
|
+
#
|
|
48
|
+
# @param context [String||IO||StringIO] file path or IO/StringIO object
|
|
49
|
+
# @param offset [Integer] offset in the IO/StringIO
|
|
50
|
+
def initialize(context, offset = 0, decrypter = nil)
|
|
51
|
+
super()
|
|
52
|
+
@archive_io = get_io(context, offset)
|
|
53
|
+
@decompressor = ::Zip::NullDecompressor
|
|
54
|
+
@decrypter = decrypter || ::Zip::NullDecrypter.new
|
|
55
|
+
@current_entry = nil
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def close
|
|
59
|
+
@archive_io.close
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Returns a Entry object. It is necessary to call this
|
|
63
|
+
# method on a newly created InputStream before reading from
|
|
64
|
+
# the first entry in the archive. Returns nil when there are
|
|
65
|
+
# no more entries.
|
|
66
|
+
def get_next_entry
|
|
67
|
+
@archive_io.seek(@current_entry.next_header_offset, IO::SEEK_SET) if @current_entry
|
|
68
|
+
open_entry
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Rewinds the stream to the beginning of the current entry
|
|
72
|
+
def rewind
|
|
73
|
+
return if @current_entry.nil?
|
|
74
|
+
@lineno = 0
|
|
75
|
+
@pos = 0
|
|
76
|
+
@archive_io.seek(@current_entry.local_header_offset, IO::SEEK_SET)
|
|
77
|
+
open_entry
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Modeled after IO.sysread
|
|
81
|
+
def sysread(number_of_bytes = nil, buf = nil)
|
|
82
|
+
@decompressor.sysread(number_of_bytes, buf)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def eof
|
|
86
|
+
@output_buffer.empty? && @decompressor.eof
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
alias :eof? :eof
|
|
90
|
+
|
|
91
|
+
class << self
|
|
92
|
+
# Same as #initialize but if a block is passed the opened
|
|
93
|
+
# stream is passed to the block and closed when the block
|
|
94
|
+
# returns.
|
|
95
|
+
def open(filename_or_io, offset = 0, decrypter = nil)
|
|
96
|
+
zio = self.new(filename_or_io, offset, decrypter)
|
|
97
|
+
return zio unless block_given?
|
|
98
|
+
begin
|
|
99
|
+
yield zio
|
|
100
|
+
ensure
|
|
101
|
+
zio.close if zio
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def open_buffer(filename_or_io, offset = 0)
|
|
106
|
+
puts "open_buffer is deprecated!!! Use open instead!"
|
|
107
|
+
self.open(filename_or_io, offset)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
protected
|
|
112
|
+
|
|
113
|
+
def get_io(io_or_file, offset = 0)
|
|
114
|
+
case io_or_file
|
|
115
|
+
when IO, StringIO
|
|
116
|
+
io = io_or_file.dup
|
|
117
|
+
io.seek(offset, ::IO::SEEK_SET)
|
|
118
|
+
io
|
|
119
|
+
else
|
|
120
|
+
file = ::File.open(io_or_file, 'rb')
|
|
121
|
+
file.seek(offset, ::IO::SEEK_SET)
|
|
122
|
+
file
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def open_entry
|
|
127
|
+
@current_entry = ::Zip::Entry.read_local_entry(@archive_io)
|
|
128
|
+
if @current_entry and @current_entry.gp_flags & 1 == 1 and @decrypter.is_a? NullEncrypter
|
|
129
|
+
raise Error, 'password required to decode zip file'
|
|
130
|
+
end
|
|
131
|
+
@decompressor = get_decompressor
|
|
132
|
+
flush
|
|
133
|
+
@current_entry
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def get_decompressor
|
|
137
|
+
case
|
|
138
|
+
when @current_entry.nil?
|
|
139
|
+
::Zip::NullDecompressor
|
|
140
|
+
when @current_entry.compression_method == ::Zip::Entry::STORED
|
|
141
|
+
::Zip::PassThruDecompressor.new(@archive_io, @current_entry.size)
|
|
142
|
+
when @current_entry.compression_method == ::Zip::Entry::DEFLATED
|
|
143
|
+
header = @archive_io.read(@decrypter.header_bytesize)
|
|
144
|
+
@decrypter.reset!(header)
|
|
145
|
+
::Zip::Inflater.new(@archive_io, @decrypter)
|
|
146
|
+
else
|
|
147
|
+
raise ::Zip::CompressionMethodError,
|
|
148
|
+
"Unsupported compression method #{@current_entry.compression_method}"
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def produce_input
|
|
153
|
+
@decompressor.produce_input
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def input_finished?
|
|
157
|
+
@decompressor.input_finished?
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
|
163
|
+
# rubyzip is free software; you can redistribute it and/or
|
|
164
|
+
# modify it under the terms of the ruby license.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
module Zip
|
|
2
|
+
module IOExtras
|
|
3
|
+
# Implements many of the convenience methods of IO
|
|
4
|
+
# such as gets, getc, readline and readlines
|
|
5
|
+
# depends on: input_finished?, produce_input and read
|
|
6
|
+
module AbstractInputStream
|
|
7
|
+
include Enumerable
|
|
8
|
+
include FakeIO
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
super
|
|
12
|
+
@lineno = 0
|
|
13
|
+
@pos = 0
|
|
14
|
+
@output_buffer = ''
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
attr_accessor :lineno
|
|
18
|
+
attr_reader :pos
|
|
19
|
+
|
|
20
|
+
def read(number_of_bytes = nil, buf = '')
|
|
21
|
+
tbuf = if @output_buffer.bytesize > 0
|
|
22
|
+
if number_of_bytes <= @output_buffer.bytesize
|
|
23
|
+
@output_buffer.slice!(0, number_of_bytes)
|
|
24
|
+
else
|
|
25
|
+
number_of_bytes -= @output_buffer.bytesize if number_of_bytes
|
|
26
|
+
rbuf = sysread(number_of_bytes, buf)
|
|
27
|
+
out = @output_buffer
|
|
28
|
+
out << rbuf if rbuf
|
|
29
|
+
@output_buffer = ''
|
|
30
|
+
out
|
|
31
|
+
end
|
|
32
|
+
else
|
|
33
|
+
sysread(number_of_bytes, buf)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if tbuf.nil? || tbuf.length == 0
|
|
37
|
+
return nil if number_of_bytes
|
|
38
|
+
return ""
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
@pos += tbuf.length
|
|
42
|
+
|
|
43
|
+
if buf
|
|
44
|
+
buf.replace(tbuf)
|
|
45
|
+
else
|
|
46
|
+
buf = tbuf
|
|
47
|
+
end
|
|
48
|
+
buf
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def readlines(a_sep_string = $/)
|
|
52
|
+
ret_val = []
|
|
53
|
+
each_line(a_sep_string) { |line| ret_val << line }
|
|
54
|
+
ret_val
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def gets(a_sep_string = $/, number_of_bytes = nil)
|
|
58
|
+
@lineno = @lineno.next
|
|
59
|
+
|
|
60
|
+
if number_of_bytes.respond_to?(:to_int)
|
|
61
|
+
number_of_bytes = number_of_bytes.to_int
|
|
62
|
+
a_sep_string = a_sep_string.to_str if a_sep_string
|
|
63
|
+
elsif a_sep_string.respond_to?(:to_int)
|
|
64
|
+
number_of_bytes = a_sep_string.to_int
|
|
65
|
+
a_sep_string = $/
|
|
66
|
+
else
|
|
67
|
+
number_of_bytes = nil
|
|
68
|
+
a_sep_string = a_sep_string.to_str if a_sep_string
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
return read(number_of_bytes) if a_sep_string.nil?
|
|
72
|
+
a_sep_string = "#{$/}#{$/}" if a_sep_string.empty?
|
|
73
|
+
|
|
74
|
+
buffer_index = 0
|
|
75
|
+
over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes)
|
|
76
|
+
while (match_index = @output_buffer.index(a_sep_string, buffer_index)).nil? && !over_limit
|
|
77
|
+
buffer_index = [buffer_index, @output_buffer.bytesize - a_sep_string.bytesize].max
|
|
78
|
+
if input_finished?
|
|
79
|
+
return @output_buffer.empty? ? nil : flush
|
|
80
|
+
end
|
|
81
|
+
@output_buffer << produce_input
|
|
82
|
+
over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes)
|
|
83
|
+
end
|
|
84
|
+
sep_index = [match_index + a_sep_string.bytesize, number_of_bytes || @output_buffer.bytesize].min
|
|
85
|
+
@pos += sep_index
|
|
86
|
+
return @output_buffer.slice!(0...sep_index)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def ungetc(byte)
|
|
90
|
+
@output_buffer = byte.chr + @output_buffer
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def flush
|
|
94
|
+
ret_val = @output_buffer
|
|
95
|
+
@output_buffer = ''
|
|
96
|
+
ret_val
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def readline(a_sep_string = $/)
|
|
100
|
+
ret_val = gets(a_sep_string)
|
|
101
|
+
raise EOFError unless ret_val
|
|
102
|
+
ret_val
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def each_line(a_sep_string = $/)
|
|
106
|
+
while true
|
|
107
|
+
yield readline(a_sep_string)
|
|
108
|
+
end
|
|
109
|
+
rescue EOFError
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
alias_method :each, :each_line
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Zip
|
|
2
|
+
module IOExtras
|
|
3
|
+
# Implements many of the output convenience methods of IO.
|
|
4
|
+
# relies on <<
|
|
5
|
+
module AbstractOutputStream
|
|
6
|
+
include FakeIO
|
|
7
|
+
|
|
8
|
+
def write(data)
|
|
9
|
+
self << data
|
|
10
|
+
data.to_s.bytesize
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def print(*params)
|
|
15
|
+
self << params.join($,) << $\.to_s
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def printf(a_format_string, *params)
|
|
19
|
+
self << sprintf(a_format_string, *params)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def putc(an_object)
|
|
23
|
+
self << case an_object
|
|
24
|
+
when Fixnum
|
|
25
|
+
an_object.chr
|
|
26
|
+
when String
|
|
27
|
+
an_object
|
|
28
|
+
else
|
|
29
|
+
raise TypeError, 'putc: Only Fixnum and String supported'
|
|
30
|
+
end
|
|
31
|
+
an_object
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def puts(*params)
|
|
35
|
+
params << "\n" if params.empty?
|
|
36
|
+
params.flatten.each do |element|
|
|
37
|
+
val = element.to_s
|
|
38
|
+
self << val
|
|
39
|
+
self << "\n" unless val[-1, 1] == "\n"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Zip
|
|
2
|
+
module IOExtras #:nodoc:
|
|
3
|
+
|
|
4
|
+
CHUNK_SIZE = 131072
|
|
5
|
+
|
|
6
|
+
RANGE_ALL = 0..-1
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
def copy_stream(ostream, istream)
|
|
10
|
+
ostream.write(istream.read(CHUNK_SIZE, '')) until istream.eof?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def copy_stream_n(ostream, istream, nbytes)
|
|
14
|
+
toread = nbytes
|
|
15
|
+
while toread > 0 && !istream.eof?
|
|
16
|
+
tr = toread > CHUNK_SIZE ? CHUNK_SIZE : toread
|
|
17
|
+
ostream.write(istream.read(tr, ''))
|
|
18
|
+
toread -= tr
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Implements kind_of? in order to pretend to be an IO object
|
|
24
|
+
module FakeIO
|
|
25
|
+
def kind_of?(object)
|
|
26
|
+
object == IO || super
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end # IOExtras namespace module
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
require 'zip/ioextras/abstract_input_stream'
|
|
34
|
+
require 'zip/ioextras/abstract_output_stream'
|
|
35
|
+
|
|
36
|
+
# Copyright (C) 2002-2004 Thomas Sondergaard
|
|
37
|
+
# rubyzip is free software; you can redistribute it and/or
|
|
38
|
+
# modify it under the terms of the ruby license.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Zip
|
|
2
|
+
class NullCompressor < Compressor #:nodoc:all
|
|
3
|
+
include Singleton
|
|
4
|
+
|
|
5
|
+
def <<(data)
|
|
6
|
+
raise IOError, "closed stream"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
attr_reader :size, :compressed_size
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
|
14
|
+
# rubyzip is free software; you can redistribute it and/or
|
|
15
|
+
# modify it under the terms of the ruby license.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Zip
|
|
2
|
+
module NullDecompressor #:nodoc:all
|
|
3
|
+
extend self
|
|
4
|
+
|
|
5
|
+
def sysread(numberOfBytes = nil, buf = nil)
|
|
6
|
+
nil
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def produce_input
|
|
10
|
+
nil
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def input_finished?
|
|
14
|
+
true
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def eof
|
|
18
|
+
true
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
alias :eof? :eof
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
|
26
|
+
# rubyzip is free software; you can redistribute it and/or
|
|
27
|
+
# modify it under the terms of the ruby license.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module Zip
|
|
2
|
+
module NullInputStream #:nodoc:all
|
|
3
|
+
include ::Zip::NullDecompressor
|
|
4
|
+
include ::Zip::IOExtras::AbstractInputStream
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
|
9
|
+
# rubyzip is free software; you can redistribute it and/or
|
|
10
|
+
# modify it under the terms of the ruby license.
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
module Zip
|
|
2
|
+
# ZipOutputStream is the basic class for writing zip files. It is
|
|
3
|
+
# possible to create a ZipOutputStream object directly, passing
|
|
4
|
+
# the zip file name to the constructor, but more often than not
|
|
5
|
+
# the ZipOutputStream will be obtained from a ZipFile (perhaps using the
|
|
6
|
+
# ZipFileSystem interface) object for a particular entry in the zip
|
|
7
|
+
# archive.
|
|
8
|
+
#
|
|
9
|
+
# A ZipOutputStream inherits IOExtras::AbstractOutputStream in order
|
|
10
|
+
# to provide an IO-like interface for writing to a single zip
|
|
11
|
+
# entry. Beyond methods for mimicking an IO-object it contains
|
|
12
|
+
# the method put_next_entry that closes the current entry
|
|
13
|
+
# and creates a new.
|
|
14
|
+
#
|
|
15
|
+
# Please refer to ZipInputStream for example code.
|
|
16
|
+
#
|
|
17
|
+
# java.util.zip.ZipOutputStream is the original inspiration for this
|
|
18
|
+
# class.
|
|
19
|
+
|
|
20
|
+
class OutputStream
|
|
21
|
+
include ::Zip::IOExtras::AbstractOutputStream
|
|
22
|
+
|
|
23
|
+
attr_accessor :comment
|
|
24
|
+
|
|
25
|
+
# Opens the indicated zip file. If a file with that name already
|
|
26
|
+
# exists it will be overwritten.
|
|
27
|
+
def initialize(file_name, stream=false, encrypter=nil)
|
|
28
|
+
super()
|
|
29
|
+
@file_name = file_name
|
|
30
|
+
@output_stream = if stream
|
|
31
|
+
iostream = @file_name.dup
|
|
32
|
+
iostream.reopen(@file_name)
|
|
33
|
+
iostream.rewind
|
|
34
|
+
iostream
|
|
35
|
+
else
|
|
36
|
+
::File.new(@file_name, "wb")
|
|
37
|
+
end
|
|
38
|
+
@entry_set = ::Zip::EntrySet.new
|
|
39
|
+
@compressor = ::Zip::NullCompressor.instance
|
|
40
|
+
@encrypter = encrypter || ::Zip::NullEncrypter.new
|
|
41
|
+
@closed = false
|
|
42
|
+
@current_entry = nil
|
|
43
|
+
@comment = nil
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Same as #initialize but if a block is passed the opened
|
|
47
|
+
# stream is passed to the block and closed when the block
|
|
48
|
+
# returns.
|
|
49
|
+
class << self
|
|
50
|
+
def open(file_name, encrypter = nil)
|
|
51
|
+
return new(file_name) unless block_given?
|
|
52
|
+
zos = new(file_name, false, encrypter)
|
|
53
|
+
yield zos
|
|
54
|
+
ensure
|
|
55
|
+
zos.close if zos
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Same as #open but writes to a filestream instead
|
|
59
|
+
def write_buffer(io = ::StringIO.new(''), encrypter = nil)
|
|
60
|
+
zos = new(io, true, encrypter)
|
|
61
|
+
yield zos
|
|
62
|
+
zos.close_buffer
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Closes the stream and writes the central directory to the zip file
|
|
67
|
+
def close
|
|
68
|
+
return if @closed
|
|
69
|
+
finalize_current_entry
|
|
70
|
+
update_local_headers
|
|
71
|
+
write_central_directory
|
|
72
|
+
@output_stream.close
|
|
73
|
+
@closed = true
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Closes the stream and writes the central directory to the zip file
|
|
77
|
+
def close_buffer
|
|
78
|
+
return @output_stream if @closed
|
|
79
|
+
finalize_current_entry
|
|
80
|
+
update_local_headers
|
|
81
|
+
write_central_directory
|
|
82
|
+
@closed = true
|
|
83
|
+
@output_stream
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Closes the current entry and opens a new for writing.
|
|
87
|
+
# +entry+ can be a ZipEntry object or a string.
|
|
88
|
+
def put_next_entry(entry_name, comment = nil, extra = nil, compression_method = Entry::DEFLATED, level = Zip.default_compression)
|
|
89
|
+
raise Error, "zip stream is closed" if @closed
|
|
90
|
+
if entry_name.kind_of?(Entry)
|
|
91
|
+
new_entry = entry_name
|
|
92
|
+
else
|
|
93
|
+
new_entry = Entry.new(@file_name, entry_name.to_s)
|
|
94
|
+
end
|
|
95
|
+
new_entry.comment = comment unless comment.nil?
|
|
96
|
+
unless extra.nil?
|
|
97
|
+
new_entry.extra = ExtraField === extra ? extra : ExtraField.new(extra.to_s)
|
|
98
|
+
end
|
|
99
|
+
new_entry.compression_method = compression_method unless compression_method.nil?
|
|
100
|
+
init_next_entry(new_entry, level)
|
|
101
|
+
@current_entry = new_entry
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def copy_raw_entry(entry)
|
|
105
|
+
entry = entry.dup
|
|
106
|
+
raise Error, "zip stream is closed" if @closed
|
|
107
|
+
raise Error, "entry is not a ZipEntry" unless entry.is_a?(Entry)
|
|
108
|
+
finalize_current_entry
|
|
109
|
+
@entry_set << entry
|
|
110
|
+
src_pos = entry.local_header_offset
|
|
111
|
+
entry.write_local_entry(@output_stream)
|
|
112
|
+
@compressor = NullCompressor.instance
|
|
113
|
+
entry.get_raw_input_stream do |is|
|
|
114
|
+
is.seek(src_pos, IO::SEEK_SET)
|
|
115
|
+
::Zip::Entry.read_local_entry(is)
|
|
116
|
+
IOExtras.copy_stream_n(@output_stream, is, entry.compressed_size)
|
|
117
|
+
end
|
|
118
|
+
@compressor = NullCompressor.instance
|
|
119
|
+
@current_entry = nil
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
private
|
|
123
|
+
|
|
124
|
+
def finalize_current_entry
|
|
125
|
+
return unless @current_entry
|
|
126
|
+
@output_stream << @encrypter.header(@current_entry.mtime)
|
|
127
|
+
finish
|
|
128
|
+
@current_entry.compressed_size = @output_stream.tell - @current_entry.local_header_offset - @current_entry.calculate_local_header_size
|
|
129
|
+
@current_entry.size = @compressor.size
|
|
130
|
+
@current_entry.crc = @compressor.crc
|
|
131
|
+
@output_stream << @encrypter.data_descriptor(@current_entry.crc, @current_entry.compressed_size, @current_entry.size)
|
|
132
|
+
@current_entry.gp_flags |= @encrypter.gp_flags
|
|
133
|
+
@current_entry = nil
|
|
134
|
+
@compressor = ::Zip::NullCompressor.instance
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def init_next_entry(entry, level = Zip.default_compression)
|
|
138
|
+
finalize_current_entry
|
|
139
|
+
@entry_set << entry
|
|
140
|
+
entry.write_local_entry(@output_stream)
|
|
141
|
+
@encrypter.reset!
|
|
142
|
+
@compressor = get_compressor(entry, level)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def get_compressor(entry, level)
|
|
146
|
+
case entry.compression_method
|
|
147
|
+
when Entry::DEFLATED then
|
|
148
|
+
::Zip::Deflater.new(@output_stream, level, @encrypter)
|
|
149
|
+
when Entry::STORED then
|
|
150
|
+
::Zip::PassThruCompressor.new(@output_stream)
|
|
151
|
+
else
|
|
152
|
+
raise ::Zip::CompressionMethodError,
|
|
153
|
+
"Invalid compression method: '#{entry.compression_method}'"
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def update_local_headers
|
|
158
|
+
pos = @output_stream.pos
|
|
159
|
+
@entry_set.each do |entry|
|
|
160
|
+
@output_stream.pos = entry.local_header_offset
|
|
161
|
+
entry.write_local_entry(@output_stream, true)
|
|
162
|
+
end
|
|
163
|
+
@output_stream.pos = pos
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def write_central_directory
|
|
167
|
+
cdir = CentralDirectory.new(@entry_set, @comment)
|
|
168
|
+
cdir.write_to_stream(@output_stream)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
protected
|
|
172
|
+
|
|
173
|
+
def finish
|
|
174
|
+
@compressor.finish
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
public
|
|
178
|
+
|
|
179
|
+
# Modeled after IO.<<
|
|
180
|
+
def << (data)
|
|
181
|
+
@compressor << data
|
|
182
|
+
self
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
|
189
|
+
# rubyzip is free software; you can redistribute it and/or
|
|
190
|
+
# modify it under the terms of the ruby license.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Zip
|
|
2
|
+
class PassThruCompressor < Compressor #:nodoc:all
|
|
3
|
+
def initialize(outputStream)
|
|
4
|
+
super()
|
|
5
|
+
@output_stream = outputStream
|
|
6
|
+
@crc = Zlib::crc32
|
|
7
|
+
@size = 0
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def << (data)
|
|
11
|
+
val = data.to_s
|
|
12
|
+
@crc = Zlib::crc32(val, @crc)
|
|
13
|
+
@size += val.bytesize
|
|
14
|
+
@output_stream << val
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
attr_reader :size, :crc
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
|
22
|
+
# rubyzip is free software; you can redistribute it and/or
|
|
23
|
+
# modify it under the terms of the ruby license.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Zip
|
|
2
|
+
class PassThruDecompressor < Decompressor #:nodoc:all
|
|
3
|
+
|
|
4
|
+
def initialize(input_stream, chars_to_read)
|
|
5
|
+
super(input_stream)
|
|
6
|
+
@chars_to_read = chars_to_read
|
|
7
|
+
@read_so_far = 0
|
|
8
|
+
@has_returned_empty_string = false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def sysread(number_of_bytes = nil, buf = '')
|
|
12
|
+
if input_finished?
|
|
13
|
+
has_returned_empty_string_val = @has_returned_empty_string
|
|
14
|
+
@has_returned_empty_string = true
|
|
15
|
+
return '' unless has_returned_empty_string_val
|
|
16
|
+
return
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
if number_of_bytes.nil? || @read_so_far + number_of_bytes > @chars_to_read
|
|
20
|
+
number_of_bytes = @chars_to_read - @read_so_far
|
|
21
|
+
end
|
|
22
|
+
@read_so_far += number_of_bytes
|
|
23
|
+
@input_stream.read(number_of_bytes, buf)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def produce_input
|
|
27
|
+
sysread(::Zip::Decompressor::CHUNK_SIZE)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def input_finished?
|
|
31
|
+
@read_so_far >= @chars_to_read
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
alias :eof :input_finished?
|
|
35
|
+
alias :eof? :input_finished?
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
|
40
|
+
# rubyzip is free software; you can redistribute it and/or
|
|
41
|
+
# modify it under the terms of the ruby license.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module Zip
|
|
2
|
+
class StreamableDirectory < Entry
|
|
3
|
+
def initialize(zipfile, entry, srcPath = nil, permissionInt = nil)
|
|
4
|
+
super(zipfile, entry)
|
|
5
|
+
|
|
6
|
+
@ftype = :directory
|
|
7
|
+
entry.get_extra_attributes_from_path(srcPath) if (srcPath)
|
|
8
|
+
@unix_perms = permissionInt if (permissionInt)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
|
14
|
+
# rubyzip is free software; you can redistribute it and/or
|
|
15
|
+
# modify it under the terms of the ruby license.
|