zopen 1.0.1 → 1.0.2

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