rubyzip 1.0.0.beta1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubyzip might be problematic. Click here for more details.
- checksums.yaml +14 -6
- data/NEWS +6 -0
- data/README.md +5 -3
- data/Rakefile +2 -2
- data/lib/zip/central_directory.rb +74 -32
- data/lib/zip/decompressor.rb +1 -1
- data/lib/zip/entry.rb +15 -2
- data/lib/zip/extra_field.rb +5 -6
- data/lib/zip/extra_field/unix.rb +2 -3
- data/lib/zip/extra_field/zip64.rb +30 -0
- data/lib/zip/file.rb +15 -14
- data/lib/zip/ioextras.rb +14 -162
- data/lib/zip/ioextras/abstract_input_stream.rb +108 -0
- data/lib/zip/ioextras/abstract_output_stream.rb +45 -0
- data/lib/zip/version.rb +2 -2
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NjQ3YjE3YmQ0MDUyYzViOThmNDBjNGVhYTRmNDdiNzAzZjYzNjZkOA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OGI5ZjFlYTk3NmQwMGY2NmM2NmVkYWI3ZjczMTVjNDAxYzg0YzY3Zg==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ODI3NzAwZDg5NzYyZDdjZTNlNDUyOWJjYmY0YTU0MGEzMjUwOTE5MjdkOTM3
|
10
|
+
ZjkzMTFjNzQzZmRlZDA4MTllZmU2N2NjMDQyMDM5NTRjMjg5ODVmMzUyODMw
|
11
|
+
ZGExYjk3MDkwNzRmYTJkYjhhYjNmMmY4YTIyYTQ2ODA4MDdiNzk=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MWM5ODRlNzdmNDNiOGE4ZjkzMWYzZTIxZTE4OTU1ZTVhZmQ4YzhhZGQ0ZWNi
|
14
|
+
N2Q4N2NhZmE1ZmJiZjFjMzcxMWI3YzgzNmRiNDVlZGYwZmYyZTJiNTljY2Yx
|
15
|
+
MTY4NGM1YjNhOGJiZmE2MGUyZTBjYTc2YzdjMzc0ZTE3NTIyZDc=
|
data/NEWS
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
= Version 1.0.0
|
2
|
+
|
3
|
+
Changed the API for gem. Now it can be used without require param in Gemfile.
|
4
|
+
Added read-only support for Zip64 files.
|
5
|
+
Added support for setting Unicode file names.
|
6
|
+
|
1
7
|
= Version 0.9.9
|
2
8
|
|
3
9
|
Added support for backslashes in zip files (generated by the default Windows
|
data/README.md
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
# rubyzip
|
1
|
+
# rubyzip
|
2
|
+
[![Build Status](https://secure.travis-ci.org/rubyzip/rubyzip.png)](http://travis-ci.org/rubyzip/rubyzip)
|
3
|
+
[![Code Climate](https://codeclimate.com/github/rubyzip/rubyzip.png)](https://codeclimate.com/github/rubyzip/rubyzip)
|
4
|
+
[![Coverage Status](https://coveralls.io/repos/rubyzip/rubyzip/badge.png?branch=master)](https://coveralls.io/r/rubyzip/rubyzip?branch=master)
|
2
5
|
|
3
6
|
rubyzip is a ruby library for reading and writing zip files.
|
4
7
|
|
5
8
|
## Important note
|
6
9
|
|
7
|
-
|
8
|
-
Rubyzip interface will be changed!!!
|
10
|
+
Rubyzip interface changed!!! No need to do `require "zip/zip"` and `Zip` prefix in class names removed.
|
9
11
|
|
10
12
|
## Installation
|
11
13
|
rubyzip is available on RubyGems, so:
|
data/Rakefile
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
2
|
require 'rake/testtask'
|
3
3
|
|
4
|
-
task :default =>
|
4
|
+
task :default => :test
|
5
5
|
|
6
6
|
Rake::TestTask.new(:test) do |test|
|
7
7
|
test.libs << File.join(File.dirname(__FILE__), 'lib')
|
8
8
|
test.libs << File.join(File.dirname(__FILE__), 'test')
|
9
9
|
test.pattern = File.join(File.dirname(__FILE__), 'test/alltests.rb')
|
10
10
|
test.verbose = true
|
11
|
-
|
11
|
+
|
12
12
|
end
|
13
13
|
|
@@ -2,9 +2,11 @@ module Zip
|
|
2
2
|
class CentralDirectory
|
3
3
|
include Enumerable
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
END_OF_CDS = 0x06054b50
|
6
|
+
ZIP64_END_OF_CDS = 0x06064b50
|
7
|
+
ZIP64_EOCD_LOCATOR = 0x07064b50
|
8
|
+
MAX_END_OF_CDS_SIZE = 65536 + 18
|
9
|
+
STATIC_EOCD_SIZE = 22
|
8
10
|
|
9
11
|
attr_reader :comment
|
10
12
|
|
@@ -13,10 +15,10 @@ module Zip
|
|
13
15
|
@entry_set.entries
|
14
16
|
end
|
15
17
|
|
16
|
-
def initialize(entries = EntrySet.new, comment =
|
18
|
+
def initialize(entries = EntrySet.new, comment = '') #:nodoc:
|
17
19
|
super()
|
18
20
|
@entry_set = entries.kind_of?(EntrySet) ? entries : EntrySet.new(entries)
|
19
|
-
@comment
|
21
|
+
@comment = comment
|
20
22
|
end
|
21
23
|
|
22
24
|
def write_to_stream(io) #:nodoc:
|
@@ -27,7 +29,7 @@ module Zip
|
|
27
29
|
|
28
30
|
def write_e_o_c_d(io, offset) #:nodoc:
|
29
31
|
tmp = [
|
30
|
-
|
32
|
+
END_OF_CDS,
|
31
33
|
0, # @numberOfThisDisk
|
32
34
|
0, # @numberOfDiskWithStartOfCDir
|
33
35
|
@entry_set ? @entry_set.size : 0,
|
@@ -43,7 +45,7 @@ module Zip
|
|
43
45
|
private :write_e_o_c_d
|
44
46
|
|
45
47
|
def cdir_size #:nodoc:
|
46
|
-
|
48
|
+
# does not include eocd
|
47
49
|
@entry_set.inject(0) do |value, entry|
|
48
50
|
entry.cdir_header_size + value
|
49
51
|
end
|
@@ -51,51 +53,91 @@ module Zip
|
|
51
53
|
|
52
54
|
private :cdir_size
|
53
55
|
|
54
|
-
def
|
55
|
-
buf
|
56
|
-
@
|
57
|
-
@
|
58
|
-
@
|
59
|
-
@
|
60
|
-
@
|
61
|
-
@
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
56
|
+
def read_64_e_o_c_d(buf) #:nodoc:
|
57
|
+
buf = get_64_e_o_c_d(buf)
|
58
|
+
@size_of_zip64_e_o_c_d = Entry.read_zip_64_long(buf)
|
59
|
+
@version_made_by = Entry.read_zip_short(buf)
|
60
|
+
@version_needed_for_extract = Entry.read_zip_short(buf)
|
61
|
+
@number_of_this_disk = Entry.read_zip_long(buf)
|
62
|
+
@number_of_disk_with_start_of_cdir = Entry.read_zip_long(buf)
|
63
|
+
@total_number_of_entries_in_cdir_on_this_disk = Entry.read_zip_64_long(buf)
|
64
|
+
@size = Entry.read_zip_64_long(buf)
|
65
|
+
@size_in_bytes = Entry.read_zip_64_long(buf)
|
66
|
+
@cdir_offset = Entry.read_zip_64_long(buf)
|
67
|
+
@zip_64_extensible = buf.slice!(0, buf.bytesize)
|
68
|
+
raise ZipError, "Zip consistency problem while reading eocd structure" unless buf.size == 0
|
69
|
+
end
|
70
|
+
|
71
|
+
def read_e_o_c_d(buf) #:nodoc:
|
72
|
+
buf = get_e_o_c_d(buf)
|
73
|
+
@number_of_this_disk = Entry.read_zip_short(buf)
|
74
|
+
@number_of_disk_with_start_of_cdir = Entry.read_zip_short(buf)
|
75
|
+
@total_number_of_entries_in_cdir_on_this_disk = Entry.read_zip_short(buf)
|
76
|
+
@size = Entry.read_zip_short(buf)
|
77
|
+
@size_in_bytes = Entry.read_zip_long(buf)
|
78
|
+
@cdir_offset = Entry.read_zip_long(buf)
|
79
|
+
comment_length = Entry.read_zip_short(buf)
|
80
|
+
@comment = if comment_length <= 0
|
81
|
+
buf.slice!(0, buf.size)
|
82
|
+
else
|
83
|
+
buf.read(comment_length)
|
84
|
+
end
|
68
85
|
raise ZipError, "Zip consistency problem while reading eocd structure" unless buf.size == 0
|
69
86
|
end
|
70
87
|
|
71
88
|
def read_central_directory_entries(io) #:nodoc:
|
72
89
|
begin
|
73
|
-
io.seek(@
|
90
|
+
io.seek(@cdir_offset, IO::SEEK_SET)
|
74
91
|
rescue Errno::EINVAL
|
75
92
|
raise ZipError, "Zip consistency problem while reading central directory entry"
|
76
93
|
end
|
77
94
|
@entry_set = EntrySet.new
|
78
95
|
@size.times do
|
79
|
-
|
80
|
-
@entry_set << tmp
|
96
|
+
@entry_set << Entry.read_c_dir_entry(io)
|
81
97
|
end
|
82
98
|
end
|
83
99
|
|
84
100
|
def read_from_stream(io) #:nodoc:
|
85
|
-
|
101
|
+
buf = start_buf(io)
|
102
|
+
if self.zip64_file?(buf)
|
103
|
+
read_64_e_o_c_d(buf)
|
104
|
+
else
|
105
|
+
read_e_o_c_d(buf)
|
106
|
+
end
|
86
107
|
read_central_directory_entries(io)
|
87
108
|
end
|
88
109
|
|
89
|
-
def get_e_o_c_d(
|
110
|
+
def get_e_o_c_d(buf) #:nodoc:
|
111
|
+
sig_index = buf.rindex([END_OF_CDS].pack('V'))
|
112
|
+
raise ZipError, "Zip end of central directory signature not found" unless sig_index
|
113
|
+
buf = buf.slice!((sig_index + 4)..(buf.bytesize))
|
114
|
+
|
115
|
+
def buf.read(count)
|
116
|
+
slice!(0, count)
|
117
|
+
end
|
118
|
+
|
119
|
+
buf
|
120
|
+
end
|
121
|
+
|
122
|
+
def zip64_file?(buf)
|
123
|
+
buf.rindex([ZIP64_END_OF_CDS].pack('V')) && buf.rindex([ZIP64_EOCD_LOCATOR].pack('V'))
|
124
|
+
end
|
125
|
+
|
126
|
+
def start_buf(io)
|
90
127
|
begin
|
91
|
-
io.seek(-
|
128
|
+
io.seek(-MAX_END_OF_CDS_SIZE, IO::SEEK_END)
|
92
129
|
rescue Errno::EINVAL
|
93
130
|
io.seek(0, IO::SEEK_SET)
|
94
131
|
end
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
132
|
+
io.read
|
133
|
+
end
|
134
|
+
|
135
|
+
def get_64_e_o_c_d(buf) #:nodoc:
|
136
|
+
zip_64_start = buf.rindex([ZIP64_END_OF_CDS].pack('V'))
|
137
|
+
raise ZipError, "Zip64 end of central directory signature not found" unless zip_64_start
|
138
|
+
zip_64_locator = buf.rindex([ZIP64_EOCD_LOCATOR].pack('V'))
|
139
|
+
raise ZipError, "Zip64 end of central directory signature locator not found" unless zip_64_locator
|
140
|
+
buf = buf.slice!((zip_64_start + 4)..zip_64_locator)
|
99
141
|
|
100
142
|
def buf.read(count)
|
101
143
|
slice!(0, count)
|
@@ -115,7 +157,7 @@ module Zip
|
|
115
157
|
@entry_set.size
|
116
158
|
end
|
117
159
|
|
118
|
-
def
|
160
|
+
def self.read_from_stream(io) #:nodoc:
|
119
161
|
cdir = new
|
120
162
|
cdir.read_from_stream(io)
|
121
163
|
return cdir
|
data/lib/zip/decompressor.rb
CHANGED
data/lib/zip/entry.rb
CHANGED
@@ -124,6 +124,7 @@ module Zip
|
|
124
124
|
end
|
125
125
|
|
126
126
|
def calculate_local_header_size #:nodoc:all
|
127
|
+
fix_zip64_sizes!
|
127
128
|
LOCAL_ENTRY_STATIC_HEADER_LENGTH + name_size + extra_size
|
128
129
|
end
|
129
130
|
|
@@ -164,6 +165,10 @@ module Zip
|
|
164
165
|
io.read(4).unpack('V')[0]
|
165
166
|
end
|
166
167
|
|
168
|
+
def read_zip_64_long(io) # :nodoc:
|
169
|
+
io.read(8).unpack('V')[0]
|
170
|
+
end
|
171
|
+
|
167
172
|
def read_c_dir_entry(io) #:nodoc:all
|
168
173
|
entry = new(io.path)
|
169
174
|
entry.read_c_dir_entry(io)
|
@@ -243,7 +248,7 @@ module Zip
|
|
243
248
|
@compressed_size,
|
244
249
|
@size,
|
245
250
|
name_size,
|
246
|
-
@extra ? @extra.
|
251
|
+
@extra ? @extra.local_size : 0].pack('VvvvvvVVVvv')
|
247
252
|
end
|
248
253
|
|
249
254
|
def write_local_entry(io) #:nodoc:all
|
@@ -398,7 +403,7 @@ module Zip
|
|
398
403
|
@compressed_size,
|
399
404
|
@size,
|
400
405
|
name_size,
|
401
|
-
@extra ? @extra.
|
406
|
+
@extra ? @extra.c_dir_size : 0,
|
402
407
|
comment_size,
|
403
408
|
0, # disk number start
|
404
409
|
@internal_file_attributes, # file type (binary=0, text=1)
|
@@ -601,6 +606,14 @@ module Zip
|
|
601
606
|
|
602
607
|
::File.symlink(linkto, dest_path)
|
603
608
|
end
|
609
|
+
|
610
|
+
def fix_zip64_sizes! #:nodoc:all
|
611
|
+
if zip64 = @extra["Zip64"]
|
612
|
+
@size = zip64.original_size
|
613
|
+
@compressed_size = zip64.compressed_size
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
604
617
|
end
|
605
618
|
end
|
606
619
|
|
data/lib/zip/extra_field.rb
CHANGED
@@ -67,24 +67,23 @@ module Zip
|
|
67
67
|
self.map { |_, v| v.to_c_dir_bin }.join
|
68
68
|
end
|
69
69
|
|
70
|
-
def
|
70
|
+
def c_dir_size
|
71
71
|
to_c_dir_bin.bytesize
|
72
72
|
end
|
73
73
|
|
74
|
-
def
|
74
|
+
def local_size
|
75
75
|
to_local_bin.bytesize
|
76
76
|
end
|
77
77
|
|
78
|
-
alias :
|
79
|
-
alias :
|
80
|
-
alias :length :local_length
|
81
|
-
alias :size :local_length
|
78
|
+
alias :length :local_size
|
79
|
+
alias :size :local_size
|
82
80
|
end
|
83
81
|
end
|
84
82
|
|
85
83
|
require 'zip/extra_field/generic'
|
86
84
|
require 'zip/extra_field/universal_time'
|
87
85
|
require 'zip/extra_field/unix'
|
86
|
+
|
88
87
|
# Copyright (C) 2002, 2003 Thomas Sondergaard
|
89
88
|
# rubyzip is free software; you can redistribute it and/or
|
90
89
|
# modify it under the terms of the ruby license.
|
data/lib/zip/extra_field/unix.rb
CHANGED
@@ -23,8 +23,7 @@ module Zip
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def ==(other)
|
26
|
-
@uid == other.uid &&
|
27
|
-
@gid == other.gid
|
26
|
+
@uid == other.uid && @gid == other.gid
|
28
27
|
end
|
29
28
|
|
30
29
|
def pack_for_local
|
@@ -32,7 +31,7 @@ module Zip
|
|
32
31
|
end
|
33
32
|
|
34
33
|
def pack_for_c_dir
|
35
|
-
|
34
|
+
''
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Zip
|
2
|
+
# Info-ZIP Extra for Zip64 size
|
3
|
+
class ExtraField::Zip64 < ExtraField::Generic
|
4
|
+
attr_accessor :original_size, :compressed_size, :relative_header_offset, :disk_start_number
|
5
|
+
HEADER_ID = "\001\000"
|
6
|
+
register_map
|
7
|
+
|
8
|
+
def initialize(binstr = nil)
|
9
|
+
@original_size = nil
|
10
|
+
@compressed_size = nil
|
11
|
+
@relative_header_offset = nil
|
12
|
+
@disk_start_number = nil
|
13
|
+
binstr and merge(binstr)
|
14
|
+
end
|
15
|
+
|
16
|
+
def merge(binstr)
|
17
|
+
return if binstr.empty?
|
18
|
+
id, size, @original_size, @compressed_size, @relative_header_offset, @disk_start_number = binstr.to_s.unpack("vvQQQV")
|
19
|
+
end
|
20
|
+
|
21
|
+
def pack_for_local
|
22
|
+
return '' unless @original_size && @compressed_sie && @relative_header_offset && @disk_start_number
|
23
|
+
[1, 16, @original_size, @compressed_size, @relative_header_offset, @disk_start_number].pack("vvQQQV")
|
24
|
+
end
|
25
|
+
|
26
|
+
def pack_for_c_dir
|
27
|
+
pack_for_local
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/zip/file.rb
CHANGED
@@ -19,9 +19,9 @@ module Zip
|
|
19
19
|
# <code>first.txt</code> and a directory entry <code>a_dir</code>
|
20
20
|
# to it.
|
21
21
|
#
|
22
|
-
# require 'zip
|
22
|
+
# require 'zip'
|
23
23
|
#
|
24
|
-
# Zip::
|
24
|
+
# Zip::File.open("my.zip", Zip::File::CREATE) {
|
25
25
|
# |zipfile|
|
26
26
|
# zipfile.get_output_stream("first.txt") { |f| f.puts "Hello from ZipFile" }
|
27
27
|
# zipfile.mkdir("a_dir")
|
@@ -31,9 +31,9 @@ module Zip
|
|
31
31
|
# <code>first.txt</code> to standard out and deletes the entry from
|
32
32
|
# the archive.
|
33
33
|
#
|
34
|
-
# require 'zip
|
34
|
+
# require 'zip'
|
35
35
|
#
|
36
|
-
# Zip::
|
36
|
+
# Zip::File.open("my.zip", Zip::File::CREATE) {
|
37
37
|
# |zipfile|
|
38
38
|
# puts zipfile.read("first.txt")
|
39
39
|
# zipfile.remove("first.txt")
|
@@ -46,6 +46,7 @@ module Zip
|
|
46
46
|
|
47
47
|
CREATE = 1
|
48
48
|
SPLIT_SIGNATURE = 0x08074b50
|
49
|
+
ZIP64_EOCD_SIGNATURE = 0x06064b50
|
49
50
|
MAX_SEGMENT_SIZE = 3221225472
|
50
51
|
MIN_SEGMENT_SIZE = 65536
|
51
52
|
DATA_BUFFER_SIZE = 8192
|
@@ -58,18 +59,20 @@ module Zip
|
|
58
59
|
attr_accessor :restore_permissions
|
59
60
|
# default -> true
|
60
61
|
attr_accessor :restore_times
|
62
|
+
# Returns the zip files comment, if it has one
|
63
|
+
attr_accessor :comment
|
61
64
|
|
62
65
|
# Opens a zip archive. Pass true as the second parameter to create
|
63
66
|
# a new archive if it doesn't exist already.
|
64
67
|
def initialize(fileName, create = nil, buffer = false)
|
65
68
|
super()
|
66
69
|
@name = fileName
|
67
|
-
@comment =
|
70
|
+
@comment = ''
|
68
71
|
@create = create
|
69
72
|
case
|
70
73
|
when ::File.exists?(fileName) && !buffer
|
71
74
|
@create = nil
|
72
|
-
::File.open(name,
|
75
|
+
::File.open(name, 'rb') do |f|
|
73
76
|
read_from_stream(f)
|
74
77
|
end
|
75
78
|
when create
|
@@ -113,15 +116,15 @@ module Zip
|
|
113
116
|
# (This can be used to extract data from a
|
114
117
|
# downloaded zip archive without first saving it to disk.)
|
115
118
|
def open_buffer(io)
|
119
|
+
unless io.is_a?(IO) && io.is_a?(String)
|
120
|
+
raise "Zip::ZipFile.open_buffer expects an argument of class String or IO. Found: #{io.class}"
|
121
|
+
end
|
116
122
|
zf = ::Zip::File.new('', true, true)
|
117
|
-
if io.is_a
|
118
|
-
zf.read_from_stream(io)
|
119
|
-
elsif io.is_a? String
|
123
|
+
if io.is_a(::String)
|
120
124
|
require 'stringio'
|
121
|
-
|
122
|
-
else
|
123
|
-
raise "Zip::ZipFile.open_buffer expects an argument of class String or IO. Found: #{io.class}"
|
125
|
+
io = ::StringIO.new(io)
|
124
126
|
end
|
127
|
+
zf.read_from_stream(io)
|
125
128
|
yield zf
|
126
129
|
zf.write_buffer
|
127
130
|
end
|
@@ -213,8 +216,6 @@ module Zip
|
|
213
216
|
end
|
214
217
|
end
|
215
218
|
|
216
|
-
# Returns the zip files comment, if it has one
|
217
|
-
attr_accessor :comment
|
218
219
|
|
219
220
|
# Returns an input stream to the specified entry. If a block is passed
|
220
221
|
# the stream object is passed to the block and the stream is automatically
|
data/lib/zip/ioextras.rb
CHANGED
@@ -5,22 +5,21 @@ module Zip
|
|
5
5
|
|
6
6
|
RANGE_ALL = 0..-1
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
class << self
|
9
|
+
def copy_stream(ostream, istream)
|
10
|
+
ostream.write(istream.read(CHUNK_SIZE, '')) until istream.eof?
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
23
|
# Implements kind_of? in order to pretend to be an IO object
|
25
24
|
module FakeIO
|
26
25
|
def kind_of?(object)
|
@@ -28,159 +27,12 @@ module Zip
|
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
31
|
-
# Implements many of the convenience methods of IO
|
32
|
-
# such as gets, getc, readline and readlines
|
33
|
-
# depends on: input_finished?, produce_input and read
|
34
|
-
module AbstractInputStream
|
35
|
-
include Enumerable
|
36
|
-
include FakeIO
|
37
|
-
|
38
|
-
def initialize
|
39
|
-
super
|
40
|
-
@lineno = 0
|
41
|
-
@pos = 0
|
42
|
-
@output_buffer = ""
|
43
|
-
end
|
44
|
-
|
45
|
-
attr_accessor :lineno
|
46
|
-
attr_reader :pos
|
47
|
-
|
48
|
-
def read(numberOfBytes = nil, buf = nil)
|
49
|
-
tbuf = nil
|
50
|
-
|
51
|
-
if @output_buffer.bytesize > 0
|
52
|
-
if numberOfBytes <= @output_buffer.bytesize
|
53
|
-
tbuf = @output_buffer.slice!(0, numberOfBytes)
|
54
|
-
else
|
55
|
-
numberOfBytes -= @output_buffer.bytesize if (numberOfBytes)
|
56
|
-
rbuf = sysread(numberOfBytes, buf)
|
57
|
-
tbuf = @output_buffer
|
58
|
-
tbuf << rbuf if (rbuf)
|
59
|
-
@output_buffer = ""
|
60
|
-
end
|
61
|
-
else
|
62
|
-
tbuf = sysread(numberOfBytes, buf)
|
63
|
-
end
|
64
|
-
|
65
|
-
@pos += tbuf.length
|
66
|
-
|
67
|
-
return nil unless (tbuf)
|
68
|
-
|
69
|
-
if buf
|
70
|
-
buf.replace(tbuf)
|
71
|
-
else
|
72
|
-
buf = tbuf
|
73
|
-
end
|
74
|
-
|
75
|
-
buf
|
76
|
-
end
|
77
|
-
|
78
|
-
def readlines(aSepString = $/)
|
79
|
-
retVal = []
|
80
|
-
each_line(aSepString) { |line| retVal << line }
|
81
|
-
retVal
|
82
|
-
end
|
83
|
-
|
84
|
-
def gets(aSepString = $/, numberOfBytes = nil)
|
85
|
-
@lineno = @lineno.next
|
86
|
-
|
87
|
-
if numberOfBytes.respond_to?(:to_int)
|
88
|
-
numberOfBytes = numberOfBytes.to_int
|
89
|
-
aSepString = aSepString.to_str if aSepString
|
90
|
-
elsif aSepString.respond_to?(:to_int)
|
91
|
-
numberOfBytes = aSepString.to_int
|
92
|
-
aSepString = $/
|
93
|
-
else
|
94
|
-
numberOfBytes = nil
|
95
|
-
aSepString = aSepString.to_str if aSepString
|
96
|
-
end
|
97
|
-
|
98
|
-
return read(numberOfBytes) if aSepString.nil?
|
99
|
-
aSepString = "#{$/}#{$/}" if aSepString.empty?
|
100
|
-
|
101
|
-
bufferIndex = 0
|
102
|
-
overLimit = (numberOfBytes && @output_buffer.bytesize >= numberOfBytes)
|
103
|
-
while ((matchIndex = @output_buffer.index(aSepString, bufferIndex)) == nil && !overLimit)
|
104
|
-
bufferIndex = [bufferIndex, @output_buffer.bytesize - aSepString.bytesize].max
|
105
|
-
if input_finished?
|
106
|
-
return @output_buffer.empty? ? nil : flush
|
107
|
-
end
|
108
|
-
@output_buffer << produce_input
|
109
|
-
overLimit = (numberOfBytes && @output_buffer.bytesize >= numberOfBytes)
|
110
|
-
end
|
111
|
-
sepIndex = [matchIndex + aSepString.bytesize, numberOfBytes || @output_buffer.bytesize].min
|
112
|
-
@pos += sepIndex
|
113
|
-
return @output_buffer.slice!(0...sepIndex)
|
114
|
-
end
|
115
|
-
|
116
|
-
def flush
|
117
|
-
retVal = @output_buffer
|
118
|
-
@output_buffer=""
|
119
|
-
return retVal
|
120
|
-
end
|
121
|
-
|
122
|
-
def readline(aSepString = $/)
|
123
|
-
retVal = gets(aSepString)
|
124
|
-
raise EOFError if retVal == nil
|
125
|
-
retVal
|
126
|
-
end
|
127
|
-
|
128
|
-
def each_line(aSepString = $/)
|
129
|
-
while true
|
130
|
-
yield readline(aSepString)
|
131
|
-
end
|
132
|
-
rescue EOFError
|
133
|
-
end
|
134
|
-
|
135
|
-
alias_method :each, :each_line
|
136
|
-
end
|
137
|
-
|
138
|
-
|
139
|
-
# Implements many of the output convenience methods of IO.
|
140
|
-
# relies on <<
|
141
|
-
module AbstractOutputStream
|
142
|
-
include FakeIO
|
143
|
-
|
144
|
-
def write(data)
|
145
|
-
self << data
|
146
|
-
data.to_s.bytesize
|
147
|
-
end
|
148
|
-
|
149
|
-
|
150
|
-
def print(*params)
|
151
|
-
self << params.join($,) << $\.to_s
|
152
|
-
end
|
153
|
-
|
154
|
-
def printf(aFormatString, *params)
|
155
|
-
self << sprintf(aFormatString, *params)
|
156
|
-
end
|
157
|
-
|
158
|
-
def putc(anObject)
|
159
|
-
self << case anObject
|
160
|
-
when Fixnum then
|
161
|
-
anObject.chr
|
162
|
-
when String then
|
163
|
-
anObject
|
164
|
-
else
|
165
|
-
raise TypeError, "putc: Only Fixnum and String supported"
|
166
|
-
end
|
167
|
-
anObject
|
168
|
-
end
|
169
|
-
|
170
|
-
def puts(*params)
|
171
|
-
params << "\n" if params.empty?
|
172
|
-
params.flatten.each do |element|
|
173
|
-
val = element.to_s
|
174
|
-
self << val
|
175
|
-
self << "\n" unless val[-1, 1] == "\n"
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
end
|
180
|
-
|
181
30
|
end # IOExtras namespace module
|
182
31
|
end
|
183
32
|
|
33
|
+
require 'zip/ioextras/abstract_input_stream'
|
34
|
+
require 'zip/ioextras/abstract_output_stream'
|
35
|
+
|
184
36
|
# Copyright (C) 2002-2004 Thomas Sondergaard
|
185
37
|
# rubyzip is free software; you can redistribute it and/or
|
186
38
|
# modify it under the terms of the ruby license.
|
@@ -0,0 +1,108 @@
|
|
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 = nil)
|
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
|
+
@pos += tbuf.length
|
37
|
+
|
38
|
+
return nil unless tbuf
|
39
|
+
|
40
|
+
if buf
|
41
|
+
buf.replace(tbuf)
|
42
|
+
else
|
43
|
+
buf = tbuf
|
44
|
+
end
|
45
|
+
buf
|
46
|
+
end
|
47
|
+
|
48
|
+
def readlines(a_sep_string = $/)
|
49
|
+
ret_val = []
|
50
|
+
each_line(a_sep_string) { |line| ret_val << line }
|
51
|
+
ret_val
|
52
|
+
end
|
53
|
+
|
54
|
+
def gets(a_sep_string = $/, number_of_bytes = nil)
|
55
|
+
@lineno = @lineno.next
|
56
|
+
|
57
|
+
if number_of_bytes.respond_to?(:to_int)
|
58
|
+
number_of_bytes = number_of_bytes.to_int
|
59
|
+
a_sep_string = a_sep_string.to_str if a_sep_string
|
60
|
+
elsif a_sep_string.respond_to?(:to_int)
|
61
|
+
number_of_bytes = a_sep_string.to_int
|
62
|
+
a_sep_string = $/
|
63
|
+
else
|
64
|
+
number_of_bytes = nil
|
65
|
+
a_sep_string = a_sep_string.to_str if a_sep_string
|
66
|
+
end
|
67
|
+
|
68
|
+
return read(number_of_bytes) if a_sep_string.nil?
|
69
|
+
a_sep_string = "#{$/}#{$/}" if a_sep_string.empty?
|
70
|
+
|
71
|
+
buffer_index = 0
|
72
|
+
over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes)
|
73
|
+
while (match_index = @output_buffer.index(a_sep_string, buffer_index)).nil? && !over_limit
|
74
|
+
buffer_index = [buffer_index, @output_buffer.bytesize - a_sep_string.bytesize].max
|
75
|
+
if input_finished?
|
76
|
+
return @output_buffer.empty? ? nil : flush
|
77
|
+
end
|
78
|
+
@output_buffer << produce_input
|
79
|
+
over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes)
|
80
|
+
end
|
81
|
+
sep_index = [match_index + a_sep_string.bytesize, number_of_bytes || @output_buffer.bytesize].min
|
82
|
+
@pos += sep_index
|
83
|
+
return @output_buffer.slice!(0...sep_index)
|
84
|
+
end
|
85
|
+
|
86
|
+
def flush
|
87
|
+
ret_val = @output_buffer
|
88
|
+
@output_buffer = ''
|
89
|
+
ret_val
|
90
|
+
end
|
91
|
+
|
92
|
+
def readline(a_sep_string = $/)
|
93
|
+
ret_val = gets(a_sep_string)
|
94
|
+
raise EOFError unless ret_val
|
95
|
+
ret_val
|
96
|
+
end
|
97
|
+
|
98
|
+
def each_line(a_sep_string = $/)
|
99
|
+
while true
|
100
|
+
yield readline(a_sep_string)
|
101
|
+
end
|
102
|
+
rescue EOFError
|
103
|
+
end
|
104
|
+
|
105
|
+
alias_method :each, :each_line
|
106
|
+
end
|
107
|
+
end
|
108
|
+
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
|
data/lib/zip/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Zip
|
2
|
-
VERSION = '1.0.0
|
3
|
-
end
|
2
|
+
VERSION = '1.0.0'
|
3
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubyzip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Simonov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -36,11 +36,14 @@ files:
|
|
36
36
|
- lib/zip/extra_field/generic.rb
|
37
37
|
- lib/zip/extra_field/universal_time.rb
|
38
38
|
- lib/zip/extra_field/unix.rb
|
39
|
+
- lib/zip/extra_field/zip64.rb
|
39
40
|
- lib/zip/extra_field.rb
|
40
41
|
- lib/zip/file.rb
|
41
42
|
- lib/zip/filesystem.rb
|
42
43
|
- lib/zip/inflater.rb
|
43
44
|
- lib/zip/input_stream.rb
|
45
|
+
- lib/zip/ioextras/abstract_input_stream.rb
|
46
|
+
- lib/zip/ioextras/abstract_output_stream.rb
|
44
47
|
- lib/zip/ioextras.rb
|
45
48
|
- lib/zip/null_compressor.rb
|
46
49
|
- lib/zip/null_decompressor.rb
|
@@ -65,17 +68,17 @@ require_paths:
|
|
65
68
|
- lib
|
66
69
|
required_ruby_version: !ruby/object:Gem::Requirement
|
67
70
|
requirements:
|
68
|
-
- - '>='
|
71
|
+
- - ! '>='
|
69
72
|
- !ruby/object:Gem::Version
|
70
73
|
version: 1.9.2
|
71
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
75
|
requirements:
|
73
|
-
- - '
|
76
|
+
- - ! '>='
|
74
77
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
78
|
+
version: '0'
|
76
79
|
requirements: []
|
77
80
|
rubyforge_project:
|
78
|
-
rubygems_version: 2.0.
|
81
|
+
rubygems_version: 2.0.3
|
79
82
|
signing_key:
|
80
83
|
specification_version: 4
|
81
84
|
summary: rubyzip is a ruby module for reading and writing zip files
|