pr-zlib 1.0.5 → 1.1.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/{CHANGES → CHANGES.md} +19 -6
- data/Gemfile +6 -0
- data/MANIFEST.md +20 -0
- data/{README → README.md} +29 -12
- data/Rakefile +11 -61
- data/bin/{minizip.rb → minirbgzip} +77 -65
- data/lib/pr/rbzlib/bytef.rb +16 -0
- data/lib/pr/rbzlib/bytef_arr.rb +29 -0
- data/lib/pr/rbzlib/bytef_str.rb +52 -0
- data/lib/pr/rbzlib/posf.rb +33 -0
- data/lib/pr/rbzlib.rb +1758 -1855
- data/lib/pr/zlib/deflate.rb +99 -0
- data/lib/pr/zlib/errors.rb +27 -0
- data/lib/pr/zlib/gzipfile.rb +315 -0
- data/lib/pr/zlib/gzipfile_errors.rb +19 -0
- data/lib/pr/zlib/gzipreader.rb +338 -0
- data/lib/pr/zlib/gzipwriter.rb +167 -0
- data/lib/pr/zlib/inflate.rb +114 -0
- data/lib/pr/zlib/zstream.rb +417 -0
- data/lib/pr/zlib.rb +25 -1466
- data/pr-zlib.gemspec +15 -15
- data/profile/bench_pr_zlib.rb +7 -5
- data/profile/bench_zlib.rb +7 -5
- data/profile/profile_pr_zlib_read.rb +3 -3
- data/profile/profile_pr_zlib_write.rb +3 -3
- data/spec/README.md +46 -0
- data/spec/rbzlib/bytef_arr_spec.rb +82 -0
- data/spec/rbzlib/bytef_spec.rb +72 -0
- data/spec/rbzlib/bytef_str_spec.rb +113 -0
- data/spec/rbzlib/posf_spec.rb +83 -0
- data/spec/rbzlib_spec.rb +170 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/zlib/deflate_spec.rb +44 -0
- data/spec/zlib/gzip_file_spec.rb +86 -0
- data/spec/zlib/gzip_reader_spec.rb +276 -0
- data/spec/zlib/gzip_writer_spec.rb +275 -0
- data/spec/zlib/inflate_spec.rb +44 -0
- data/spec/zlib/zstream_spec.rb +156 -0
- data/spec/zlib_spec.rb +195 -0
- data.tar.gz.sig +0 -0
- metadata +68 -55
- metadata.gz.sig +0 -0
- data/MANIFEST +0 -20
- data/test/test_rbzlib.rb +0 -133
- data/test/test_rbzlib_bytef.rb +0 -76
- data/test/test_rbzlib_posf.rb +0 -56
- data/test/test_zlib.rb +0 -162
- data/test/test_zlib_deflate.rb +0 -55
- data/test/test_zlib_gzip_file.rb +0 -93
- data/test/test_zlib_gzip_reader.rb +0 -183
- data/test/test_zlib_gzip_writer.rb +0 -186
- data/test/test_zlib_inflate.rb +0 -55
- data/test/test_zlib_zstream.rb +0 -146
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'zstream'
|
4
|
+
|
5
|
+
module Zlib
|
6
|
+
class Deflate < ZStream
|
7
|
+
|
8
|
+
def self.deflate_run(src)
|
9
|
+
@z.zstream_run(src, src.length, Z_FINISH)
|
10
|
+
@z.zstream_detach_buffer()
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.deflate(src, level = Z_DEFAULT_COMPRESSION)
|
14
|
+
@z = ZStream.new
|
15
|
+
@z.zstream_init(DeflateFuncs)
|
16
|
+
err = deflateInit(@z.stream, level)
|
17
|
+
if err != Z_OK
|
18
|
+
raise_zlib_error(err, @z.stream.msg)
|
19
|
+
end
|
20
|
+
@z.ZSTREAM_READY()
|
21
|
+
|
22
|
+
begin
|
23
|
+
dst = deflate_run(src)
|
24
|
+
ensure
|
25
|
+
@z.zstream_end()
|
26
|
+
end
|
27
|
+
dst
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(level = Z_DEFAULT_COMPRESSION, wbits = MAX_WBITS, memlevel = DEF_MEM_LEVEL, strategy = Z_DEFAULT_STRATEGY)
|
31
|
+
@z = ZStream.new
|
32
|
+
@z.zstream_init(DeflateFuncs)
|
33
|
+
err = deflateInit2(@z.stream, level, Z_DEFLATED, wbits, memlevel, strategy)
|
34
|
+
if err != Z_OK
|
35
|
+
raise_zlib_error(err, @z.stream.msg)
|
36
|
+
end
|
37
|
+
@z.ZSTREAM_READY()
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize_copy(orig)
|
41
|
+
z1 = @z
|
42
|
+
z2 = orig.z
|
43
|
+
err = deflateCopy(z1.stream, z2.stream)
|
44
|
+
if err != Z_OK
|
45
|
+
raise_zlib_error(err, 0)
|
46
|
+
end
|
47
|
+
z1.flags = z2.flags
|
48
|
+
end
|
49
|
+
|
50
|
+
def do_deflate(src, flush)
|
51
|
+
if src.nil?
|
52
|
+
@z.zstream_run('', 0, Z_FINISH)
|
53
|
+
return
|
54
|
+
end
|
55
|
+
if flush != Z_NO_FLUSH || (src && src.length > 0)
|
56
|
+
@z.zstream_run(src, src.length, flush)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
private :do_deflate
|
60
|
+
|
61
|
+
def deflate(src, flush = Z_NO_FLUSH)
|
62
|
+
do_deflate(src, flush)
|
63
|
+
@z.zstream_detach_buffer
|
64
|
+
end
|
65
|
+
|
66
|
+
def <<(src)
|
67
|
+
do_deflate(src, Z_NO_FLUSH)
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
def flush(v_flush)
|
72
|
+
if v_flush != Z_NO_FLUSH
|
73
|
+
@z.zstream_run('', 0, flush)
|
74
|
+
end
|
75
|
+
@z.zstream_detach_buffer()
|
76
|
+
end
|
77
|
+
|
78
|
+
def params(level = Z_DEFAULT_COMPRESSION, strategy = Z_DEFAULT_STRATEGY)
|
79
|
+
err = deflateParams(@z.stream, level, strategy)
|
80
|
+
while err == Z_BUF_ERROR
|
81
|
+
warn('deflateParams() returned Z_BUF_ERROR')
|
82
|
+
@z.zstream_expand_buffer()
|
83
|
+
err = deflateParams(@z.stream, level, strategy)
|
84
|
+
end
|
85
|
+
if err != Z_OK
|
86
|
+
raise_zlib_error(err, @z.stream.msg)
|
87
|
+
end
|
88
|
+
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
|
92
|
+
def set_dictionary(dic)
|
93
|
+
err = deflateSetDictionary(@z.stream, dic, dic.length)
|
94
|
+
if err != Z_OK
|
95
|
+
raise_zlib_error(err, @z.stream.msg)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Zlib
|
4
|
+
class Error < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
class StreamEnd < Error
|
8
|
+
end
|
9
|
+
|
10
|
+
class NeedDict < Error
|
11
|
+
end
|
12
|
+
|
13
|
+
class DataError < Error
|
14
|
+
end
|
15
|
+
|
16
|
+
class StreamError < Error
|
17
|
+
end
|
18
|
+
|
19
|
+
class MemError < Error
|
20
|
+
end
|
21
|
+
|
22
|
+
class BufError < Error
|
23
|
+
end
|
24
|
+
|
25
|
+
class VersionError < Error
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,315 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'zstream'
|
4
|
+
require_relative 'gzipfile_errors'
|
5
|
+
|
6
|
+
module Zlib
|
7
|
+
class GzipFile
|
8
|
+
GZ_MAGIC1 = 0x1f
|
9
|
+
GZ_MAGIC2 = 0x8b
|
10
|
+
GZ_METHOD_DEFLATE = 8
|
11
|
+
GZ_FLAG_MULTIPART = 0x2
|
12
|
+
GZ_FLAG_EXTRA = 0x4
|
13
|
+
GZ_FLAG_ORIG_NAME = 0x8
|
14
|
+
GZ_FLAG_COMMENT = 0x10
|
15
|
+
GZ_FLAG_ENCRYPT = 0x20
|
16
|
+
GZ_FLAG_UNKNOWN_MASK = 0xc0
|
17
|
+
|
18
|
+
GZ_EXTRAFLAG_FAST = 0x4
|
19
|
+
GZ_EXTRAFLAG_SLOW = 0x2
|
20
|
+
|
21
|
+
OS_CODE = 0x03 # OS_UNIX
|
22
|
+
|
23
|
+
GZFILE_FLAG_SYNC = 0x10 # ZSTREAM_FLAG_UNUSED
|
24
|
+
GZFILE_FLAG_HEADER_FINISHED = (0x10 << 1) # (ZSTREAM_FLAG_UNUSED << 1)
|
25
|
+
GZFILE_FLAG_FOOTER_FINISHED = (0x10 << 2) # (ZSTREAM_FLAG_UNUSED << 2)
|
26
|
+
|
27
|
+
def GZFILE_IS_FINISHED(gz)
|
28
|
+
gz.z.ZSTREAM_IS_FINISHED() && (gz.z.buf.nil? || gz.z.buf.offset.zero?)
|
29
|
+
end
|
30
|
+
|
31
|
+
GZFILE_READ_SIZE = 2048
|
32
|
+
|
33
|
+
Gzfile = Struct.new(:z, :io, :level, :mtime, :os_code, :orig_name, :comment, :crc, :lineno, :ungetc, :end)
|
34
|
+
|
35
|
+
def gzfile_close(closeflag)
|
36
|
+
io = @gz.io
|
37
|
+
send(@gz.end)
|
38
|
+
|
39
|
+
@gz.io = nil
|
40
|
+
@gz.orig_name = nil
|
41
|
+
@gz.comment = nil
|
42
|
+
|
43
|
+
if closeflag && defined?(io.close)
|
44
|
+
io.close
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def gzfile_ensure_close
|
49
|
+
if @gz.z.ZSTREAM_IS_READY()
|
50
|
+
gzfile_close(true)
|
51
|
+
end
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.wrap(io, level = Zlib::DEFAULT_COMPRESSION, strategy = Zlib::DEFAULT_STRATEGY)
|
56
|
+
obj = new(io, level, strategy)
|
57
|
+
if block_given?
|
58
|
+
begin
|
59
|
+
yield(obj)
|
60
|
+
ensure
|
61
|
+
obj.gzfile_ensure_close()
|
62
|
+
end
|
63
|
+
else
|
64
|
+
obj
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_io
|
69
|
+
raise GzipFile::Error, 'closed gzip stream' unless @gz.z.ZSTREAM_IS_READY()
|
70
|
+
@gz.io
|
71
|
+
end
|
72
|
+
|
73
|
+
def crc
|
74
|
+
raise GzipFile::Error, 'closed gzip stream' unless @gz.z.ZSTREAM_IS_READY()
|
75
|
+
@gz.crc
|
76
|
+
end
|
77
|
+
|
78
|
+
def mtime
|
79
|
+
raise GzipFile::Error, 'closed gzip stream' unless @gz.z.ZSTREAM_IS_READY()
|
80
|
+
Time.at(@gz.mtime)
|
81
|
+
end
|
82
|
+
|
83
|
+
def level
|
84
|
+
raise GzipFile::Error, 'closed gzip stream' unless @gz.z.ZSTREAM_IS_READY()
|
85
|
+
@gz.level
|
86
|
+
end
|
87
|
+
|
88
|
+
def os_code
|
89
|
+
raise GzipFile::Error, 'closed gzip stream' unless @gz.z.ZSTREAM_IS_READY()
|
90
|
+
@gz.os_code
|
91
|
+
end
|
92
|
+
|
93
|
+
def orig_name
|
94
|
+
raise GzipFile::Error, 'closed gzip stream' unless @gz.z.ZSTREAM_IS_READY()
|
95
|
+
@gz.orig_name ? @gz.orig_name.dup : nil
|
96
|
+
end
|
97
|
+
|
98
|
+
def comment
|
99
|
+
raise GzipFile::Error, 'closed gzip stream' unless @gz.z.ZSTREAM_IS_READY()
|
100
|
+
@gz.comment ? @gz.comment.dup : nil
|
101
|
+
end
|
102
|
+
|
103
|
+
def close
|
104
|
+
raise GzipFile::Error, 'closed gzip stream' unless @gz.z.ZSTREAM_IS_READY()
|
105
|
+
gzfile_close(true)
|
106
|
+
@gz.io
|
107
|
+
end
|
108
|
+
|
109
|
+
def finish
|
110
|
+
raise GzipFile::Error, 'closed gzip stream' unless @gz.z.ZSTREAM_IS_READY()
|
111
|
+
gzfile_close(false)
|
112
|
+
@gz.io
|
113
|
+
end
|
114
|
+
|
115
|
+
def closed?
|
116
|
+
@gz.io.nil?
|
117
|
+
end
|
118
|
+
|
119
|
+
def sync
|
120
|
+
raise GzipFile::Error, 'closed gzip stream' unless @gz.z.ZSTREAM_IS_READY()
|
121
|
+
!(@gz.z.flags & GZFILE_FLAG_SYNC).zero?
|
122
|
+
end
|
123
|
+
|
124
|
+
def sync=(mode)
|
125
|
+
raise GzipFile::Error, 'closed gzip stream' unless @gz.z.ZSTREAM_IS_READY()
|
126
|
+
if mode
|
127
|
+
@gz.z.flags |= GZFILE_FLAG_SYNC
|
128
|
+
else
|
129
|
+
@gz.z.flags &= ~GZFILE_FLAG_SYNC
|
130
|
+
end
|
131
|
+
mode
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.gzfile_s_open(filename, mode, level, strategy, &blk)
|
135
|
+
io = File.open(filename, mode)
|
136
|
+
self.wrap(io, level, strategy, &blk)
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def gzfile_new(funcs, endfunc)
|
142
|
+
@gz = Gzfile.new
|
143
|
+
@gz.z = ZStream.new
|
144
|
+
@gz.z.zstream_init(funcs)
|
145
|
+
@gz.io = nil
|
146
|
+
@gz.level = 0
|
147
|
+
@gz.mtime = 0
|
148
|
+
@gz.os_code = OS_CODE
|
149
|
+
@gz.orig_name = nil
|
150
|
+
@gz.comment = nil
|
151
|
+
@gz.crc = crc32(0, nil, 0)
|
152
|
+
@gz.lineno = 0
|
153
|
+
@gz.ungetc = 0
|
154
|
+
@gz.end = endfunc
|
155
|
+
self
|
156
|
+
end
|
157
|
+
|
158
|
+
def gzfile_reset
|
159
|
+
@gz.z.zstream_reset
|
160
|
+
@gz.crc = crc32(0, nil, 0)
|
161
|
+
@gz.lineno = 0
|
162
|
+
@gz.ungetc = 0
|
163
|
+
end
|
164
|
+
|
165
|
+
def gzfile_get16(src)
|
166
|
+
src.unpack('v').first
|
167
|
+
end
|
168
|
+
|
169
|
+
def gzfile_get32(src)
|
170
|
+
src.unpack('V').first
|
171
|
+
end
|
172
|
+
|
173
|
+
def gzfile_set32(n)
|
174
|
+
[n].pack('V')
|
175
|
+
end
|
176
|
+
|
177
|
+
def gzfile_make_header
|
178
|
+
buf = 0.chr * 10
|
179
|
+
flags = 0
|
180
|
+
extraflags = 0
|
181
|
+
if @gz.orig_name
|
182
|
+
flags |= GZ_FLAG_ORIG_NAME
|
183
|
+
end
|
184
|
+
if @gz.comment
|
185
|
+
flags |= GZ_FLAG_COMMENT
|
186
|
+
end
|
187
|
+
if @gz.mtime.zero?
|
188
|
+
@gz.mtime = Time.now.to_i
|
189
|
+
end
|
190
|
+
if @gz.level == Zlib::BEST_SPEED
|
191
|
+
extraflags |= GZ_EXTRAFLAG_FAST
|
192
|
+
elsif @gz.level == Zlib::BEST_COMPRESSION
|
193
|
+
extraflags |= GZ_EXTRAFLAG_SLOW
|
194
|
+
end
|
195
|
+
buf[0] = GZ_MAGIC1.chr
|
196
|
+
buf[1] = GZ_MAGIC2.chr
|
197
|
+
buf[2] = GZ_METHOD_DEFLATE.chr
|
198
|
+
buf[3] = flags.chr
|
199
|
+
buf[4, 4] = gzfile_set32(@gz.mtime)
|
200
|
+
buf[8] = extraflags.chr
|
201
|
+
buf[9] = @gz.os_code.chr
|
202
|
+
@gz.z.zstream_append_buffer(buf, buf.length)
|
203
|
+
|
204
|
+
if @gz.orig_name
|
205
|
+
@gz.z.zstream_append_buffer(@gz.orig_name, @gz.orig_name.length)
|
206
|
+
@gz.z.zstream_append_buffer("\0", 1)
|
207
|
+
end
|
208
|
+
if @gz.comment
|
209
|
+
@gz.z.zstream_append_buffer(@gz.comment, @gz.comment.length)
|
210
|
+
@gz.z.zstream_append_buffer("\0", 1)
|
211
|
+
end
|
212
|
+
|
213
|
+
@gz.z.flags |= GZFILE_FLAG_HEADER_FINISHED
|
214
|
+
end
|
215
|
+
|
216
|
+
def gzfile_make_footer
|
217
|
+
buf = 0.chr * 8
|
218
|
+
buf[0, 4] = gzfile_set32(@gz.crc)
|
219
|
+
buf[4, 4] = gzfile_set32(@gz.z.stream.total_in)
|
220
|
+
@gz.z.zstream_append_buffer(buf, buf.length)
|
221
|
+
@gz.z.flags |= GZFILE_FLAG_FOOTER_FINISHED
|
222
|
+
end
|
223
|
+
|
224
|
+
def gzfile_read_header
|
225
|
+
if !gzfile_read_raw_ensure(10)
|
226
|
+
raise GzipFile::Error, 'not in gzip format'
|
227
|
+
end
|
228
|
+
|
229
|
+
head = @gz.z.input
|
230
|
+
|
231
|
+
if head[0].ord != GZ_MAGIC1 || head[1].ord != GZ_MAGIC2
|
232
|
+
raise GzipFile::Error, 'not in gzip format'
|
233
|
+
end
|
234
|
+
if head[2].ord != GZ_METHOD_DEFLATE
|
235
|
+
raise GzipFile::Error, "unsupported compression method #{head[2].ord}"
|
236
|
+
end
|
237
|
+
|
238
|
+
flags = head[3].ord
|
239
|
+
if (flags & GZ_FLAG_MULTIPART).nonzero?
|
240
|
+
raise GzipFile::Error, 'multi-part gzip file is not supported'
|
241
|
+
elsif (flags & GZ_FLAG_ENCRYPT).nonzero?
|
242
|
+
raise GzipFile::Error, 'encrypted gzip file is not supported'
|
243
|
+
elsif (flags & GZ_FLAG_UNKNOWN_MASK).nonzero?
|
244
|
+
raise GzipFile::Error, 'unknown flags 0x%02x' % flags
|
245
|
+
end
|
246
|
+
|
247
|
+
if (head[8].ord & GZ_EXTRAFLAG_FAST).nonzero?
|
248
|
+
@gz.level = Zlib::BEST_SPEED
|
249
|
+
elsif (head[8].ord & GZ_EXTRAFLAG_SLOW).nonzero?
|
250
|
+
@gz.level = Zlib::BEST_COMPRESSION
|
251
|
+
else
|
252
|
+
@gz.level = Zlib::DEFAULT_COMPRESSION
|
253
|
+
end
|
254
|
+
|
255
|
+
@gz.mtime = gzfile_get32(head[4, 4])
|
256
|
+
@gz.os_code = head[9].ord
|
257
|
+
@gz.z.zstream_discard_input(10)
|
258
|
+
|
259
|
+
if (flags & GZ_FLAG_EXTRA).nonzero?
|
260
|
+
if !gzfile_read_raw_ensure(2)
|
261
|
+
raise GzipFile::Error, 'unexpected end of file'
|
262
|
+
end
|
263
|
+
len = gzfile_get16(@gz.z.input)
|
264
|
+
if !gzfile_read_raw_ensure(2 + len)
|
265
|
+
raise GzipFile::Error, 'unexpected end of file'
|
266
|
+
end
|
267
|
+
@gz.z.zstream_discard_input(2 + len)
|
268
|
+
end
|
269
|
+
if (flags & GZ_FLAG_ORIG_NAME).nonzero?
|
270
|
+
ap = gzfile_read_raw_until_zero(0)
|
271
|
+
len = ap
|
272
|
+
@gz.orig_name = @gz.z.input[0, len]
|
273
|
+
@gz.z.zstream_discard_input(len + 1)
|
274
|
+
end
|
275
|
+
if (flags & GZ_FLAG_COMMENT).nonzero?
|
276
|
+
ap = gzfile_read_raw_until_zero(0)
|
277
|
+
len = ap
|
278
|
+
@gz.comment = @gz.z.input[0, len]
|
279
|
+
@gz.z.zstream_discard_input(len + 1)
|
280
|
+
end
|
281
|
+
|
282
|
+
if @gz.z.input && @gz.z.input.length > 0
|
283
|
+
@gz.z.zstream_run(0, 0, Zlib::SYNC_FLUSH)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def gzfile_check_footer
|
288
|
+
@gz.z.flags |= GZFILE_FLAG_FOOTER_FINISHED
|
289
|
+
|
290
|
+
if !gzfile_read_raw_ensure(8)
|
291
|
+
raise NoFooter, 'footer is not found'
|
292
|
+
end
|
293
|
+
crc = gzfile_get32(@gz.z.input)
|
294
|
+
length = gzfile_get32(@gz.z.input[4, 4])
|
295
|
+
@gz.z.stream.total_in += 8
|
296
|
+
@gz.z.zstream_discard_input(8)
|
297
|
+
if @gz.crc != crc
|
298
|
+
raise CRCError, 'invalid compressed data -- crc error'
|
299
|
+
end
|
300
|
+
if @gz.z.stream.total_out != length
|
301
|
+
raise LengthError, 'invalid compressed data -- length error'
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
def gzfile_calc_crc(str)
|
306
|
+
if str.length <= @gz.ungetc
|
307
|
+
@gz.ungetc -= str.length
|
308
|
+
else
|
309
|
+
@gz.crc = crc32(@gz.crc, str[@gz.ungetc, str.length - @gz.ungetc],
|
310
|
+
str.length - @gz.ungetc)
|
311
|
+
@gz.ungetc = 0
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'errors'
|
4
|
+
|
5
|
+
module Zlib
|
6
|
+
class GzipFile
|
7
|
+
class Error < Zlib::Error
|
8
|
+
end
|
9
|
+
|
10
|
+
class NoFooter < Error
|
11
|
+
end
|
12
|
+
|
13
|
+
class CRCError < Error
|
14
|
+
end
|
15
|
+
|
16
|
+
class LengthError < Error
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|