rubyzip 0.9.9 → 1.3.0

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.
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