rubyzip 0.9.9 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (135) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +284 -41
  3. data/Rakefile +11 -6
  4. data/TODO +0 -1
  5. data/lib/zip/central_directory.rb +208 -0
  6. data/lib/zip/compressor.rb +1 -2
  7. data/lib/zip/constants.rb +59 -7
  8. data/lib/zip/crypto/encryption.rb +11 -0
  9. data/lib/zip/crypto/null_encryption.rb +43 -0
  10. data/lib/zip/crypto/traditional_encryption.rb +99 -0
  11. data/lib/zip/decompressor.rb +4 -4
  12. data/lib/zip/deflater.rb +17 -13
  13. data/lib/zip/dos_time.rb +13 -14
  14. data/lib/zip/entry.rb +700 -0
  15. data/lib/zip/entry_set.rb +86 -0
  16. data/lib/zip/errors.rb +18 -0
  17. data/lib/zip/extra_field/generic.rb +43 -0
  18. data/lib/zip/extra_field/ntfs.rb +90 -0
  19. data/lib/zip/extra_field/old_unix.rb +44 -0
  20. data/lib/zip/extra_field/universal_time.rb +47 -0
  21. data/lib/zip/extra_field/unix.rb +37 -0
  22. data/lib/zip/extra_field/zip64.rb +68 -0
  23. data/lib/zip/extra_field/zip64_placeholder.rb +15 -0
  24. data/lib/zip/extra_field.rb +101 -0
  25. data/lib/zip/file.rb +443 -0
  26. data/lib/zip/{zipfilesystem.rb → filesystem.rb} +162 -157
  27. data/lib/zip/inflater.rb +29 -28
  28. data/lib/zip/input_stream.rb +173 -0
  29. data/lib/zip/ioextras/abstract_input_stream.rb +111 -0
  30. data/lib/zip/ioextras/abstract_output_stream.rb +43 -0
  31. data/lib/zip/ioextras.rb +21 -149
  32. data/lib/zip/null_compressor.rb +2 -2
  33. data/lib/zip/null_decompressor.rb +8 -6
  34. data/lib/zip/null_input_stream.rb +3 -2
  35. data/lib/zip/output_stream.rb +189 -0
  36. data/lib/zip/pass_thru_compressor.rb +6 -6
  37. data/lib/zip/pass_thru_decompressor.rb +19 -19
  38. data/lib/zip/{zip_streamable_directory.rb → streamable_directory.rb} +3 -3
  39. data/lib/zip/streamable_stream.rb +56 -0
  40. data/lib/zip/version.rb +3 -0
  41. data/lib/zip.rb +71 -0
  42. data/samples/example.rb +44 -32
  43. data/samples/example_filesystem.rb +16 -18
  44. data/samples/example_recursive.rb +33 -28
  45. data/samples/{gtkRubyzip.rb → gtk_ruby_zip.rb} +26 -28
  46. data/samples/qtzip.rb +22 -31
  47. data/samples/write_simple.rb +12 -13
  48. data/samples/zipfind.rb +31 -39
  49. data/test/basic_zip_file_test.rb +60 -0
  50. data/test/case_sensitivity_test.rb +69 -0
  51. data/test/central_directory_entry_test.rb +69 -0
  52. data/test/central_directory_test.rb +100 -0
  53. data/test/crypto/null_encryption_test.rb +57 -0
  54. data/test/crypto/traditional_encryption_test.rb +80 -0
  55. data/test/data/WarnInvalidDate.zip +0 -0
  56. data/test/data/file1.txt +46 -0
  57. data/test/data/file1.txt.deflatedData +0 -0
  58. data/test/data/file2.txt +1504 -0
  59. data/test/data/globTest/foo/bar/baz/foo.txt +0 -0
  60. data/test/data/globTest/foo.txt +0 -0
  61. data/test/data/globTest/food.txt +0 -0
  62. data/test/data/globTest.zip +0 -0
  63. data/test/data/gpbit3stored.zip +0 -0
  64. data/test/data/mimetype +1 -0
  65. data/test/data/notzippedruby.rb +7 -0
  66. data/test/data/ntfs.zip +0 -0
  67. data/test/data/oddExtraField.zip +0 -0
  68. data/test/data/path_traversal/Makefile +10 -0
  69. data/test/data/path_traversal/jwilk/README.md +5 -0
  70. data/test/data/path_traversal/jwilk/absolute1.zip +0 -0
  71. data/test/data/path_traversal/jwilk/absolute2.zip +0 -0
  72. data/test/data/path_traversal/jwilk/dirsymlink.zip +0 -0
  73. data/test/data/path_traversal/jwilk/dirsymlink2a.zip +0 -0
  74. data/test/data/path_traversal/jwilk/dirsymlink2b.zip +0 -0
  75. data/test/data/path_traversal/jwilk/relative0.zip +0 -0
  76. data/test/data/path_traversal/jwilk/relative2.zip +0 -0
  77. data/test/data/path_traversal/jwilk/symlink.zip +0 -0
  78. data/test/data/path_traversal/relative1.zip +0 -0
  79. data/test/data/path_traversal/tilde.zip +0 -0
  80. data/test/data/path_traversal/tuzovakaoff/README.md +3 -0
  81. data/test/data/path_traversal/tuzovakaoff/absolutepath.zip +0 -0
  82. data/test/data/path_traversal/tuzovakaoff/symlink.zip +0 -0
  83. data/test/data/rubycode.zip +0 -0
  84. data/test/data/rubycode2.zip +0 -0
  85. data/test/data/test.xls +0 -0
  86. data/test/data/testDirectory.bin +0 -0
  87. data/test/data/zip64-sample.zip +0 -0
  88. data/test/data/zipWithDirs.zip +0 -0
  89. data/test/data/zipWithEncryption.zip +0 -0
  90. data/test/deflater_test.rb +65 -0
  91. data/test/encryption_test.rb +42 -0
  92. data/test/entry_set_test.rb +163 -0
  93. data/test/entry_test.rb +154 -0
  94. data/test/errors_test.rb +35 -0
  95. data/test/extra_field_test.rb +76 -0
  96. data/test/file_extract_directory_test.rb +54 -0
  97. data/test/file_extract_test.rb +145 -0
  98. data/test/file_permissions_test.rb +65 -0
  99. data/test/file_split_test.rb +57 -0
  100. data/test/file_test.rb +666 -0
  101. data/test/filesystem/dir_iterator_test.rb +58 -0
  102. data/test/filesystem/directory_test.rb +139 -0
  103. data/test/filesystem/file_mutating_test.rb +87 -0
  104. data/test/filesystem/file_nonmutating_test.rb +508 -0
  105. data/test/filesystem/file_stat_test.rb +64 -0
  106. data/test/gentestfiles.rb +126 -0
  107. data/test/inflater_test.rb +14 -0
  108. data/test/input_stream_test.rb +182 -0
  109. data/test/ioextras/abstract_input_stream_test.rb +102 -0
  110. data/test/ioextras/abstract_output_stream_test.rb +106 -0
  111. data/test/ioextras/fake_io_test.rb +18 -0
  112. data/test/local_entry_test.rb +154 -0
  113. data/test/output_stream_test.rb +128 -0
  114. data/test/pass_thru_compressor_test.rb +30 -0
  115. data/test/pass_thru_decompressor_test.rb +14 -0
  116. data/test/path_traversal_test.rb +141 -0
  117. data/test/samples/example_recursive_test.rb +37 -0
  118. data/test/settings_test.rb +95 -0
  119. data/test/test_helper.rb +234 -0
  120. data/test/unicode_file_names_and_comments_test.rb +62 -0
  121. data/test/zip64_full_test.rb +51 -0
  122. data/test/zip64_support_test.rb +14 -0
  123. metadata +274 -41
  124. data/NEWS +0 -172
  125. data/lib/zip/settings.rb +0 -10
  126. data/lib/zip/tempfile_bugfixed.rb +0 -195
  127. data/lib/zip/zip.rb +0 -56
  128. data/lib/zip/zip_central_directory.rb +0 -135
  129. data/lib/zip/zip_entry.rb +0 -638
  130. data/lib/zip/zip_entry_set.rb +0 -77
  131. data/lib/zip/zip_extra_field.rb +0 -213
  132. data/lib/zip/zip_file.rb +0 -340
  133. data/lib/zip/zip_input_stream.rb +0 -144
  134. data/lib/zip/zip_output_stream.rb +0 -173
  135. data/lib/zip/zip_streamable_stream.rb +0 -47
data/lib/zip/inflater.rb CHANGED
@@ -1,61 +1,62 @@
1
1
  module Zip
2
- class Inflater < Decompressor #:nodoc:all
3
- def initialize(inputStream)
4
- super
5
- @zlibInflater = Zlib::Inflate.new(-Zlib::MAX_WBITS)
6
- @outputBuffer=""
7
- @hasReturnedEmptyString = ! EMPTY_FILE_RETURNS_EMPTY_STRING_FIRST
2
+ class Inflater < Decompressor #:nodoc:all
3
+ def initialize(input_stream, decrypter = NullDecrypter.new)
4
+ super(input_stream)
5
+ @zlib_inflater = ::Zlib::Inflate.new(-Zlib::MAX_WBITS)
6
+ @output_buffer = ''.dup
7
+ @has_returned_empty_string = false
8
+ @decrypter = decrypter
8
9
  end
9
10
 
10
- def sysread(numberOfBytes = nil, buf = nil)
11
- readEverything = numberOfBytes.nil?
12
- while (readEverything || @outputBuffer.bytesize < numberOfBytes)
11
+ def sysread(number_of_bytes = nil, buf = '')
12
+ readEverything = number_of_bytes.nil?
13
+ while readEverything || @output_buffer.bytesize < number_of_bytes
13
14
  break if internal_input_finished?
14
- @outputBuffer << internal_produce_input(buf)
15
+ @output_buffer << internal_produce_input(buf)
15
16
  end
16
- return value_when_finished if @outputBuffer.bytesize == 0 && input_finished?
17
- endIndex = numberOfBytes.nil? ? @outputBuffer.bytesize : numberOfBytes
18
- return @outputBuffer.slice!(0...endIndex)
17
+ return value_when_finished if @output_buffer.bytesize == 0 && input_finished?
18
+ end_index = number_of_bytes.nil? ? @output_buffer.bytesize : number_of_bytes
19
+ @output_buffer.slice!(0...end_index)
19
20
  end
20
21
 
21
22
  def produce_input
22
- if (@outputBuffer.empty?)
23
- return internal_produce_input
23
+ if @output_buffer.empty?
24
+ internal_produce_input
24
25
  else
25
- return @outputBuffer.slice!(0...(@outputBuffer.length))
26
+ @output_buffer.slice!(0...(@output_buffer.length))
26
27
  end
27
28
  end
28
29
 
29
30
  # to be used with produce_input, not read (as read may still have more data cached)
30
31
  # is data cached anywhere other than @outputBuffer? the comment above may be wrong
31
32
  def input_finished?
32
- @outputBuffer.empty? && internal_input_finished?
33
+ @output_buffer.empty? && internal_input_finished?
33
34
  end
34
- alias :eof :input_finished?
35
- alias :eof? :input_finished?
35
+
36
+ alias :eof input_finished?
37
+ alias :eof? input_finished?
36
38
 
37
39
  private
38
40
 
39
- def internal_produce_input(buf = nil)
41
+ def internal_produce_input(buf = '')
40
42
  retried = 0
41
43
  begin
42
- @zlibInflater.inflate(@inputStream.read(Decompressor::CHUNK_SIZE, buf))
44
+ @zlib_inflater.inflate(@decrypter.decrypt(@input_stream.read(Decompressor::CHUNK_SIZE, buf)))
43
45
  rescue Zlib::BufError
44
- raise if (retried >= 5) # how many times should we retry?
46
+ raise if retried >= 5 # how many times should we retry?
45
47
  retried += 1
46
48
  retry
47
49
  end
48
50
  end
49
51
 
50
52
  def internal_input_finished?
51
- @zlibInflater.finished?
53
+ @zlib_inflater.finished?
52
54
  end
53
55
 
54
- # TODO: Specialize to handle different behaviour in ruby > 1.7.0 ?
55
- def value_when_finished # mimic behaviour of ruby File object.
56
- return if @hasReturnedEmptyString
57
- @hasReturnedEmptyString = true
58
- return ""
56
+ def value_when_finished # mimic behaviour of ruby File object.
57
+ return if @has_returned_empty_string
58
+ @has_returned_empty_string = true
59
+ ''
59
60
  end
60
61
  end
61
62
  end
@@ -0,0 +1,173 @@
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 = 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
+ open(filename_or_io, offset)
108
+ end
109
+ end
110
+
111
+ protected
112
+
113
+ def get_io(io_or_file, offset = 0)
114
+ if io_or_file.respond_to?(:seek)
115
+ io = io_or_file.dup
116
+ io.seek(offset, ::IO::SEEK_SET)
117
+ io
118
+ else
119
+ file = ::File.open(io_or_file, 'rb')
120
+ file.seek(offset, ::IO::SEEK_SET)
121
+ file
122
+ end
123
+ end
124
+
125
+ def open_entry
126
+ @current_entry = ::Zip::Entry.read_local_entry(@archive_io)
127
+ if @current_entry && @current_entry.gp_flags & 1 == 1 && @decrypter.is_a?(NullEncrypter)
128
+ raise Error, 'password required to decode zip file'
129
+ end
130
+ if @current_entry && @current_entry.gp_flags & 8 == 8 && @current_entry.crc == 0 \
131
+ && @current_entry.compressed_size == 0 \
132
+ && @current_entry.size == 0 && !@complete_entry
133
+ raise GPFBit3Error,
134
+ 'General purpose flag Bit 3 is set so not possible to get proper info from local header.' \
135
+ 'Please use ::Zip::File instead of ::Zip::InputStream'
136
+ end
137
+ @decompressor = get_decompressor
138
+ flush
139
+ @current_entry
140
+ end
141
+
142
+ def get_decompressor
143
+ if @current_entry.nil?
144
+ ::Zip::NullDecompressor
145
+ elsif @current_entry.compression_method == ::Zip::Entry::STORED
146
+ if @current_entry.gp_flags & 8 == 8 && @current_entry.crc == 0 && @current_entry.size == 0 && @complete_entry
147
+ ::Zip::PassThruDecompressor.new(@archive_io, @complete_entry.size)
148
+ else
149
+ ::Zip::PassThruDecompressor.new(@archive_io, @current_entry.size)
150
+ end
151
+ elsif @current_entry.compression_method == ::Zip::Entry::DEFLATED
152
+ header = @archive_io.read(@decrypter.header_bytesize)
153
+ @decrypter.reset!(header)
154
+ ::Zip::Inflater.new(@archive_io, @decrypter)
155
+ else
156
+ raise ::Zip::CompressionMethodError,
157
+ "Unsupported compression method #{@current_entry.compression_method}"
158
+ end
159
+ end
160
+
161
+ def produce_input
162
+ @decompressor.produce_input
163
+ end
164
+
165
+ def input_finished?
166
+ @decompressor.input_finished?
167
+ end
168
+ end
169
+ end
170
+
171
+ # Copyright (C) 2002, 2003 Thomas Sondergaard
172
+ # rubyzip is free software; you can redistribute it and/or
173
+ # modify it under the terms of the ruby license.
@@ -0,0 +1,111 @@
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.empty?
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
+ return @output_buffer.empty? ? nil : flush if input_finished?
79
+ @output_buffer << produce_input
80
+ over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes)
81
+ end
82
+ sep_index = [match_index + a_sep_string.bytesize, number_of_bytes || @output_buffer.bytesize].min
83
+ @pos += sep_index
84
+ @output_buffer.slice!(0...sep_index)
85
+ end
86
+
87
+ def ungetc(byte)
88
+ @output_buffer = byte.chr + @output_buffer
89
+ end
90
+
91
+ def flush
92
+ ret_val = @output_buffer
93
+ @output_buffer = ''
94
+ ret_val
95
+ end
96
+
97
+ def readline(a_sep_string = $/)
98
+ ret_val = gets(a_sep_string)
99
+ raise EOFError unless ret_val
100
+ ret_val
101
+ end
102
+
103
+ def each_line(a_sep_string = $/)
104
+ yield readline(a_sep_string) while true
105
+ rescue EOFError
106
+ end
107
+
108
+ alias_method :each, :each_line
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,43 @@
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
+ def print(*params)
14
+ self << params.join($,) << $\.to_s
15
+ end
16
+
17
+ def printf(a_format_string, *params)
18
+ self << format(a_format_string, *params)
19
+ end
20
+
21
+ def putc(an_object)
22
+ self << case an_object
23
+ when Integer
24
+ an_object.chr
25
+ when String
26
+ an_object
27
+ else
28
+ raise TypeError, 'putc: Only Integer and String supported'
29
+ end
30
+ an_object
31
+ end
32
+
33
+ def puts(*params)
34
+ params << "\n" if params.empty?
35
+ params.flatten.each do |element|
36
+ val = element.to_s
37
+ self << val
38
+ self << "\n" unless val[-1, 1] == "\n"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
data/lib/zip/ioextras.rb CHANGED
@@ -1,163 +1,35 @@
1
- module IOExtras #:nodoc:
1
+ module Zip
2
+ module IOExtras #:nodoc:
3
+ CHUNK_SIZE = 131_072
2
4
 
3
- CHUNK_SIZE = 131072
5
+ RANGE_ALL = 0..-1
4
6
 
5
- RANGE_ALL = 0..-1
6
-
7
- def self.copy_stream(ostream, istream)
8
- s = ''
9
- ostream.write(istream.read(CHUNK_SIZE, s)) until istream.eof?
10
- end
11
-
12
- def self.copy_stream_n(ostream, istream, nbytes)
13
- s = ''
14
- toread = nbytes
15
- while (toread > 0 && ! istream.eof?)
16
- tr = toread > CHUNK_SIZE ? CHUNK_SIZE : toread
17
- ostream.write(istream.read(tr, s))
18
- toread -= tr
19
- end
20
- end
21
-
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
- # Implements many of the convenience methods of IO
31
- # such as gets, getc, readline and readlines
32
- # depends on: input_finished?, produce_input and read
33
- module AbstractInputStream
34
- include Enumerable
35
- include FakeIO
36
-
37
- def initialize
38
- super
39
- @lineno = 0
40
- @outputBuffer = ""
41
- end
42
-
43
- attr_accessor :lineno
44
-
45
- def read(numberOfBytes = nil, buf = nil)
46
- tbuf = nil
47
-
48
- if @outputBuffer.bytesize > 0
49
- if numberOfBytes <= @outputBuffer.bytesize
50
- tbuf = @outputBuffer.slice!(0, numberOfBytes)
51
- else
52
- numberOfBytes -= @outputBuffer.bytesize if (numberOfBytes)
53
- rbuf = sysread(numberOfBytes, buf)
54
- tbuf = @outputBuffer
55
- tbuf << rbuf if (rbuf)
56
- @outputBuffer = ""
57
- end
58
- else
59
- tbuf = sysread(numberOfBytes, buf)
60
- end
61
-
62
- return nil unless (tbuf)
63
-
64
- if buf
65
- buf.replace(tbuf)
66
- else
67
- buf = tbuf
7
+ class << self
8
+ def copy_stream(ostream, istream)
9
+ ostream.write(istream.read(CHUNK_SIZE, '')) until istream.eof?
68
10
  end
69
11
 
70
- buf
71
- end
72
-
73
- def readlines(aSepString = $/)
74
- retVal = []
75
- each_line(aSepString) { |line| retVal << line }
76
- retVal
77
- end
78
-
79
- def gets(aSepString = $/)
80
- @lineno = @lineno.next
81
- return read if aSepString.nil?
82
- aSepString = "#{$/}#{$/}" if aSepString.empty?
83
-
84
- bufferIndex = 0
85
- while ((matchIndex = @outputBuffer.index(aSepString, bufferIndex)) == nil)
86
- bufferIndex = @outputBuffer.bytesize
87
- if input_finished?
88
- return @outputBuffer.empty? ? nil : flush
12
+ def copy_stream_n(ostream, istream, nbytes)
13
+ toread = nbytes
14
+ while toread > 0 && !istream.eof?
15
+ tr = toread > CHUNK_SIZE ? CHUNK_SIZE : toread
16
+ ostream.write(istream.read(tr, ''))
17
+ toread -= tr
89
18
  end
90
- @outputBuffer << produce_input
91
19
  end
92
- sepIndex = matchIndex + aSepString.bytesize
93
- return @outputBuffer.slice!(0...sepIndex)
94
- end
95
-
96
- def flush
97
- retVal = @outputBuffer
98
- @outputBuffer=""
99
- return retVal
100
20
  end
101
21
 
102
- def readline(aSepString = $/)
103
- retVal = gets(aSepString)
104
- raise EOFError if retVal == nil
105
- retVal
106
- end
107
-
108
- def each_line(aSepString = $/)
109
- while true
110
- yield readline(aSepString)
22
+ # Implements kind_of? in order to pretend to be an IO object
23
+ module FakeIO
24
+ def kind_of?(object)
25
+ object == IO || super
111
26
  end
112
- rescue EOFError
113
27
  end
28
+ end # IOExtras namespace module
29
+ end
114
30
 
115
- alias_method :each, :each_line
116
- end
117
-
118
-
119
- # Implements many of the output convenience methods of IO.
120
- # relies on <<
121
- module AbstractOutputStream
122
- include FakeIO
123
-
124
- def write(data)
125
- self << data
126
- data.to_s.bytesize
127
- end
128
-
129
-
130
- def print(*params)
131
- self << params.join($,) << $\.to_s
132
- end
133
-
134
- def printf(aFormatString, *params)
135
- self << sprintf(aFormatString, *params)
136
- end
137
-
138
- def putc(anObject)
139
- self << case anObject
140
- when Fixnum then anObject.chr
141
- when String then anObject
142
- else raise TypeError, "putc: Only Fixnum and String supported"
143
- end
144
- anObject
145
- end
146
-
147
- def puts(*params)
148
- params << "\n" if params.empty?
149
- params.flatten.each do |element|
150
- val = element.to_s
151
- self << val
152
- self << "\n" unless val[-1,1] == "\n"
153
- end
154
- end
155
-
156
- end
157
-
158
- end # IOExtras namespace module
159
-
160
-
31
+ require 'zip/ioextras/abstract_input_stream'
32
+ require 'zip/ioextras/abstract_output_stream'
161
33
 
162
34
  # Copyright (C) 2002-2004 Thomas Sondergaard
163
35
  # rubyzip is free software; you can redistribute it and/or
@@ -2,8 +2,8 @@ module Zip
2
2
  class NullCompressor < Compressor #:nodoc:all
3
3
  include Singleton
4
4
 
5
- def << (data)
6
- raise IOError, "closed stream"
5
+ def <<(_data)
6
+ raise IOError, 'closed stream'
7
7
  end
8
8
 
9
9
  attr_reader :size, :compressed_size
@@ -1,14 +1,15 @@
1
1
  module Zip
2
- class NullDecompressor #:nodoc:all
3
- include Singleton
4
- def sysread(numberOfBytes = nil, buf = nil)
2
+ module NullDecompressor #:nodoc:all
3
+ module_function
4
+
5
+ def sysread(_numberOfBytes = nil, _buf = nil)
5
6
  nil
6
7
  end
7
-
8
+
8
9
  def produce_input
9
10
  nil
10
11
  end
11
-
12
+
12
13
  def input_finished?
13
14
  true
14
15
  end
@@ -16,7 +17,8 @@ module Zip
16
17
  def eof
17
18
  true
18
19
  end
19
- alias :eof? :eof
20
+
21
+ alias eof? eof
20
22
  end
21
23
  end
22
24
 
@@ -1,6 +1,7 @@
1
1
  module Zip
2
- class NullInputStream < NullDecompressor #:nodoc:all
3
- include IOExtras::AbstractInputStream
2
+ module NullInputStream #:nodoc:all
3
+ include ::Zip::NullDecompressor
4
+ include ::Zip::IOExtras::AbstractInputStream
4
5
  end
5
6
  end
6
7