zopen 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/zopen.rb +235 -224
  3. data/tests/zopen_spec.rb +47 -47
  4. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b97ac6a008c95a2bf01bc09976919d43ca557922
4
- data.tar.gz: d883f2917c04e223ad8ba5b45264cede4f004d4d
3
+ metadata.gz: ad1a11d193d3b241eb3736978a001ffb27419f02
4
+ data.tar.gz: 4ca599acb3c0f0c2dde0adeada8c18a08fff2bc7
5
5
  SHA512:
6
- metadata.gz: 353cb39f04c2980897093b1ac8fb4fa81ccc899474893cb0373d1f10252d4885bc263c78dc19f259f845331b0cfde2ffe6342599b1e31f9215cb79de161c20aa
7
- data.tar.gz: ac690a82001bfedfdd17d7c3444c1019fd0a93a27e3bb4fa6eeb155d416a40d635d874303e23cc215a0978a7b0d28d43ff64017c73730036f8eaf59b6a3b4645
6
+ metadata.gz: a26b37e0874abeafadbafb86fa25b639160e3fc4001bb2fbaa5692fd2665132f5ed7cd1f2f3aee75846c9edf4d98305c337f0a3adbcd42ccf5bb17067afcb60d
7
+ data.tar.gz: a2ff651afd0f673d06eb4b189f222feed60d96dd947bf06ec60673ac3fab13ad725d22c0e6ec8fcbefff7e69167c24246069caa4452b03ad6067bb52e54c2d88
data/lib/zopen.rb CHANGED
@@ -18,228 +18,239 @@ require 'delegate'
18
18
  # extensions and use different packers.
19
19
  module ZOpen
20
20
 
21
- # Handler for a plain file.
22
- #
23
- # This just opens a File
24
- Plain = lambda do |filename, mode|
25
- File.new(filename, mode)
26
- end
27
-
28
- # Handler for gzip compressed files.
29
- #
30
- # This handler uses either *zlib* module or the external *gzip*
31
- # program.
32
- Gzip = lambda do |filename, mode|
33
- begin
34
- require 'zlib'
35
- case mode
36
- when /r/, nil then Zlib::GzipReader.open(filename)
37
- when /w/ then Zlib::GzipWriter.open(filename)
38
- else fail "Unsupported open mode: #{mode}"
39
- end
40
- rescue LoadError
41
- case mode
42
- when /r/, nil then IO.popen("gzip -d -c '#{filename}'", mode)
43
- when /w/ then IO.popen("gzip -c - > '#{filename}'", mode)
44
- else fail "Unsupported open mode: #{mode}"
45
- end
46
- end
47
- end
48
-
49
- # Handler for bzip2 compressed files.
50
- #
51
- # This handler uses either *bzip2* module provided by the
52
- # *bzip2-ruby* gem or the external *bzip2* program.
53
- Bzip2 = lambda do |filename, mode|
54
- begin
55
- require 'bzip2'
56
- case mode
57
- when /r/, nil then Bzip2::Reader.open(filename)
58
- when /w/ then Bzip2::Writer.open(filename)
59
- else fail "Unsupported open mode: #{mode}"
60
- end
61
- rescue LoadError
62
- case mode
63
- when /r/, nil then IO.popen("bzip2 -d -c '#{filename}'", mode)
64
- when /w/ then IO.popen("bzip2 -c - > '#{filename}'", mode)
65
- else fail "Unsupported open mode: #{mode}"
66
- end
67
- end
68
- end
69
-
70
- # Handler for xz compressed files.
71
- #
72
- # This handler uses either *XZ* module provided by the
73
- # *ruby-xz* gem or the external *xz* program.
74
- XZ = lambda do |filename, mode|
75
- begin
76
- require 'xz'
77
- case mode
78
- when /r/, nil then ::XZ::StreamReader.open(filename)
79
- when /w/ then ::XZ::StreamWriter.open(filename)
80
- else fail "Unsupported open mode: #{mode}"
81
- end
82
- rescue LoadError
83
- case mode
84
- when /r/, nil then IO.popen("xz -d -c '#{filename}'", mode)
85
- when /w/ then IO.popen("xz -c - > '#{filename}'", mode)
86
- else fail "Unsupported open mode: #{mode}"
87
- end
88
- end
89
- end
90
-
91
- # A possible compressed file.
92
- #
93
- # This class delegates all functions to its underlying IO-like
94
- # object, which should provide the typical read/write
95
- # methods. However, many compressed files to not allow random
96
- # access, so methods like *seek* might not be available.
97
- class File < SimpleDelegator
98
- class << self
99
- alias_method :open, :new
100
- end
101
-
102
- # Open file.
103
- #
104
- # The only two open modes that are guaranteed to be supported
105
- # are 'r' and 'w' for reading and writing, respectively.
106
- #
107
- # If a code block is given the block is called with the new
108
- # file as parameter and the file is closed when the block
109
- # returns.
110
- #
111
- # @param filename [String] the name of the file to be opened
112
- # @param mode [String,nil] the mode to open the file
113
- # @return [File] the opened file
114
- # @yield [File] this file
115
- def initialize(filename, mode=nil)
116
- super(openfile(filename, mode))
117
- if block_given?
118
- yield self
119
- close
120
- end
121
- end
122
-
123
- # Return the content of a file.
124
- #
125
- # @param filename [String] the name of the file
126
- # @return [String] the content of the file
127
- def self.read(filename)
128
- new(filename, 'r') { |f| return f.read }
129
- end
130
-
131
- # Write a string to a file.
132
- #
133
- # @param filename [String] the name of the file
134
- # @param text [String] the string to be written to the file
135
- def self.write(filename, text)
136
- new(filename, 'w') { |f| f.write text }
137
- end
138
-
139
- private
140
- # Open a file with a certain mode.
141
- #
142
- # This method tests all registered handlers until it finds
143
- # some whose pattern matches the filename. Then the
144
- # corresponding handler is called.
145
- #
146
- # If no matching handler is found the file is opened as plain
147
- # file.
148
- #
149
- # @param filename [String] the name of the file
150
- # @param mode [String] the mode to open the file in
151
- def openfile(filename, mode)
152
- h = handlers
153
- h.find do |pat, open|
154
- return open.call(filename, mode) if pat =~ filename
155
- end if h
156
- ::File.new(filename, mode)
157
- end
158
-
159
- protected
160
- # Returns a hash of handlers.
161
- #
162
- # This function returns a hash of handlers. Each key should be
163
- # a regexp to test the file name. The key should be a callable
164
- # object (i.e. an object that has a *call* method, e.g. a
165
- # *Proc*). The callable object resembles the *open* function
166
- # *of a File object, i.e., it is called with two parameters
167
- # **filename* and *mode* and should return a corresponding
168
- # *opened *IO* object.
169
- #
170
- # This function may be overwritten in subclasses in order to
171
- # provide custom handlers.
172
- def handlers
173
- @@handlers
174
- end
175
-
176
- @@handlers = {
177
- /\.gz$/ => Gzip,
178
- /\.bz2$/ => Bzip2,
179
- /\.xz$/ => XZ
180
- }
181
- end
182
-
183
- # Create a new File-like class with handlers.
184
- #
185
- # This *handlers* parameter should be a hash whose keys are a
186
- # regular expression and the values are open-like callable
187
- # objects. If a name of a file to be opened matches a regular
188
- # expression, the corresponding callable object is called with the
189
- # file name and the open mode, and it should return an appropriate
190
- # IO object.
191
- #
192
- # @param handlers [Hash<Regexp,Proc>,nil] a hash of file handlers
193
- # @return [Class] a new file class
194
- def self.newfile(handlers = nil)
195
- if handlers then
196
- zFile = Class.new(File)
197
- zFile.send :define_method, :handlers do
198
- handlers
199
- end
200
- zFile
201
- else
202
- File
203
- end
204
- end
205
-
206
- # Opens a file with standard handlers.
207
- #
208
- # This opens a file that recognized gzip, bzip2 and xz compressed
209
- # files.
210
- #
211
- # Like File.open this method may be passed a code block which is
212
- # called with the new File as parameter.
213
- #
214
- # @param filename [String] the name of the file
215
- # @param mode [String,nil] the open mode
216
- # @return [File] the opened file
217
- # @yield [File] this file
218
- def self.open(filename, mode=nil)
219
- if block_given? then
220
- File.open(filename, mode) { |f| yield f }
221
- else
222
- File.open(filename, mode)
223
- end
224
- end
225
-
226
- # Writes text to a file with standard handlers.
227
- #
228
- # This method recognizes gzip, bzip2 and xz compressed files.
229
- #
230
- # @param [String] filename the name of the file
231
- # @param [String] text the text to be written to the file
232
- def self.write(filename, text)
233
- File.write(filename, text)
234
- end
235
-
236
- # Reads text from a file with standard handlers.
237
- #
238
- # This method recognizes gzip, bzip2 and xz compressed files.
239
- #
240
- # @param [String] filename the name of the file
241
- # @return [String] the content of the file
242
- def self.read(filename)
243
- File.read(filename)
244
- end
21
+ # Handler for a plain file.
22
+ #
23
+ # This just opens a File
24
+ Plain = lambda do |filename, mode|
25
+ File.new(filename, mode)
26
+ end
27
+
28
+ # Handler for gzip compressed files.
29
+ #
30
+ # This handler uses either *zlib* module or the external *gzip*
31
+ # program.
32
+ Gzip = lambda do |filename, mode|
33
+ begin
34
+ require 'zlib'
35
+ case mode
36
+ when /r/, nil then Zlib::GzipReader.open(filename)
37
+ when /w/ then Zlib::GzipWriter.open(filename)
38
+ else fail "Unsupported open mode: #{mode}"
39
+ end
40
+ rescue LoadError
41
+ case mode
42
+ when /r/, nil then IO.popen("gzip -d -c '#{filename}'", mode)
43
+ when /w/ then IO.popen("gzip -c - > '#{filename}'", mode)
44
+ else fail "Unsupported open mode: #{mode}"
45
+ end
46
+ end
47
+ end
48
+
49
+ # Handler for bzip2 compressed files.
50
+ #
51
+ # This handler uses either *bzip2* module provided by the
52
+ # *bzip2-ruby* gem or the external *bzip2* program.
53
+ Bzip2 = lambda do |filename, mode|
54
+ begin
55
+ require 'bzip2'
56
+ case mode
57
+ when /r/, nil then Bzip2::Reader.open(filename)
58
+ when /w/ then Bzip2::Writer.open(filename)
59
+ else fail "Unsupported open mode: #{mode}"
60
+ end
61
+ rescue LoadError
62
+ case mode
63
+ when /r/, nil then IO.popen("bzip2 -d -c '#{filename}'", mode)
64
+ when /w/ then IO.popen("bzip2 -c - > '#{filename}'", mode)
65
+ else fail "Unsupported open mode: #{mode}"
66
+ end
67
+ end
68
+ end
69
+
70
+ # Handler for xz compressed files.
71
+ #
72
+ # This handler uses either *XZ* module provided by the
73
+ # *ruby-xz* gem or the external *xz* program.
74
+ XZ = lambda do |filename, mode|
75
+ begin
76
+ require 'xz'
77
+ case mode
78
+ when /r/, nil then ::XZ::StreamReader.open(filename)
79
+ when /w/ then ::XZ::StreamWriter.open(filename)
80
+ else fail "Unsupported open mode: #{mode}"
81
+ end
82
+ rescue LoadError
83
+ case mode
84
+ when /r/, nil then IO.popen("xz -d -c '#{filename}'", mode)
85
+ when /w/ then IO.popen("xz -c - > '#{filename}'", mode)
86
+ else fail "Unsupported open mode: #{mode}"
87
+ end
88
+ end
89
+ end
90
+
91
+ # A possible compressed file.
92
+ #
93
+ # This class delegates all functions to its underlying IO-like
94
+ # object, which should provide the typical read/write
95
+ # methods. However, many compressed files to not allow random
96
+ # access, so methods like *seek* might not be available.
97
+ class File < SimpleDelegator
98
+ class << self
99
+ # Open file.
100
+ #
101
+ # The only two open modes that are guaranteed to be supported
102
+ # are 'r' and 'w' for reading and writing, respectively.
103
+ #
104
+ # If a code block is given the block is called with the new
105
+ # file as parameter and the file is closed when the block
106
+ # returns.
107
+ #
108
+ # @param filename [String] the name of the file to be opened
109
+ # @param mode [String,nil] the mode to open the file
110
+ # @return [File] the opened file
111
+ # @yield [File] this file
112
+ def new(filename, mode = nil)
113
+ file = allocate
114
+ file.send(:initialize, filename, mode)
115
+ if block_given?
116
+ begin
117
+ yield file
118
+ ensure
119
+ file.close
120
+ end
121
+ else
122
+ file
123
+ end
124
+ end
125
+
126
+ alias_method :open, :new
127
+ end
128
+
129
+ # Constructor
130
+ def initialize(filename, mode=nil)
131
+ super(openfile(filename, mode))
132
+ end
133
+
134
+ # Return the content of a file.
135
+ #
136
+ # @param filename [String] the name of the file
137
+ # @return [String] the content of the file
138
+ def self.read(filename)
139
+ new(filename, 'r') { |f| return f.read }
140
+ end
141
+
142
+ # Write a string to a file.
143
+ #
144
+ # @param filename [String] the name of the file
145
+ # @param text [String] the string to be written to the file
146
+ def self.write(filename, text)
147
+ new(filename, 'w') { |f| f.write text }
148
+ end
149
+
150
+ private
151
+ # Open a file with a certain mode.
152
+ #
153
+ # This method tests all registered handlers until it finds
154
+ # some whose pattern matches the filename. Then the
155
+ # corresponding handler is called.
156
+ #
157
+ # If no matching handler is found the file is opened as plain
158
+ # file.
159
+ #
160
+ # @param filename [String] the name of the file
161
+ # @param mode [String] the mode to open the file in
162
+ def openfile(filename, mode)
163
+ h = handlers
164
+ h.find do |pat, open|
165
+ return open.call(filename, mode) if pat =~ filename
166
+ end if h
167
+ ::File.new(filename, mode)
168
+ end
169
+
170
+ protected
171
+ # Returns a hash of handlers.
172
+ #
173
+ # This function returns a hash of handlers. Each key should be
174
+ # a regexp to test the file name. The key should be a callable
175
+ # object (i.e. an object that has a *call* method, e.g. a
176
+ # *Proc*). The callable object resembles the *open* function
177
+ # *of a File object, i.e., it is called with two parameters
178
+ # **filename* and *mode* and should return a corresponding
179
+ # *opened *IO* object.
180
+ #
181
+ # This function may be overwritten in subclasses in order to
182
+ # provide custom handlers.
183
+ def handlers
184
+ @@handlers
185
+ end
186
+
187
+ @@handlers = {
188
+ /\.gz$/ => Gzip,
189
+ /\.bz2$/ => Bzip2,
190
+ /\.xz$/ => XZ
191
+ }
192
+ end
193
+
194
+ # Create a new File-like class with handlers.
195
+ #
196
+ # This *handlers* parameter should be a hash whose keys are a
197
+ # regular expression and the values are open-like callable
198
+ # objects. If a name of a file to be opened matches a regular
199
+ # expression, the corresponding callable object is called with the
200
+ # file name and the open mode, and it should return an appropriate
201
+ # IO object.
202
+ #
203
+ # @param handlers [Hash<Regexp,Proc>,nil] a hash of file handlers
204
+ # @return [Class] a new file class
205
+ def self.newfile(handlers = nil)
206
+ if handlers then
207
+ zFile = Class.new(File)
208
+ zFile.send :define_method, :handlers do
209
+ handlers
210
+ end
211
+ zFile
212
+ else
213
+ File
214
+ end
215
+ end
216
+
217
+ # Opens a file with standard handlers.
218
+ #
219
+ # This opens a file that recognized gzip, bzip2 and xz compressed
220
+ # files.
221
+ #
222
+ # Like File.open this method may be passed a code block which is
223
+ # called with the new File as parameter.
224
+ #
225
+ # @param filename [String] the name of the file
226
+ # @param mode [String,nil] the open mode
227
+ # @return [File] the opened file
228
+ # @yield [File] this file
229
+ def self.open(filename, mode=nil)
230
+ if block_given? then
231
+ File.open(filename, mode) { |f| yield f }
232
+ else
233
+ File.open(filename, mode)
234
+ end
235
+ end
236
+
237
+ # Writes text to a file with standard handlers.
238
+ #
239
+ # This method recognizes gzip, bzip2 and xz compressed files.
240
+ #
241
+ # @param [String] filename the name of the file
242
+ # @param [String] text the text to be written to the file
243
+ def self.write(filename, text)
244
+ File.write(filename, text)
245
+ end
246
+
247
+ # Reads text from a file with standard handlers.
248
+ #
249
+ # This method recognizes gzip, bzip2 and xz compressed files.
250
+ #
251
+ # @param [String] filename the name of the file
252
+ # @return [String] the content of the file
253
+ def self.read(filename)
254
+ File.read(filename)
255
+ end
245
256
  end
data/tests/zopen_spec.rb CHANGED
@@ -4,63 +4,63 @@ require 'tempfile'
4
4
  require 'zopen'
5
5
 
6
6
  describe ZOpen do
7
- before do
8
- @fhandler = ZOpen.newfile
9
- end
7
+ before do
8
+ @fhandler = ZOpen.newfile
9
+ end
10
10
 
11
- it 'should read plain files' do
12
- t = Tempfile.new('foo')
13
- t.write "Hallo Welt\n"
14
- t.close
11
+ it 'should read plain files' do
12
+ t = Tempfile.new('foo')
13
+ t.write "Hallo Welt\n"
14
+ t.close
15
15
 
16
- f = @fhandler.open(t.path)
17
- f.read.must_equal "Hallo Welt\n"
18
- f.close
16
+ f = @fhandler.open(t.path)
17
+ f.read.must_equal "Hallo Welt\n"
18
+ f.close
19
19
 
20
- @fhandler.open(t.path) do |f2|
21
- f2.read.must_equal "Hallo Welt\n"
22
- end
20
+ @fhandler.open(t.path) do |f2|
21
+ f2.read.must_equal "Hallo Welt\n"
22
+ end
23
23
 
24
- @fhandler.read(t.path).must_equal "Hallo Welt\n"
25
- end
24
+ @fhandler.read(t.path).must_equal "Hallo Welt\n"
25
+ end
26
26
 
27
- it 'should fail on non existing files' do
28
- assert_raises Errno::ENOENT do
29
- @fhandler.open('nonexistingfile')
30
- end
31
- end
27
+ it 'should fail on non existing files' do
28
+ assert_raises Errno::ENOENT do
29
+ @fhandler.open('nonexistingfile')
30
+ end
31
+ end
32
32
 
33
- it 'should write plain files' do
34
- t = Tempfile.new('foo')
35
- t.close
33
+ it 'should write plain files' do
34
+ t = Tempfile.new('foo')
35
+ t.close
36
36
 
37
- f = @fhandler.open(t.path, 'w')
38
- f.write "Hallo Welt\n"
39
- f.close
40
- File.read(t.path).must_equal "Hallo Welt\n"
37
+ f = @fhandler.open(t.path, 'w')
38
+ f.write "Hallo Welt\n"
39
+ f.close
40
+ File.read(t.path).must_equal "Hallo Welt\n"
41
41
 
42
- @fhandler.open(t.path, 'w') do |fout|
43
- fout.write "Hello world\n"
44
- end
45
- File.read(t.path).must_equal "Hello world\n"
42
+ @fhandler.open(t.path, 'w') do |fout|
43
+ fout.write "Hello world\n"
44
+ end
45
+ File.read(t.path).must_equal "Hello world\n"
46
46
 
47
- @fhandler.write t.path, "Hello world\n"
48
- File.read(t.path).must_equal "Hello world\n"
49
- end
47
+ @fhandler.write t.path, "Hello world\n"
48
+ File.read(t.path).must_equal "Hello world\n"
49
+ end
50
50
 
51
- describe 'File with patterns' do
52
- it 'should call the correct handler' do
53
- file = Minitest::Mock.new
54
- file.expect :write, nil, ["Hallo Welt\n"]
55
- file.expect :close, nil, []
51
+ describe 'File with patterns' do
52
+ it 'should call the correct handler' do
53
+ file = Minitest::Mock.new
54
+ file.expect :write, nil, ["Hallo Welt\n"]
55
+ file.expect :close, nil, []
56
56
 
57
- open = Minitest::Mock.new
58
- open.expect :call, file, ['foo.txt', nil]
57
+ open = Minitest::Mock.new
58
+ open.expect :call, file, ['foo.txt', nil]
59
59
 
60
- @fhandler = ZOpen.newfile({%r/\.txt$/ => open})
61
- f = @fhandler.open('foo.txt')
62
- f.write "Hallo Welt\n"
63
- f.close
64
- end
65
- end
60
+ @fhandler = ZOpen.newfile({%r/\.txt$/ => open})
61
+ f = @fhandler.open('foo.txt')
62
+ f.write "Hallo Welt\n"
63
+ f.close
64
+ end
65
+ end
66
66
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zopen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frank Fischer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-04 00:00:00.000000000 Z
11
+ date: 2016-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: yard
@@ -38,7 +38,7 @@ files:
38
38
  - tests/zopen_spec.rb
39
39
  homepage: http://bitbucket.org/lyro/zopen
40
40
  licenses:
41
- - GPL-3
41
+ - GPL-3.0
42
42
  metadata: {}
43
43
  post_install_message:
44
44
  rdoc_options: []
@@ -56,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
56
56
  version: '0'
57
57
  requirements: []
58
58
  rubyforge_project:
59
- rubygems_version: 2.4.3
59
+ rubygems_version: 2.5.1
60
60
  signing_key:
61
61
  specification_version: 4
62
62
  summary: Automatically open compressed files