pr-zlib 1.0.2 → 1.0.3

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.
@@ -1,1554 +1,1567 @@
1
- # zlib.rb -- An interface for rbzlib
2
- # Copyright (C) UENO Katsuhiro 2000-2003
3
- #
4
- # Ruby translation by Park Heesob
5
-
6
- require 'pr/rbzlib'
7
- include Rbzlib
8
-
9
- module Zlib
10
-
11
- RUBY_ZLIB_VERSION = '0.6.0'
12
- PR_ZLIB_VERSION = '1.0.2'
13
-
14
- class Error < StandardError
15
- end
16
-
17
- class StreamEnd < Error
18
- end
19
-
20
- class NeedDict < Error
21
- end
22
-
23
- class DataError < Error
24
- end
25
-
26
- class StreamError < Error
27
- end
28
-
29
- class MemError < Error
30
- end
31
-
32
- class BufError < Error
33
- end
34
-
35
- class VersionError < Error
36
- end
37
-
38
- VERSION = RUBY_ZLIB_VERSION
39
- ZLIB_VERSION = ZLIB_VERSION
40
-
41
- BINARY = Z_BINARY
42
- ASCII = Z_ASCII
43
- UNKNOWN = Z_UNKNOWN
44
-
45
- NO_COMPRESSION = Z_NO_COMPRESSION
46
- BEST_SPEED = Z_BEST_SPEED
47
- BEST_COMPRESSION = Z_BEST_COMPRESSION
48
- DEFAULT_COMPRESSION = Z_DEFAULT_COMPRESSION
49
-
50
- FILTERED = Z_FILTERED
51
- HUFFMAN_ONLY = Z_HUFFMAN_ONLY
52
- DEFAULT_STRATEGY = Z_DEFAULT_STRATEGY
53
- MAX_WBITS = MAX_WBITS
54
- DEF_MEM_LEVEL = DEF_MEM_LEVEL
55
- MAX_MEM_LEVEL = MAX_MEM_LEVEL
56
- NO_FLUSH = Z_NO_FLUSH
57
- SYNC_FLUSH = Z_SYNC_FLUSH
58
- FULL_FLUSH = Z_FULL_FLUSH
59
- FINISH = Z_FINISH
60
-
61
- OS_CODE = OS_CODE
62
- OS_MSDOS = 0x00
63
- OS_AMIGA = 0x01
64
- OS_VMS = 0x02
65
- OS_UNIX = 0x03
66
- OS_ATARI = 0x05
67
- OS_OS2 = 0x06
68
- OS_MACOS = 0x07
69
- OS_TOPS20 = 0x0a
70
- OS_WIN32 = 0x0b
71
-
72
- ZSTREAM_FLAG_READY = 0x1
73
- ZSTREAM_FLAG_IN_STREAM = 0x2
74
- ZSTREAM_FLAG_FINISHED = 0x4
75
- ZSTREAM_FLAG_CLOSING = 0x8
76
- ZSTREAM_FLAG_UNUSED = 0x10
77
-
78
- ZSTREAM_INITIAL_BUFSIZE = 1024
79
- ZSTREAM_AVAIL_OUT_STEP_MAX = 16384
80
- ZSTREAM_AVAIL_OUT_STEP_MIN = 2048
81
-
82
- ZStreamFuncs = Struct.new(:reset, :end, :run)
83
- DeflateFuncs = ZStreamFuncs.new(:deflateReset, :deflateEnd, :deflate)
84
- InflateFuncs = ZStreamFuncs.new(:inflateReset, :inflateEnd, :inflate)
85
-
86
- class ZStream
87
- attr_accessor :flags, :buf, :input, :stream, :func
88
-
89
- def raise_zlib_error(err, msg)
90
- msg = zError(err) if msg.nil? || msg==''
91
-
92
- case err
93
- when Z_STREAM_END
94
- raise StreamEnd, msg
95
- when Z_NEED_DICT
96
- raise NeedDict, msg
97
- when Z_STREAM_ERROR
98
- raise StreamError, msg
99
- when Z_DATA_ERROR
100
- raise DataError, msg
101
- when Z_BUF_ERROR
102
- raise BufError, msg
103
- when Z_VERSION_ERROR
104
- raise VersionError, msg
105
- when Z_MEM_ERROR
106
- raise MemError, msg
107
- when Z_ERRNO
108
- raise SystemCallError, msg
109
- else
110
- raise Error, "unknown zlib error #errend: #msgend"
111
- end
112
- end
113
-
114
- def zstream_expand_buffer()
115
- if @buf.nil?
116
- @buf = Bytef.new(0.chr * ZSTREAM_INITIAL_BUFSIZE)
117
- @stream.next_out = Bytef.new(@buf)
118
- @stream.avail_out = ZSTREAM_INITIAL_BUFSIZE
119
- return
120
- end
121
-
122
- if (@buf.length - @buf.offset >= ZSTREAM_AVAIL_OUT_STEP_MAX)
123
- @stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX
124
- else
125
- inc = @buf.offset / 2
126
- if (inc < ZSTREAM_AVAIL_OUT_STEP_MIN)
127
- inc = ZSTREAM_AVAIL_OUT_STEP_MIN
128
- end
129
- if @buf.length < @buf.offset + inc
130
- @buf.buffer << 0.chr * (@buf.offset + inc - @buf.length)
131
- end
132
- @stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?
133
- inc : ZSTREAM_AVAIL_OUT_STEP_MAX
134
- end
135
- @stream.next_out = Bytef.new(@buf,@buf.offset)
136
- end
137
-
138
- def zstream_append_buffer(src, len)
139
- if @buf.nil?
140
- @buf = Bytef.new(src[0,len],len)
141
- @stream.next_out = Bytef.new(@buf)
142
- @stream.avail_out = 0
143
- return
144
- end
145
- if (@buf.length < @buf.offset + len)
146
- @buf.buffer << (0.chr * (@buf.offset + len - @buf.length))
147
- @stream.avail_out = 0
148
- else
149
- if (@stream.avail_out >= len)
150
- @stream.avail_out -= len
151
- else
152
- @stream.avail_out = 0
153
- end
154
- end
155
- @buf.buffer[@buf.offset,len] = src[0,len]
156
- @buf += len
157
- @stream.next_out = Bytef.new(@buf, @buf.offset)
158
- end
159
-
160
- def zstream_detach_buffer()
161
- if @buf.nil?
162
- dst = ''
163
- else
164
- dst = @buf.buffer[0,@buf.offset]
165
- end
166
-
167
- @buf = Bytef.new(0.chr * ZSTREAM_INITIAL_BUFSIZE)
168
- @stream.next_out = Bytef.new(@buf)
169
- @stream.avail_out = ZSTREAM_INITIAL_BUFSIZE
170
- @buf_filled = 0
171
-
172
- return dst
173
- end
174
-
175
- def zstream_shift_buffer(len)
176
- if (@buf.offset <= len)
177
- return zstream_detach_buffer()
178
- end
179
-
180
- dst = @buf.buffer[0, len]
181
- @buf -= len
182
- @buf.buffer[0,@buf.offset] = @buf.buffer[len,@buf.offset]
183
- @stream.next_out = Bytef.new(@buf,@buf.offset)
184
- @stream.avail_out = @buf.length - @buf.offset
185
- if (@stream.avail_out > ZSTREAM_AVAIL_OUT_STEP_MAX)
186
- @stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX
187
- end
188
- return dst
189
- end
190
-
191
- def zstream_buffer_ungetc(c)
192
- if (@buf.nil? || (@buf.length - @buf.offset).zero?)
193
- zstream_expand_buffer()
194
- end
195
- @buf.buffer[0,0] = c.chr
196
- @buf += 1
197
- if (@stream.avail_out > 0)
198
- @stream.next_out+=1
199
- @stream.avail_out-=1
200
- end
201
- end
202
-
203
- def zstream_append_input(src, len)
204
- return if (len <= 0)
205
- src = src.current if src.class != String
206
- if @input.nil?
207
- @input = src[0,len]
208
- else
209
- @input << src[0,len]
210
- end
211
- end
212
-
213
- def zstream_discard_input(len)
214
- if (@input.nil? || @input.length <= len)
215
- @input = nil
216
- else
217
- @input[0,len] = ''
218
- end
219
- end
220
-
221
- def zstream_reset_input()
222
- @input = nil
223
- end
224
-
225
- def zstream_passthrough_input()
226
- if @input
227
- zstream_append_buffer(@input,@input.length)
228
- @input = nil
229
- end
230
- end
231
-
232
- def zstream_detach_input()
233
- if @input.nil?
234
- dst = ''
235
- else
236
- dst = @input
237
- end
238
- @input = nil
239
- return dst
240
- end
241
-
242
- def zstream_reset()
243
- err = send(@func.reset,@stream)
244
- if (err != Z_OK)
245
- raise_zlib_error(err, @stream.msg)
246
- end
247
- @flags = ZSTREAM_FLAG_READY
248
- @buf = nil
249
- @buf_filled = 0
250
- @stream.next_out = 0
251
- @stream.avail_out = 0
252
- zstream_reset_input()
253
- end
254
-
255
- def zstream_end()
256
- if (!ZSTREAM_IS_READY())
257
- warn("attempt to close uninitialized zstream; ignored.")
258
- return nil
259
- end
260
- if (@flags & ZSTREAM_FLAG_IN_STREAM).nonzero?
261
- warn("attempt to close unfinished zstream; reset forced.")
262
- zstream_reset()
263
- end
264
-
265
- zstream_reset_input()
266
- err = send(@func.end,@stream)
267
- if (err != Z_OK)
268
- raise_zlib_error(err, @stream.msg)
269
- end
270
- @flags = 0
271
- return nil
272
- end
273
-
274
- def zstream_sync(src, len)
275
- if @input
276
- @stream.next_in = Bytef.new(@input)
277
- @stream.avail_in = @input.length
278
- err = inflateSync(@stream)
279
- if (err == Z_OK)
280
- zstream_discard_input(@input.length - @stream.avail_in)
281
- zstream_append_input(src, len)
282
- return true
283
- end
284
- zstream_reset_input()
285
- if (err != Z_DATA_ERROR)
286
- rest = @stream.next_in.buffer[0,@stream.avail_in]
287
- raise_zlib_error(err, @stream.msg)
288
- end
289
- end
290
-
291
- return false if (len <= 0)
292
-
293
- @stream.next_in = src
294
- @stream.avail_in = len
295
- err = inflateSync(@stream)
296
- if (err == Z_OK)
297
- zstream_append_input(@stream.next_in, @stream.avail_in)
298
- return true
299
- end
300
- if (err != Z_DATA_ERROR)
301
- rest = @stream.next_in.buffer[0,@stream.avail_in]
302
- raise_zlib_error(err, @stream.msg)
303
- end
304
- return false
305
- end
306
-
307
- def zstream_init(func)
308
- @flags = 0
309
- @buf = nil
310
- @input = nil
311
- @stream = Z_stream.new
312
- @stream.msg = ''
313
- @stream.next_in = nil
314
- @stream.avail_in = 0
315
- @stream.next_out = nil
316
- @stream.avail_out = 0
317
- @func = func
318
- end
319
-
320
- def zstream_run(src, len, flush)
321
- if(@input.nil? && len==0)
322
- @stream.next_in = ''
323
- @stream.avail_in = 0
324
- else
325
- zstream_append_input(src,len)
326
- @stream.next_in = Bytef.new(@input)
327
- @stream.avail_in = @input.length
328
- guard = @input
329
- end
330
- if(@stream.avail_out.zero?)
331
- zstream_expand_buffer()
332
- end
333
-
334
- loop do
335
- n = @stream.avail_out
336
- err = send(@func.run,@stream,flush)
337
- @buf += n - @stream.avail_out
338
- if(err == Z_STREAM_END)
339
- @flags &= ~ZSTREAM_FLAG_IN_STREAM
340
- @flags |= ZSTREAM_FLAG_FINISHED
341
- break
342
- end
343
- if (err != Z_OK)
344
- if (flush != Z_FINISH && err == Z_BUF_ERROR && @stream.avail_out > 0)
345
- @flags |= ZSTREAM_FLAG_IN_STREAM
346
- break
347
- end
348
- @input = nil
349
- if (@stream.avail_in > 0)
350
- zstream_append_input(@stream.next_in, @stream.avail_in)
351
- end
352
- raise_zlib_error(err, @stream.msg)
353
- end
354
- if (@stream.avail_out > 0)
355
- @flags |= ZSTREAM_FLAG_IN_STREAM
356
- break
357
- end
358
- zstream_expand_buffer()
359
- end
360
-
361
- @input = nil
362
- if (@stream.avail_in > 0)
363
- zstream_append_input(@stream.next_in, @stream.avail_in)
364
- guard = nil
365
- end
366
- end
367
-
368
- def ZSTREAM_READY()
369
- (@flags |= ZSTREAM_FLAG_READY)
370
- end
371
-
372
- def ZSTREAM_IS_READY()
373
- !(@flags & ZSTREAM_FLAG_READY).zero?
374
- end
375
-
376
- def ZSTREAM_IS_FINISHED()
377
- !(@flags & ZSTREAM_FLAG_FINISHED).zero?
378
- end
379
-
380
- def ZSTREAM_IS_CLOSING()
381
- !(@flags & ZSTREAM_FLAG_CLOSING).zero?
382
- end
383
-
384
- end
385
-
386
- class ZStream
387
- @@final = proc do |z|
388
- proc do
389
- if z && z.ZSTREAM_IS_READY()
390
- err = send(z.func.end, z.stream)
391
- if (err == Z_STREAM_ERROR)
392
- warn("the stream state was inconsistent.")
393
- end
394
- if (err == Z_DATA_ERROR)
395
- warn("the stream was freed prematurely.")
396
- end
397
- end
398
- end
399
- end
400
-
401
- attr_reader :z
402
-
403
- def avail_out()
404
- @z.stream.avail_out
405
- end
406
-
407
- def avail_out=(size)
408
- if @z.buf.nil?
409
- @z.buf = Bytef.new(0.chr * size)
410
- @z.stream.next_out = Bytef.new(@z.buf)
411
- @z.stream.avail_out = size
412
- elsif @z.stream.avail_out != size
413
- if @z.buf.offset + size > @z.buf.length
414
- @z.buf.buffer << 0.chr * (@z.buf.offset + size - @z.buf.length)
415
- end
416
- @z.stream.next_out = Bytef.new(@z.buf,@z.buf.offset)
417
- @z.stream.avail_out = size
418
- end
419
- end
420
-
421
- def avail_in
422
- @z.input.nil? ? 0 : @z.input.length
423
- end
424
-
425
- def total_in
426
- raise GzipFile::Error,"closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
427
- @z.stream.total_in
428
- end
429
-
430
- def total_out
431
- raise GzipFile::Error,"closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
432
- @z.stream.total_out
433
- end
434
-
435
- def data_type
436
- @z.stream.data_type
437
- end
438
-
439
- def adler
440
- @z.stream.adler
441
- end
442
-
443
- def finished?
444
- @z.ZSTREAM_IS_FINISHED()
445
- end
446
- alias stream_end? :finished?
447
-
448
- def closed?
449
- @z.ZSTREAM_IS_READY()
450
- end
451
- alias ended? :closed?
452
-
453
- def close()
454
- if (!@z.ZSTREAM_IS_READY())
455
- warn("attempt to close uninitialized zstream ignored.")
456
- return nil
457
- end
458
- if (@z.flags & ZSTREAM_FLAG_IN_STREAM).nonzero?
459
- warn("attempt to close unfinished zstream reset forced.")
460
- @z.input = nil
461
- end
462
-
463
- @z.input = nil
464
- err = send(@z.func.end,@z.stream)
465
- if (err != Z_OK)
466
- raise_zlib_error(err, @z.stream.msg)
467
- end
468
- @z.flags = 0
469
- end
470
- alias end :close
471
-
472
- def reset()
473
- err = send(@z.func.reset,@z.stream)
474
- if err != Z_OK
475
- raise_zlib_error(err, @z.stream.msg)
476
- end
477
- @z.flags = ZSTREAM_FLAG_READY
478
- @z.buf = nil
479
- @z.stream.next_out = 0
480
- @z.stream.avail_out = 0
481
- @z.input = nil
482
- end
483
-
484
- def finish()
485
- @z.zstream_run("", 0, Z_FINISH)
486
- @z.zstream_detach_buffer()
487
- end
488
-
489
- def flush_next_in
490
- @z.zstream_detach_input
491
- end
492
-
493
- def flush_next_out
494
- @z.zstream_detach_buffer
495
- end
496
-
497
- def initialize
498
- @z = nil
499
- ObjectSpace.define_finalizer self, @@final.call(@z)
500
- end
501
-
502
- end
503
-
504
- class Deflate < ZStream
505
-
506
- def self.deflate_run(src)
507
- @z.zstream_run(src,src.length,Z_FINISH)
508
- return @z.zstream_detach_buffer()
509
- end
510
-
511
- def self.deflate(src,level=Z_DEFAULT_COMPRESSION)
512
- @z = ZStream.new
513
- @z.zstream_init(DeflateFuncs)
514
- err = deflateInit(@z.stream, level)
515
- if (err != Z_OK)
516
- raise_zlib_error(err, @z.stream.msg)
517
- end
518
- @z.ZSTREAM_READY()
519
-
520
- begin
521
- dst = deflate_run(src)
522
- ensure
523
- @z.zstream_end()
524
- end
525
- dst
526
- end
527
-
528
- def initialize(level=Z_DEFAULT_COMPRESSION,wbits=MAX_WBITS,memlevel=DEF_MEM_LEVEL,strategy=Z_DEFAULT_STRATEGY)
529
- @z = ZStream.new
530
- @z.zstream_init(DeflateFuncs)
531
- err = deflateInit2(@z.stream,level,Z_DEFLATED,wbits,memlevel,strategy)
532
- if (err != Z_OK)
533
- raise_zlib_error(err, @z.stream.msg)
534
- end
535
- @z.ZSTREAM_READY()
536
- end
537
-
538
- def initialize_copy(orig)
539
- z1 = @z
540
- z2 = orig.z
541
- err = deflateCopy(z1.stream, z2.stream)
542
- if (err != Z_OK)
543
- raise_zlib_error(err, 0)
544
- end
545
- z1.flags = z2.flags
546
- end
547
-
548
- def do_deflate(src,flush)
549
- if src.nil?
550
- @z.zstream_run('',0,Z_FINISH)
551
- return
552
- end
553
- if (flush != Z_NO_FLUSH || (src && src.length>0))
554
- @z.zstream_run(src,src.length,flush)
555
- end
556
- end
557
- private :do_deflate
558
-
559
- def deflate(src,flush=Z_NO_FLUSH)
560
- do_deflate(src,flush)
561
- @z.zstream_detach_buffer
562
- end
563
-
564
- def <<(src)
565
- do_deflate(src,Z_NO_FLUSH)
566
- self
567
- end
568
-
569
- def flush(v_flush)
570
- if(v_flush != Z_NO_FLUSH)
571
- @z.zstream_run("", 0, flush)
572
- end
573
- @z.zstream_detach_buffer()
574
- end
575
-
576
- def params(level=Z_DEFAULT_COMPRESSION,strategy=Z_DEFAULT_STRATEGY)
577
- err = deflateParams(@z.stream, level, strategy)
578
- while (err == Z_BUF_ERROR)
579
- warn("deflateParams() returned Z_BUF_ERROR")
580
- @z.zstream_expand_buffer()
581
- err = deflateParams(@z.stream, level, strategy)
582
- end
583
- if (err != Z_OK)
584
- raise_zlib_error(err, @z.stream.msg)
585
- end
586
-
587
- nil
588
- end
589
-
590
- def set_dictionary(dic)
591
- err = deflateSetDictionary(@z.stream,dic,dic.length)
592
- if (err != Z_OK)
593
- raise_zlib_error(err, @z.stream.msg)
594
- end
595
- end
596
-
597
- end
598
-
599
- class Inflate < ZStream
600
-
601
- def self.inflate_run(src)
602
- @z.zstream_run(src,src.length,Z_SYNC_FLUSH)
603
- @z.zstream_run('',0,Z_FINISH)
604
- @z.zstream_detach_buffer()
605
- end
606
-
607
- def self.inflate(src)
608
- @z = ZStream.new
609
- @z.zstream_init(InflateFuncs)
610
- err = inflateInit(@z.stream)
611
- if (err != Z_OK)
612
- raise_zlib_error(err, @z.stream.msg)
613
- end
614
- @z.ZSTREAM_READY()
615
- begin
616
- dst = inflate_run(src)
617
- ensure
618
- @z.zstream_end
619
- end
620
- dst
621
- end
622
-
623
- def do_inflate(src)
624
- if(src.nil?)
625
- @z.zstream_run("", 0, Z_FINISH)
626
- return
627
- end
628
- if (src.length>0)
629
- @z.zstream_run(src,src.length,Z_SYNC_FLUSH)
630
- end
631
- end
632
- private :do_inflate
633
-
634
- def initialize(wbits=MAX_WBITS)
635
- @z = ZStream.new
636
- @z.zstream_init(InflateFuncs)
637
- err = inflateInit2(@z.stream, wbits)
638
- if (err != Z_OK)
639
- raise_zlib_error(err, @z.stream.msg)
640
- end
641
- @z.ZSTREAM_READY()
642
- end
643
-
644
- def inflate(src)
645
- if (@z.ZSTREAM_IS_FINISHED())
646
- if src.nil?
647
- dst = @z.zstream_detach_buffer()
648
- else
649
- @z.zstream_append_buffer(src,src.lenth)
650
- dst = ''
651
- end
652
- else
653
- do_inflate(src)
654
- dst = @z.zstream_detach_buffer()
655
- if (@z.ZSTREAM_IS_FINISHED())
656
- @z.zstream_passthrough_input()
657
- end
658
- end
659
- if block_given?
660
- yield dst
661
- else
662
- dst
663
- end
664
- end
665
-
666
- def <<(src)
667
- if @z.ZSTREAM_IS_FINISHED()
668
- if src
669
- @z.zstream_append_buffer(src,src.length)
670
- end
671
- else
672
- do_inflate(src)
673
- if @z.ZSTREAM_IS_FINISHED()
674
- @z.zstream_passthrough_input()
675
- end
676
- end
677
- self
678
- end
679
-
680
- def sync
681
- raise GzipFile::Error,"closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
682
- return @z.zstream_sync(src,src.length)
683
- end
684
-
685
- def sync_point?()
686
- err = inflateSyncPoint(@z.stream)
687
- return true if err == 1
688
-
689
- if err != Z_OK
690
- raise_zlib_error(err, @z.stream.msg)
691
- end
692
-
693
- false
694
- end
695
-
696
- def set_dictionary(dic)
697
- src = dic
698
- err = inflateSetDictionary(@z.stream,src,src.length)
699
-
700
- if err != Z_OK
701
- raise_zlib_error(err, @z.stream.msg)
702
- end
703
-
704
- dic
705
- end
706
-
707
- end
708
-
709
- class GzipFile
710
- GZ_MAGIC1 = 0x1f
711
- GZ_MAGIC2 = 0x8b
712
- GZ_METHOD_DEFLATE = 8
713
- GZ_FLAG_MULTIPART = 0x2
714
- GZ_FLAG_EXTRA = 0x4
715
- GZ_FLAG_ORIG_NAME = 0x8
716
- GZ_FLAG_COMMENT = 0x10
717
- GZ_FLAG_ENCRYPT = 0x20
718
- GZ_FLAG_UNKNOWN_MASK = 0xc0
719
-
720
- GZ_EXTRAFLAG_FAST = 0x4
721
- GZ_EXTRAFLAG_SLOW = 0x2
722
-
723
- OS_CODE = OS_UNIX
724
-
725
- GZFILE_FLAG_SYNC = ZSTREAM_FLAG_UNUSED
726
- GZFILE_FLAG_HEADER_FINISHED = (ZSTREAM_FLAG_UNUSED << 1)
727
- GZFILE_FLAG_FOOTER_FINISHED = (ZSTREAM_FLAG_UNUSED << 2)
728
-
729
- def GZFILE_IS_FINISHED(gz)
730
- gz.z.ZSTREAM_IS_FINISHED() && (gz.z.buf.nil? || gz.z.buf.offset.zero?)
731
- end
732
-
733
- GZFILE_READ_SIZE = 2048
734
-
735
- class Error < Zlib::Error
736
- end
737
-
738
- class NoFooter < Error
739
- end
740
-
741
- class CRCError < Error
742
- end
743
-
744
- class LengthError < Error
745
- end
746
-
747
- Gzfile = Struct.new(:z,:io,:level,:mtime,:os_code,:orig_name,:comment,:crc,:lineno,:ungetc,:end)
748
-
749
- def gzfile_close(closeflag)
750
- io = @gz.io
751
- send(@gz.end)
752
-
753
- @gz.io = nil
754
- @gz.orig_name = nil
755
- @gz.comment = nil
756
-
757
- if closeflag && defined?(io.close)
758
- io.close
759
- end
760
- end
761
-
762
- def gzfile_ensure_close()
763
- if @gz.z.ZSTREAM_IS_READY()
764
- gzfile_close(true)
765
- end
766
- nil
767
- end
768
-
769
- def self.wrap(io, level=Z_DEFAULT_COMPRESSION, strategy=Z_DEFAULT_STRATEGY)
770
- obj = new(io,level,strategy)
771
- if block_given?
772
- begin
773
- yield(obj)
774
- ensure
775
- obj.gzfile_ensure_close()
776
- end
777
- else
778
- return obj
779
- end
780
- end
781
-
782
- def to_io
783
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
784
- @gz.io
785
- end
786
-
787
- def crc
788
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
789
- @gz.crc
790
- end
791
-
792
- def mtime
793
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
794
- Time.at(@gz.mtime)
795
- end
796
-
797
- def level
798
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
799
- @gz.level
800
- end
801
-
802
- def os_code
803
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
804
- @gz.os_code
805
- end
806
-
807
- def orig_name
808
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
809
- @gz.orig_name ? @gz.orig_name.dup : nil
810
- end
811
-
812
- def comment
813
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
814
- @gz.comment ? @gz.comment.dup : nil
815
- end
816
-
817
- def close
818
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
819
- gzfile_close(true)
820
- @gz.io
821
- end
822
-
823
- def finish
824
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
825
- gzfile_close(false)
826
- @gz.io
827
- end
828
-
829
- def closed?
830
- @gz.io.nil?
831
- end
832
-
833
- def sync
834
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
835
- !(@gz.z.flags & GZFILE_FLAG_SYNC).zero?
836
- end
837
-
838
- def sync=(mode)
839
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
840
- if(mode)
841
- @gz.z.flags |= GZFILE_FLAG_SYNC
842
- else
843
- @gz.z.flags &= ~GZFILE_FLAG_SYNC
844
- end
845
- mode
846
- end
847
-
848
- def self.gzfile_s_open(filename,mode,level,strategy,&blk)
849
- io = File.open(filename,mode)
850
- self.wrap(io,level,strategy,&blk)
851
- end
852
-
853
- private
854
-
855
- def gzfile_new(funcs,endfunc)
856
- @gz = Gzfile.new
857
- @gz.z = ZStream.new
858
- @gz.z.zstream_init(funcs)
859
- @gz.io = nil
860
- @gz.level = 0
861
- @gz.mtime = 0
862
- @gz.os_code = OS_CODE
863
- @gz.orig_name = nil
864
- @gz.comment = nil
865
- @gz.crc = crc32(0,nil,0)
866
- @gz.lineno = 0
867
- @gz.ungetc = 0
868
- @gz.end = endfunc
869
- self
870
- end
871
-
872
- def gzfile_reset()
873
- @gz.z.zstream_reset
874
- @gz.crc = crc32(0,nil,0)
875
- @gz.lineno = 0
876
- @gz.ungetc = 0
877
- end
878
-
879
- def gzfile_get16(src)
880
- src.unpack('S').first
881
- end
882
-
883
- def gzfile_get32(src)
884
- src.unpack('L').first
885
- end
886
-
887
- def gzfile_set32(n)
888
- [n].pack('L')
889
- end
890
-
891
- def gzfile_make_header
892
- buf = 0.chr * 10
893
- flags = 0
894
- extraflags = 0
895
- if @gz.orig_name
896
- flags |= GZ_FLAG_ORIG_NAME
897
- end
898
- if @gz.comment
899
- flags |= GZ_FLAG_COMMENT
900
- end
901
- if @gz.mtime.zero?
902
- @gz.mtime = Time.now.to_i
903
- end
904
- if (@gz.level == Z_BEST_SPEED)
905
- extraflags |= GZ_EXTRAFLAG_FAST
906
- elsif (@gz.level == Z_BEST_COMPRESSION)
907
- extraflags |= GZ_EXTRAFLAG_SLOW
908
- end
909
- buf[0] = GZ_MAGIC1.chr
910
- buf[1] = GZ_MAGIC2.chr
911
- buf[2] = GZ_METHOD_DEFLATE.chr
912
- buf[3] = flags.chr
913
- buf[4,4] = gzfile_set32(@gz.mtime)
914
- buf[8] = extraflags.chr
915
- buf[9] = @gz.os_code.chr
916
- @gz.z.zstream_append_buffer(buf,buf.length)
917
-
918
- if @gz.orig_name
919
- @gz.z.zstream_append_buffer(@gz.orig_name,@gz.orig_name.length)
920
- @gz.z.zstream_append_buffer("\0", 1)
921
- end
922
- if @gz.comment
923
- @gz.z.zstream_append_buffer(@gz.comment,@gz.comment.length)
924
- @gz.z.zstream_append_buffer("\0", 1)
925
- end
926
-
927
- @gz.z.flags |= GZFILE_FLAG_HEADER_FINISHED
928
- end
929
-
930
- def gzfile_make_footer()
931
- buf = 0.chr * 8
932
- buf[0,4] = gzfile_set32(@gz.crc)
933
- buf[4,4] = gzfile_set32(@gz.z.stream.total_in)
934
- @gz.z.zstream_append_buffer(buf, buf.length)
935
- @gz.z.flags |= GZFILE_FLAG_FOOTER_FINISHED
936
- end
937
-
938
- def gzfile_read_header()
939
- if !gzfile_read_raw_ensure(10)
940
- raise GzipFile::Error, "not in gzip format"
941
- end
942
-
943
- head = @gz.z.input
944
-
945
- if (head[0].ord != GZ_MAGIC1 || head[1].ord != GZ_MAGIC2)
946
- raise GzipFile::Error, "not in gzip format"
947
- end
948
- if (head[2].ord != GZ_METHOD_DEFLATE)
949
- raise GzipFile::Error, "unsupported compression method #{head[2].ord}"
950
- end
951
-
952
- flags = head[3].ord
953
- if (flags & GZ_FLAG_MULTIPART).nonzero?
954
- raise GzipFile::Error, "multi-part gzip file is not supported"
955
- elsif (flags & GZ_FLAG_ENCRYPT).nonzero?
956
- raise GzipFile::Error, "encrypted gzip file is not supported"
957
- elsif (flags & GZ_FLAG_UNKNOWN_MASK).nonzero?
958
- raise GzipFile::Error, "unknown flags 0x%02x" % flags
959
- end
960
-
961
- if (head[8].ord & GZ_EXTRAFLAG_FAST).nonzero?
962
- @gz.level = Z_BEST_SPEED
963
- elsif (head[8].ord & GZ_EXTRAFLAG_SLOW).nonzero?
964
- @gz.level = Z_BEST_COMPRESSION
965
- else
966
- @gz.level = Z_DEFAULT_COMPRESSION
967
- end
968
-
969
- @gz.mtime = gzfile_get32(head[4,4])
970
- @gz.os_code = head[9].ord
971
- @gz.z.zstream_discard_input(10)
972
-
973
- if (flags & GZ_FLAG_EXTRA).nonzero?
974
- if !gzfile_read_raw_ensure(2)
975
- raise GzipFile::Error, "unexpected end of file"
976
- end
977
- len = gzfile_get16(@gz.z.input)
978
- if !gzfile_read_raw_ensure(2 + len)
979
- raise GzipFile::Error, "unexpected end of file"
980
- end
981
- @gz.z.zstream_discard_input(2 + len)
982
- end
983
- if (flags & GZ_FLAG_ORIG_NAME).nonzero?
984
- ap = gzfile_read_raw_until_zero(0)
985
- len = ap
986
- @gz.orig_name = @gz.z.input[0,len]
987
- @gz.z.zstream_discard_input(len + 1)
988
- end
989
- if (flags & GZ_FLAG_COMMENT).nonzero?
990
- ap = gzfile_read_raw_until_zero(0)
991
- len = ap
992
- @gz.comment = @gz.z.input[0,len]
993
- @gz.z.zstream_discard_input(len + 1)
994
- end
995
-
996
- if (@gz.z.input && @gz.z.input.length > 0)
997
- @gz.z.zstream_run(0, 0, Z_SYNC_FLUSH)
998
- end
999
- end
1000
-
1001
- def gzfile_check_footer()
1002
- @gz.z.flags |= GZFILE_FLAG_FOOTER_FINISHED
1003
-
1004
- if (!gzfile_read_raw_ensure(8))
1005
- raise NoFooter, "footer is not found"
1006
- end
1007
- crc = gzfile_get32(@gz.z.input)
1008
- length = gzfile_get32(@gz.z.input[4,4])
1009
- @gz.z.stream.total_in += 8
1010
- @gz.z.zstream_discard_input(8)
1011
- if (@gz.crc != crc)
1012
- raise CRCError, "invalid compressed data -- crc error"
1013
- end
1014
- if (@gz.z.stream.total_out != length)
1015
- raise LengthError, "invalid compressed data -- length error"
1016
- end
1017
- end
1018
-
1019
- def gzfile_calc_crc(str)
1020
- if (str.length <= @gz.ungetc)
1021
- @gz.ungetc -= str.length
1022
- else
1023
- @gz.crc = crc32(@gz.crc, str[@gz.ungetc,str.length - @gz.ungetc],
1024
- str.length - @gz.ungetc)
1025
- @gz.ungetc = 0
1026
- end
1027
- end
1028
-
1029
- end
1030
-
1031
- class GzipWriter < GzipFile
1032
-
1033
- def mtime=(mtime)
1034
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1035
-
1036
- if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).nonzero?
1037
- raise GzipFile::Error,"header is already written"
1038
- end
1039
-
1040
- @gz.mtime = mtime.to_i
1041
- end
1042
-
1043
- def orig_name=(str)
1044
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1045
-
1046
- if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).nonzero?
1047
- raise GzipFile::Error,"header is already written"
1048
- end
1049
-
1050
- ap = str[0.chr]
1051
- @gz.orig_name = ap ? str[0,ap] : str.dup
1052
- end
1053
-
1054
- def comment=(str)
1055
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1056
-
1057
- if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).nonzero?
1058
- raise GzipFile::Error,"header is already written"
1059
- end
1060
-
1061
- @gz.comment = str.dup
1062
- end
1063
-
1064
- def pos
1065
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1066
- @gz.z.stream.total_in
1067
- end
1068
-
1069
- alias tell :pos
1070
-
1071
- def self.open(filename, level=Z_DEFAULT_COMPRESSION, strategy=Z_DEFAULT_STRATEGY, &blk)
1072
- GzipWriter.gzfile_s_open(filename, 'wb', level, strategy, &blk)
1073
- end
1074
-
1075
- def initialize(io, level=Z_DEFAULT_COMPRESSION, strategy=Z_DEFAULT_STRATEGY)
1076
- gzfile_new(DeflateFuncs, :gzfile_writer_end)
1077
- @gz.level = level
1078
-
1079
- err = deflateInit2(
1080
- @gz.z.stream,
1081
- @gz.level,
1082
- Z_DEFLATED,
1083
- -MAX_WBITS,
1084
- DEF_MEM_LEVEL,
1085
- strategy
1086
- )
1087
-
1088
- if err != Z_OK
1089
- raise_zlib_error(err, @gz.stream.msg)
1090
- end
1091
-
1092
- @gz.io = io
1093
- @gz.z.ZSTREAM_READY()
1094
- end
1095
-
1096
- def flush(v_flush=Z_SYNC_FLUSH)
1097
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1098
-
1099
- if v_flush != Z_NO_FLUSH
1100
- @gz.z.zstream_run("", 0, v_flush)
1101
- end
1102
-
1103
- gzfile_write_raw()
1104
-
1105
- if defined?(@gz.io.flush)
1106
- @gz.io.flush()
1107
- end
1108
-
1109
- self
1110
- end
1111
-
1112
- def write(str)
1113
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1114
- str = str.to_s
1115
- gzfile_write(str, str.length)
1116
- str.length
1117
- end
1118
-
1119
- def putc(ch)
1120
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1121
- gzfile_write(ch.chr, 1)
1122
- ch
1123
- end
1124
-
1125
- def <<(str)
1126
- @gz.io << str
1127
- end
1128
-
1129
- def printf(*arg)
1130
- @gz.io.printf(*arg)
1131
- end
1132
-
1133
- def print(*arg)
1134
- @gz.io.print(*arg)
1135
- end
1136
-
1137
- def puts(str)
1138
- @gz.io.puts(str)
1139
- end
1140
-
1141
- def gzfile_write_raw
1142
- if (@gz.z.buf.offset > 0)
1143
- str = @gz.z.zstream_detach_buffer()
1144
- @gz.io.write(str)
1145
- if ((@gz.z.flags & GZFILE_FLAG_SYNC).nonzero? && defined?(@gz.io.flush))
1146
- @gz.io.flush()
1147
- end
1148
- end
1149
- end
1150
-
1151
- private :gzfile_write_raw
1152
-
1153
- def gzfile_write(str,len)
1154
- if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).zero?
1155
- gzfile_make_header()
1156
- end
1157
-
1158
- if (len > 0 || (@gz.z.flags & GZFILE_FLAG_SYNC))
1159
- @gz.crc = crc32(@gz.crc, str, len)
1160
- @gz.z.zstream_run(str, len, (@gz.z.flags & GZFILE_FLAG_SYNC).nonzero? ?
1161
- Z_SYNC_FLUSH : Z_NO_FLUSH)
1162
- end
1163
- gzfile_write_raw()
1164
- end
1165
-
1166
- private :gzfile_write
1167
-
1168
- def gzfile_writer_end_run
1169
- if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).zero?
1170
- gzfile_make_header()
1171
- end
1172
- @gz.z.zstream_run("", 0, Z_FINISH)
1173
- gzfile_make_footer()
1174
- gzfile_write_raw()
1175
-
1176
- return nil
1177
- end
1178
-
1179
- def gzfile_writer_end
1180
- return if @gz.z.ZSTREAM_IS_CLOSING()
1181
- @gz.z.flags |= ZSTREAM_FLAG_CLOSING
1182
- begin
1183
- gzfile_writer_end_run()
1184
- ensure
1185
- @gz.z.zstream_end()
1186
- end
1187
- end
1188
- end
1189
-
1190
- class GzipReader < GzipFile
1191
- include Enumerable
1192
-
1193
- def lineno
1194
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1195
- @gz.lineno
1196
- end
1197
-
1198
- def lineno=(lineno)
1199
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1200
- @gz.lineno = lineno
1201
- end
1202
-
1203
- def eof
1204
- raise GzipFile::Error,"closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1205
- GZFILE_IS_FINISHED(@gz)
1206
- end
1207
- alias eof? :eof
1208
-
1209
- def pos
1210
- if @gz.z.buf.nil?
1211
- @gz.z.stream.total_out
1212
- else
1213
- @gz.z.stream.total_out - @gz.z.buf.offset
1214
- end
1215
- end
1216
- alias tell :pos
1217
-
1218
- def self.open(filename,level=Z_DEFAULT_COMPRESSION,strategy=Z_DEFAULT_STRATEGY,&blk)
1219
- GzipReader.gzfile_s_open(filename,"rb",level=Z_DEFAULT_COMPRESSION,strategy=Z_DEFAULT_STRATEGY,&blk)
1220
- end
1221
-
1222
- def initialize(io,level=Z_DEFAULT_COMPRESSION,strategy=Z_DEFAULT_STRATEGY)
1223
- gzfile_new(InflateFuncs, :gzfile_reader_end)
1224
- @gz.level = level
1225
- err = inflateInit2(@gz.z.stream, -MAX_WBITS)
1226
- if (err != Z_OK)
1227
- raise_zlib_error(err, @gz.stream.msg)
1228
- end
1229
- @gz.io = io
1230
- @gz.z.ZSTREAM_READY()
1231
- gzfile_read_header()
1232
- self
1233
- end
1234
-
1235
- def rewind()
1236
- gzfile_reader_rewind()
1237
- return 0
1238
- end
1239
-
1240
- def unused()
1241
- gzfile_reader_get_unused()
1242
- end
1243
-
1244
- def read(len=nil)
1245
- if len.nil?
1246
- return gzfile_read_all()
1247
- end
1248
-
1249
- if len < 0
1250
- raise ArgumentError, "negative length #{len} given"
1251
- end
1252
-
1253
- return gzfile_read(len)
1254
- end
1255
-
1256
- def getc()
1257
- dst = gzfile_read(1)
1258
- dst ? dst[0] : dst
1259
- end
1260
-
1261
- def readchar()
1262
- dst = getc()
1263
- if dst.nil?
1264
- raise EOFError, "end of file reached"
1265
- end
1266
- dst
1267
- end
1268
-
1269
- def each_byte()
1270
- while (c = getc)
1271
- yield(c)
1272
- end
1273
- nil
1274
- end
1275
-
1276
- def ungetc(ch)
1277
- gzfile_ungetc(ch)
1278
- nil
1279
- end
1280
-
1281
- def gets(rs=$/)
1282
- dst = gzreader_gets(rs)
1283
- $_ = dst if dst
1284
- dst
1285
- end
1286
-
1287
- def readline(rs=$/)
1288
- gets(rs)
1289
- end
1290
-
1291
- def each(rs=$/)
1292
- while (str = gzreader_gets(rs))
1293
- yield(str)
1294
- end
1295
- self
1296
- end
1297
- alias each_line :each
1298
-
1299
- def readlines(rs=$/)
1300
- dst = []
1301
- while str = gzreader_gets(rs)
1302
- dst.push(str)
1303
- end
1304
- dst
1305
- end
1306
-
1307
- private
1308
-
1309
- def gzfile_reader_end_run()
1310
- if (GZFILE_IS_FINISHED(@gz) && (@gz.z.flags &
1311
- GZFILE_FLAG_FOOTER_FINISHED).zero?)
1312
- gzfile_check_footer()
1313
- end
1314
- nil
1315
- end
1316
-
1317
- def gzfile_reader_end()
1318
- return if @gz.z.ZSTREAM_IS_CLOSING()
1319
- @gz.z.flags |= ZSTREAM_FLAG_CLOSING
1320
- begin
1321
- gzfile_reader_end_run()
1322
- ensure
1323
- @gz.z.zstream_end()
1324
- end
1325
- end
1326
-
1327
- def gzfile_ungetc(c)
1328
- @gz.z.zstream_buffer_ungetc(c)
1329
- @gz.ungetc+=1
1330
- end
1331
-
1332
- def gzfile_reader_rewind
1333
- n = @gz.z.stream.total_in
1334
- if @gz.z.input
1335
- n += @gz.z.input.length
1336
- end
1337
- @gz.io.seek(-n,1)
1338
- gzfile_reset()
1339
- end
1340
-
1341
- def gzfile_reader_get_unused()
1342
- return nil if (!@gz.z.ZSTREAM_IS_READY())
1343
- return nil if (!GZFILE_IS_FINISHED(@gz))
1344
- if (@gz.z.flags & GZFILE_FLAG_FOOTER_FINISHED).zero?
1345
- gzfile_check_footer()
1346
- end
1347
- return nil if @gz.z.input.nil?
1348
- @gz.z.input.dup
1349
- end
1350
-
1351
- def rscheck(rsptr,rslen,rs)
1352
- raise RuntimeError, "rs modified" if rs != rsptr
1353
- end
1354
-
1355
- def gzreader_gets(rs=$/)
1356
- if rs && rs.class != String
1357
- raise TypeError,"wrong argument type #{rs.class} (expected String)"
1358
- end
1359
- if rs.nil?
1360
- dst = gzfile_read_all()
1361
- @gz.lineno += 1 if dst.length.nonzero?
1362
- return dst
1363
- end
1364
- if rs.length.zero?
1365
- rsptr = "\n\n"
1366
- rslen = 2
1367
- rspara = true
1368
- else
1369
- rsptr = rs
1370
- rslen = rs.length
1371
- rspara = false
1372
- end
1373
- if rspara
1374
- gzreader_skip_linebreaks
1375
- end
1376
- while (@gz.z.buf.offset < rslen)
1377
- if (@gz.z.ZSTREAM_IS_FINISHED())
1378
- @gz.lineno+=1 if (@gz.z.buf.offset > 0)
1379
- return gzfile_read(rslen)
1380
- end
1381
- gzfile_read_more()
1382
- end
1383
-
1384
- ap = 0
1385
- n = rslen
1386
- loop do
1387
- if (n > @gz.z.buf.offset)
1388
- break if (@gz.z.ZSTREAM_IS_FINISHED())
1389
- gzfile_read_more()
1390
- ap = n - rslen
1391
- end
1392
-
1393
- rscheck(rsptr, rslen, rs) if (!rspara)
1394
- res = @gz.z.buf.buffer[ap,@gz.z.buf.offset - n + 1].index(rsptr[0])
1395
-
1396
- if res.nil?
1397
- n = @gz.z.buf.offset + 1
1398
- else
1399
- n += (res - ap)
1400
- ap = res
1401
- break if (rslen == 1 || @gz.z.buf.buffer[ap,rslen]==rsptr)
1402
- ap+=1
1403
- n+=1
1404
- end
1405
- end
1406
-
1407
- @gz.lineno+=1
1408
- dst = gzfile_read(n)
1409
- if (rspara)
1410
- gzreader_skip_linebreaks()
1411
- end
1412
- dst
1413
- end
1414
-
1415
- def gzfile_read(len)
1416
- if len < 0
1417
- raise ArgumentError, "negative length #{len} given"
1418
- end
1419
-
1420
- if len.zero?
1421
- return ""
1422
- end
1423
-
1424
- while (!@gz.z.ZSTREAM_IS_FINISHED() && @gz.z.buf.offset < len)
1425
- gzfile_read_more()
1426
- end
1427
-
1428
- if (GZFILE_IS_FINISHED(@gz))
1429
- if (@gz.z.flags & GZFILE_FLAG_FOOTER_FINISHED).zero?
1430
- gzfile_check_footer()
1431
- end
1432
- return nil
1433
- end
1434
-
1435
- dst = @gz.z.zstream_shift_buffer(len)
1436
- gzfile_calc_crc(dst)
1437
- dst
1438
- end
1439
-
1440
- def gzfile_read_all()
1441
- while (!@gz.z.ZSTREAM_IS_FINISHED())
1442
- gzfile_read_more()
1443
- end
1444
- if (GZFILE_IS_FINISHED(@gz))
1445
- if (@gz.z.flags & GZFILE_FLAG_FOOTER_FINISHED).zero?
1446
- gzfile_check_footer()
1447
- end
1448
- return ''
1449
- end
1450
-
1451
- dst = @gz.z.zstream_detach_buffer()
1452
- gzfile_calc_crc(dst)
1453
- dst
1454
- end
1455
-
1456
- def gzfile_read_raw()
1457
- str = @gz.io.read(GZFILE_READ_SIZE)
1458
- if str && str.class != String
1459
- raise TypeError,"wrong argument type #{rs.class} (expected String)"
1460
- end
1461
- str
1462
- end
1463
-
1464
- def gzfile_read_raw_ensure(size)
1465
- while @gz.z.input.nil? || @gz.z.input.length < size
1466
- str = gzfile_read_raw()
1467
- return false if str.nil?
1468
- @gz.z.zstream_append_input(str,str.length)
1469
- end
1470
- true
1471
- end
1472
-
1473
- def gzfile_read_raw_until_zero(offset)
1474
- ap = nil
1475
-
1476
- loop do
1477
- ap = @gz.z.input[offset, @gz.z.input.length-offset].index(0.chr)
1478
- break if ap
1479
- str = gzfile_read_raw()
1480
-
1481
- raise Error, "unexpected end of file" if str.nil?
1482
-
1483
- offset = @gz.z.input.length
1484
- @gz.z.zstream_append_input(str,str.length)
1485
- end
1486
-
1487
- ap
1488
- end
1489
-
1490
- def gzfile_read_more
1491
- while (!@gz.z.ZSTREAM_IS_FINISHED())
1492
- str = gzfile_read_raw()
1493
- if str.nil?
1494
- if (!@gz.z.ZSTREAM_IS_FINISHED())
1495
- raise Error, "unexpected end of file"
1496
- end
1497
- break
1498
- end
1499
- if (str.length > 0)
1500
- @gz.z.zstream_run(str, str.length,Z_SYNC_FLUSH)
1501
- end
1502
- break if (@gz.z.buf.offset > 0)
1503
- end
1504
- @gz.z.buf.offset
1505
- end
1506
- end
1507
-
1508
- module_function
1509
-
1510
- def zlib_version
1511
- zlibVersion()
1512
- end
1513
-
1514
- def adler32(string=nil, adler=nil)
1515
- if adler
1516
- [adler].pack('L') # check range
1517
- sum = adler
1518
- elsif string.nil?
1519
- sum = 0
1520
- else
1521
- sum = Rbzlib.adler32(0,nil)
1522
- end
1523
-
1524
- if string.nil?
1525
- sum = Rbzlib.adler32(sum,nil)
1526
- else
1527
- sum = Rbzlib.adler32(sum,string,string.length)
1528
- end
1529
- sum
1530
- end
1531
-
1532
- def crc32(string=nil, adler=nil)
1533
- if adler
1534
- [adler].pack('L') # check range
1535
- sum = adler
1536
- elsif string.nil?
1537
- sum = 0
1538
- else
1539
- sum = Rbzlib.crc32(0,nil)
1540
- end
1541
-
1542
- if string.nil?
1543
- sum = Rbzlib.crc32(sum,nil)
1544
- else
1545
- sum = Rbzlib.crc32(sum,string,string.length)
1546
- end
1547
- sum
1548
- end
1549
-
1550
- def crc_table
1551
- get_crc_table
1552
- end
1553
-
1554
- end
1
+ # zlib.rb -- An interface for rbzlib
2
+ # Copyright (C) UENO Katsuhiro 2000-2003
3
+ #
4
+ # Ruby translation by Park Heesob
5
+
6
+ require_relative 'rbzlib'
7
+ include Rbzlib
8
+
9
+ module Zlib
10
+
11
+ RUBY_ZLIB_VERSION = '0.6.0'
12
+ PR_ZLIB_VERSION = '1.0.2'
13
+
14
+ class Error < StandardError
15
+ end
16
+
17
+ class StreamEnd < Error
18
+ end
19
+
20
+ class NeedDict < Error
21
+ end
22
+
23
+ class DataError < Error
24
+ end
25
+
26
+ class StreamError < Error
27
+ end
28
+
29
+ class MemError < Error
30
+ end
31
+
32
+ class BufError < Error
33
+ end
34
+
35
+ class VersionError < Error
36
+ end
37
+
38
+ VERSION = RUBY_ZLIB_VERSION
39
+ ZLIB_VERSION = ZLIB_VERSION
40
+
41
+ BINARY = Z_BINARY
42
+ ASCII = Z_ASCII
43
+ UNKNOWN = Z_UNKNOWN
44
+
45
+ NO_COMPRESSION = Z_NO_COMPRESSION
46
+ BEST_SPEED = Z_BEST_SPEED
47
+ BEST_COMPRESSION = Z_BEST_COMPRESSION
48
+ DEFAULT_COMPRESSION = Z_DEFAULT_COMPRESSION
49
+
50
+ FILTERED = Z_FILTERED
51
+ HUFFMAN_ONLY = Z_HUFFMAN_ONLY
52
+ DEFAULT_STRATEGY = Z_DEFAULT_STRATEGY
53
+ MAX_WBITS = MAX_WBITS
54
+ DEF_MEM_LEVEL = DEF_MEM_LEVEL
55
+ MAX_MEM_LEVEL = MAX_MEM_LEVEL
56
+ NO_FLUSH = Z_NO_FLUSH
57
+ SYNC_FLUSH = Z_SYNC_FLUSH
58
+ FULL_FLUSH = Z_FULL_FLUSH
59
+ FINISH = Z_FINISH
60
+
61
+ OS_CODE = OS_CODE
62
+ OS_MSDOS = 0x00
63
+ OS_AMIGA = 0x01
64
+ OS_VMS = 0x02
65
+ OS_UNIX = 0x03
66
+ OS_ATARI = 0x05
67
+ OS_OS2 = 0x06
68
+ OS_MACOS = 0x07
69
+ OS_TOPS20 = 0x0a
70
+ OS_WIN32 = 0x0b
71
+
72
+ ZSTREAM_FLAG_READY = 0x1
73
+ ZSTREAM_FLAG_IN_STREAM = 0x2
74
+ ZSTREAM_FLAG_FINISHED = 0x4
75
+ ZSTREAM_FLAG_CLOSING = 0x8
76
+ ZSTREAM_FLAG_UNUSED = 0x10
77
+
78
+ ZSTREAM_INITIAL_BUFSIZE = 1024
79
+ ZSTREAM_AVAIL_OUT_STEP_MAX = 16384
80
+ ZSTREAM_AVAIL_OUT_STEP_MIN = 2048
81
+
82
+ ZStreamFuncs = Struct.new(:reset, :end, :run)
83
+ DeflateFuncs = ZStreamFuncs.new(:deflateReset, :deflateEnd, :deflate)
84
+ InflateFuncs = ZStreamFuncs.new(:inflateReset, :inflateEnd, :inflate)
85
+
86
+ class ZStream
87
+ attr_accessor :flags, :buf, :input, :stream, :func
88
+
89
+ def raise_zlib_error(err, msg)
90
+ msg = zError(err) if msg.nil? || msg==''
91
+
92
+ case err
93
+ when Z_STREAM_END
94
+ raise StreamEnd, msg
95
+ when Z_NEED_DICT
96
+ raise NeedDict, msg
97
+ when Z_STREAM_ERROR
98
+ raise StreamError, msg
99
+ when Z_DATA_ERROR
100
+ raise DataError, msg
101
+ when Z_BUF_ERROR
102
+ raise BufError, msg
103
+ when Z_VERSION_ERROR
104
+ raise VersionError, msg
105
+ when Z_MEM_ERROR
106
+ raise MemError, msg
107
+ when Z_ERRNO
108
+ raise SystemCallError, msg
109
+ else
110
+ raise Error, "unknown zlib error #errend: #msgend"
111
+ end
112
+ end
113
+
114
+ def zstream_expand_buffer()
115
+ if @buf.nil?
116
+ @buf = Bytef.new(0.chr * ZSTREAM_INITIAL_BUFSIZE)
117
+ @stream.next_out = Bytef.new(@buf)
118
+ @stream.avail_out = ZSTREAM_INITIAL_BUFSIZE
119
+ return
120
+ end
121
+
122
+ if (@buf.length - @buf.offset >= ZSTREAM_AVAIL_OUT_STEP_MAX)
123
+ @stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX
124
+ else
125
+ inc = @buf.offset / 2
126
+ if (inc < ZSTREAM_AVAIL_OUT_STEP_MIN)
127
+ inc = ZSTREAM_AVAIL_OUT_STEP_MIN
128
+ end
129
+ if @buf.length < @buf.offset + inc
130
+ @buf.buffer << 0.chr * (@buf.offset + inc - @buf.length)
131
+ end
132
+ @stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?
133
+ inc : ZSTREAM_AVAIL_OUT_STEP_MAX
134
+ end
135
+ @stream.next_out = Bytef.new(@buf,@buf.offset)
136
+ end
137
+
138
+ def zstream_append_buffer(src, len)
139
+ if @buf.nil?
140
+ @buf = Bytef.new(src[0,len],len)
141
+ @stream.next_out = Bytef.new(@buf)
142
+ @stream.avail_out = 0
143
+ return
144
+ end
145
+ if (@buf.length < @buf.offset + len)
146
+ @buf.buffer << (0.chr * (@buf.offset + len - @buf.length))
147
+ @stream.avail_out = 0
148
+ else
149
+ if (@stream.avail_out >= len)
150
+ @stream.avail_out -= len
151
+ else
152
+ @stream.avail_out = 0
153
+ end
154
+ end
155
+ @buf.buffer[@buf.offset,len] = src[0,len]
156
+ @buf += len
157
+ @stream.next_out = Bytef.new(@buf, @buf.offset)
158
+ end
159
+
160
+ def zstream_detach_buffer()
161
+ if @buf.nil?
162
+ dst = ''
163
+ else
164
+ dst = @buf.buffer[0,@buf.offset]
165
+ end
166
+
167
+ @buf = Bytef.new(0.chr * ZSTREAM_INITIAL_BUFSIZE)
168
+ @stream.next_out = Bytef.new(@buf)
169
+ @stream.avail_out = ZSTREAM_INITIAL_BUFSIZE
170
+ @buf_filled = 0
171
+
172
+ return dst
173
+ end
174
+
175
+ def zstream_shift_buffer(len)
176
+ if (@buf.offset <= len)
177
+ return zstream_detach_buffer()
178
+ end
179
+
180
+ dst = @buf.buffer[0, len]
181
+ @buf -= len
182
+ @buf.buffer[0,@buf.offset] = @buf.buffer[len,@buf.offset]
183
+ @stream.next_out = Bytef.new(@buf,@buf.offset)
184
+ @stream.avail_out = @buf.length - @buf.offset
185
+ if (@stream.avail_out > ZSTREAM_AVAIL_OUT_STEP_MAX)
186
+ @stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX
187
+ end
188
+ return dst
189
+ end
190
+
191
+ def zstream_buffer_ungetc(c)
192
+ if (@buf.nil? || (@buf.length - @buf.offset).zero?)
193
+ zstream_expand_buffer()
194
+ end
195
+ @buf.buffer[0,0] = c.chr
196
+ @buf += 1
197
+ if (@stream.avail_out > 0)
198
+ @stream.next_out+=1
199
+ @stream.avail_out-=1
200
+ end
201
+ end
202
+
203
+ def zstream_append_input(src, len)
204
+ return if (len <= 0)
205
+ src = src.current if src.class != String
206
+ if @input.nil?
207
+ @input = src[0,len]
208
+ else
209
+ @input << src[0,len]
210
+ end
211
+ end
212
+
213
+ def zstream_discard_input(len)
214
+ if (@input.nil? || @input.length <= len)
215
+ @input = nil
216
+ else
217
+ @input[0,len] = ''
218
+ end
219
+ end
220
+
221
+ def zstream_reset_input()
222
+ @input = nil
223
+ end
224
+
225
+ def zstream_passthrough_input()
226
+ if @input
227
+ zstream_append_buffer(@input,@input.length)
228
+ @input = nil
229
+ end
230
+ end
231
+
232
+ def zstream_detach_input()
233
+ if @input.nil?
234
+ dst = ''
235
+ else
236
+ dst = @input
237
+ end
238
+ @input = nil
239
+ return dst
240
+ end
241
+
242
+ def zstream_reset()
243
+ err = send(@func.reset,@stream)
244
+ if (err != Z_OK)
245
+ raise_zlib_error(err, @stream.msg)
246
+ end
247
+ @flags = ZSTREAM_FLAG_READY
248
+ @buf = nil
249
+ @buf_filled = 0
250
+ @stream.next_out = 0
251
+ @stream.avail_out = 0
252
+ zstream_reset_input()
253
+ end
254
+
255
+ def zstream_end()
256
+ if (!ZSTREAM_IS_READY())
257
+ warn("attempt to close uninitialized zstream; ignored.")
258
+ return nil
259
+ end
260
+ if (@flags & ZSTREAM_FLAG_IN_STREAM).nonzero?
261
+ warn("attempt to close unfinished zstream; reset forced.")
262
+ zstream_reset()
263
+ end
264
+
265
+ zstream_reset_input()
266
+ err = send(@func.end,@stream)
267
+ if (err != Z_OK)
268
+ raise_zlib_error(err, @stream.msg)
269
+ end
270
+ @flags = 0
271
+ return nil
272
+ end
273
+
274
+ def zstream_sync(src, len)
275
+ if @input
276
+ @stream.next_in = Bytef.new(@input)
277
+ @stream.avail_in = @input.length
278
+ err = inflateSync(@stream)
279
+ if (err == Z_OK)
280
+ zstream_discard_input(@input.length - @stream.avail_in)
281
+ zstream_append_input(src, len)
282
+ return true
283
+ end
284
+ zstream_reset_input()
285
+ if (err != Z_DATA_ERROR)
286
+ rest = @stream.next_in.buffer[0,@stream.avail_in]
287
+ raise_zlib_error(err, @stream.msg)
288
+ end
289
+ end
290
+
291
+ return false if (len <= 0)
292
+
293
+ @stream.next_in = src
294
+ @stream.avail_in = len
295
+ err = inflateSync(@stream)
296
+ if (err == Z_OK)
297
+ zstream_append_input(@stream.next_in, @stream.avail_in)
298
+ return true
299
+ end
300
+ if (err != Z_DATA_ERROR)
301
+ rest = @stream.next_in.buffer[0,@stream.avail_in]
302
+ raise_zlib_error(err, @stream.msg)
303
+ end
304
+ return false
305
+ end
306
+
307
+ def zstream_init(func)
308
+ @flags = 0
309
+ @buf = nil
310
+ @input = nil
311
+ @stream = Z_stream.new
312
+ @stream.msg = ''
313
+ @stream.next_in = nil
314
+ @stream.avail_in = 0
315
+ @stream.next_out = nil
316
+ @stream.avail_out = 0
317
+ @func = func
318
+ end
319
+
320
+ def zstream_run(src, len, flush)
321
+ if(@input.nil? && len==0)
322
+ @stream.next_in = ''
323
+ @stream.avail_in = 0
324
+ else
325
+ zstream_append_input(src,len)
326
+ @stream.next_in = Bytef.new(@input)
327
+ @stream.avail_in = @input.length
328
+ guard = @input
329
+ end
330
+ if(@stream.avail_out.zero?)
331
+ zstream_expand_buffer()
332
+ end
333
+
334
+ loop do
335
+ n = @stream.avail_out
336
+ err = send(@func.run,@stream,flush)
337
+ @buf += n - @stream.avail_out
338
+ if(err == Z_STREAM_END)
339
+ @flags &= ~ZSTREAM_FLAG_IN_STREAM
340
+ @flags |= ZSTREAM_FLAG_FINISHED
341
+ break
342
+ end
343
+ if (err != Z_OK)
344
+ if (flush != Z_FINISH && err == Z_BUF_ERROR && @stream.avail_out > 0)
345
+ @flags |= ZSTREAM_FLAG_IN_STREAM
346
+ break
347
+ end
348
+ @input = nil
349
+ if (@stream.avail_in > 0)
350
+ zstream_append_input(@stream.next_in, @stream.avail_in)
351
+ end
352
+ raise_zlib_error(err, @stream.msg)
353
+ end
354
+ if (@stream.avail_out > 0)
355
+ @flags |= ZSTREAM_FLAG_IN_STREAM
356
+ break
357
+ end
358
+ zstream_expand_buffer()
359
+ end
360
+
361
+ @input = nil
362
+ if (@stream.avail_in > 0)
363
+ zstream_append_input(@stream.next_in, @stream.avail_in)
364
+ guard = nil
365
+ end
366
+ end
367
+
368
+ def ZSTREAM_READY()
369
+ (@flags |= ZSTREAM_FLAG_READY)
370
+ end
371
+
372
+ def ZSTREAM_IS_READY()
373
+ !(@flags & ZSTREAM_FLAG_READY).zero?
374
+ end
375
+
376
+ def ZSTREAM_IS_FINISHED()
377
+ !(@flags & ZSTREAM_FLAG_FINISHED).zero?
378
+ end
379
+
380
+ def ZSTREAM_IS_CLOSING()
381
+ !(@flags & ZSTREAM_FLAG_CLOSING).zero?
382
+ end
383
+
384
+ end
385
+
386
+ class ZStream
387
+ @@final = proc do |z|
388
+ proc do
389
+ if z && z.ZSTREAM_IS_READY()
390
+ err = send(z.func.end, z.stream)
391
+ if (err == Z_STREAM_ERROR)
392
+ warn("the stream state was inconsistent.")
393
+ end
394
+ if (err == Z_DATA_ERROR)
395
+ warn("the stream was freed prematurely.")
396
+ end
397
+ end
398
+ end
399
+ end
400
+
401
+ attr_reader :z
402
+
403
+ def avail_out()
404
+ @z.stream.avail_out
405
+ end
406
+
407
+ def avail_out=(size)
408
+ if @z.buf.nil?
409
+ @z.buf = Bytef.new(0.chr * size)
410
+ @z.stream.next_out = Bytef.new(@z.buf)
411
+ @z.stream.avail_out = size
412
+ elsif @z.stream.avail_out != size
413
+ if @z.buf.offset + size > @z.buf.length
414
+ @z.buf.buffer << 0.chr * (@z.buf.offset + size - @z.buf.length)
415
+ end
416
+ @z.stream.next_out = Bytef.new(@z.buf,@z.buf.offset)
417
+ @z.stream.avail_out = size
418
+ end
419
+ end
420
+
421
+ def avail_in
422
+ @z.input.nil? ? 0 : @z.input.length
423
+ end
424
+
425
+ def total_in
426
+ raise GzipFile::Error,"closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
427
+ @z.stream.total_in
428
+ end
429
+
430
+ def total_out
431
+ raise GzipFile::Error,"closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
432
+ @z.stream.total_out
433
+ end
434
+
435
+ def data_type
436
+ @z.stream.data_type
437
+ end
438
+
439
+ def adler
440
+ @z.stream.adler
441
+ end
442
+
443
+ def finished?
444
+ @z.ZSTREAM_IS_FINISHED()
445
+ end
446
+ alias stream_end? :finished?
447
+
448
+ def closed?
449
+ @z.ZSTREAM_IS_READY()
450
+ end
451
+ alias ended? :closed?
452
+
453
+ def close()
454
+ if (!@z.ZSTREAM_IS_READY())
455
+ warn("attempt to close uninitialized zstream ignored.")
456
+ return nil
457
+ end
458
+ if (@z.flags & ZSTREAM_FLAG_IN_STREAM).nonzero?
459
+ warn("attempt to close unfinished zstream reset forced.")
460
+ @z.input = nil
461
+ end
462
+
463
+ @z.input = nil
464
+ err = send(@z.func.end,@z.stream)
465
+ if (err != Z_OK)
466
+ raise_zlib_error(err, @z.stream.msg)
467
+ end
468
+ @z.flags = 0
469
+ end
470
+ alias end :close
471
+
472
+ def reset()
473
+ err = send(@z.func.reset,@z.stream)
474
+ if err != Z_OK
475
+ raise_zlib_error(err, @z.stream.msg)
476
+ end
477
+ @z.flags = ZSTREAM_FLAG_READY
478
+ @z.buf = nil
479
+ @z.stream.next_out = 0
480
+ @z.stream.avail_out = 0
481
+ @z.input = nil
482
+ end
483
+
484
+ def finish()
485
+ @z.zstream_run("", 0, Z_FINISH)
486
+ @z.zstream_detach_buffer()
487
+ end
488
+
489
+ def flush_next_in
490
+ @z.zstream_detach_input
491
+ end
492
+
493
+ def flush_next_out
494
+ @z.zstream_detach_buffer
495
+ end
496
+
497
+ def initialize
498
+ @z = nil
499
+ ObjectSpace.define_finalizer self, @@final.call(@z)
500
+ end
501
+
502
+ end
503
+
504
+ class Deflate < ZStream
505
+
506
+ def self.deflate_run(src)
507
+ @z.zstream_run(src,src.length,Z_FINISH)
508
+ return @z.zstream_detach_buffer()
509
+ end
510
+
511
+ def self.deflate(src,level=Z_DEFAULT_COMPRESSION)
512
+ @z = ZStream.new
513
+ @z.zstream_init(DeflateFuncs)
514
+ err = deflateInit(@z.stream, level)
515
+ if (err != Z_OK)
516
+ raise_zlib_error(err, @z.stream.msg)
517
+ end
518
+ @z.ZSTREAM_READY()
519
+
520
+ begin
521
+ dst = deflate_run(src)
522
+ ensure
523
+ @z.zstream_end()
524
+ end
525
+ dst
526
+ end
527
+
528
+ def initialize(level=Z_DEFAULT_COMPRESSION,wbits=MAX_WBITS,memlevel=DEF_MEM_LEVEL,strategy=Z_DEFAULT_STRATEGY)
529
+ @z = ZStream.new
530
+ @z.zstream_init(DeflateFuncs)
531
+ err = deflateInit2(@z.stream,level,Z_DEFLATED,wbits,memlevel,strategy)
532
+ if (err != Z_OK)
533
+ raise_zlib_error(err, @z.stream.msg)
534
+ end
535
+ @z.ZSTREAM_READY()
536
+ end
537
+
538
+ def initialize_copy(orig)
539
+ z1 = @z
540
+ z2 = orig.z
541
+ err = deflateCopy(z1.stream, z2.stream)
542
+ if (err != Z_OK)
543
+ raise_zlib_error(err, 0)
544
+ end
545
+ z1.flags = z2.flags
546
+ end
547
+
548
+ def do_deflate(src,flush)
549
+ if src.nil?
550
+ @z.zstream_run('',0,Z_FINISH)
551
+ return
552
+ end
553
+ if (flush != Z_NO_FLUSH || (src && src.length>0))
554
+ @z.zstream_run(src,src.length,flush)
555
+ end
556
+ end
557
+ private :do_deflate
558
+
559
+ def deflate(src,flush=Z_NO_FLUSH)
560
+ do_deflate(src,flush)
561
+ @z.zstream_detach_buffer
562
+ end
563
+
564
+ def <<(src)
565
+ do_deflate(src,Z_NO_FLUSH)
566
+ self
567
+ end
568
+
569
+ def flush(v_flush)
570
+ if(v_flush != Z_NO_FLUSH)
571
+ @z.zstream_run("", 0, flush)
572
+ end
573
+ @z.zstream_detach_buffer()
574
+ end
575
+
576
+ def params(level=Z_DEFAULT_COMPRESSION,strategy=Z_DEFAULT_STRATEGY)
577
+ err = deflateParams(@z.stream, level, strategy)
578
+ while (err == Z_BUF_ERROR)
579
+ warn("deflateParams() returned Z_BUF_ERROR")
580
+ @z.zstream_expand_buffer()
581
+ err = deflateParams(@z.stream, level, strategy)
582
+ end
583
+ if (err != Z_OK)
584
+ raise_zlib_error(err, @z.stream.msg)
585
+ end
586
+
587
+ nil
588
+ end
589
+
590
+ def set_dictionary(dic)
591
+ err = deflateSetDictionary(@z.stream,dic,dic.length)
592
+ if (err != Z_OK)
593
+ raise_zlib_error(err, @z.stream.msg)
594
+ end
595
+ end
596
+
597
+ end
598
+
599
+ class Inflate < ZStream
600
+
601
+ def self.inflate_run(src)
602
+ @z.zstream_run(src,src.length,Z_SYNC_FLUSH)
603
+ @z.zstream_run('',0,Z_FINISH)
604
+ @z.zstream_detach_buffer()
605
+ end
606
+
607
+ def self.inflate(src)
608
+ @z = ZStream.new
609
+ @z.zstream_init(InflateFuncs)
610
+ err = inflateInit(@z.stream)
611
+ if (err != Z_OK)
612
+ raise_zlib_error(err, @z.stream.msg)
613
+ end
614
+ @z.ZSTREAM_READY()
615
+ begin
616
+ dst = inflate_run(src)
617
+ ensure
618
+ @z.zstream_end
619
+ end
620
+ dst
621
+ end
622
+
623
+ def do_inflate(src)
624
+ if(src.nil?)
625
+ @z.zstream_run("", 0, Z_FINISH)
626
+ return
627
+ end
628
+ if (src.length>0)
629
+ @z.zstream_run(src,src.length,Z_SYNC_FLUSH)
630
+ end
631
+ end
632
+ private :do_inflate
633
+
634
+ def initialize(wbits=MAX_WBITS)
635
+ @z = ZStream.new
636
+ @z.zstream_init(InflateFuncs)
637
+ err = inflateInit2(@z.stream, wbits)
638
+ if (err != Z_OK)
639
+ raise_zlib_error(err, @z.stream.msg)
640
+ end
641
+ @z.ZSTREAM_READY()
642
+ end
643
+
644
+ def inflate(src)
645
+ if (@z.ZSTREAM_IS_FINISHED())
646
+ if src.nil?
647
+ dst = @z.zstream_detach_buffer()
648
+ else
649
+ @z.zstream_append_buffer(src,src.lenth)
650
+ dst = ''
651
+ end
652
+ else
653
+ do_inflate(src)
654
+ dst = @z.zstream_detach_buffer()
655
+ if (@z.ZSTREAM_IS_FINISHED())
656
+ @z.zstream_passthrough_input()
657
+ end
658
+ end
659
+ if block_given?
660
+ yield dst
661
+ else
662
+ dst
663
+ end
664
+ end
665
+
666
+ def <<(src)
667
+ if @z.ZSTREAM_IS_FINISHED()
668
+ if src
669
+ @z.zstream_append_buffer(src,src.length)
670
+ end
671
+ else
672
+ do_inflate(src)
673
+ if @z.ZSTREAM_IS_FINISHED()
674
+ @z.zstream_passthrough_input()
675
+ end
676
+ end
677
+ self
678
+ end
679
+
680
+ def sync
681
+ raise GzipFile::Error,"closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
682
+ return @z.zstream_sync(src,src.length)
683
+ end
684
+
685
+ def sync_point?()
686
+ err = inflateSyncPoint(@z.stream)
687
+ return true if err == 1
688
+
689
+ if err != Z_OK
690
+ raise_zlib_error(err, @z.stream.msg)
691
+ end
692
+
693
+ false
694
+ end
695
+
696
+ def set_dictionary(dic)
697
+ src = dic
698
+ err = inflateSetDictionary(@z.stream,src,src.length)
699
+
700
+ if err != Z_OK
701
+ raise_zlib_error(err, @z.stream.msg)
702
+ end
703
+
704
+ dic
705
+ end
706
+
707
+ end
708
+
709
+ class GzipFile
710
+ GZ_MAGIC1 = 0x1f
711
+ GZ_MAGIC2 = 0x8b
712
+ GZ_METHOD_DEFLATE = 8
713
+ GZ_FLAG_MULTIPART = 0x2
714
+ GZ_FLAG_EXTRA = 0x4
715
+ GZ_FLAG_ORIG_NAME = 0x8
716
+ GZ_FLAG_COMMENT = 0x10
717
+ GZ_FLAG_ENCRYPT = 0x20
718
+ GZ_FLAG_UNKNOWN_MASK = 0xc0
719
+
720
+ GZ_EXTRAFLAG_FAST = 0x4
721
+ GZ_EXTRAFLAG_SLOW = 0x2
722
+
723
+ OS_CODE = OS_UNIX
724
+
725
+ GZFILE_FLAG_SYNC = ZSTREAM_FLAG_UNUSED
726
+ GZFILE_FLAG_HEADER_FINISHED = (ZSTREAM_FLAG_UNUSED << 1)
727
+ GZFILE_FLAG_FOOTER_FINISHED = (ZSTREAM_FLAG_UNUSED << 2)
728
+
729
+ def GZFILE_IS_FINISHED(gz)
730
+ gz.z.ZSTREAM_IS_FINISHED() && (gz.z.buf.nil? || gz.z.buf.offset.zero?)
731
+ end
732
+
733
+ GZFILE_READ_SIZE = 2048
734
+
735
+ class Error < Zlib::Error
736
+ end
737
+
738
+ class NoFooter < Error
739
+ end
740
+
741
+ class CRCError < Error
742
+ end
743
+
744
+ class LengthError < Error
745
+ end
746
+
747
+ Gzfile = Struct.new(:z,:io,:level,:mtime,:os_code,:orig_name,:comment,:crc,:lineno,:ungetc,:end)
748
+
749
+ def gzfile_close(closeflag)
750
+ io = @gz.io
751
+ send(@gz.end)
752
+
753
+ @gz.io = nil
754
+ @gz.orig_name = nil
755
+ @gz.comment = nil
756
+
757
+ if closeflag && defined?(io.close)
758
+ io.close
759
+ end
760
+ end
761
+
762
+ def gzfile_ensure_close()
763
+ if @gz.z.ZSTREAM_IS_READY()
764
+ gzfile_close(true)
765
+ end
766
+ nil
767
+ end
768
+
769
+ def self.wrap(io, level=Z_DEFAULT_COMPRESSION, strategy=Z_DEFAULT_STRATEGY)
770
+ obj = new(io,level,strategy)
771
+ if block_given?
772
+ begin
773
+ yield(obj)
774
+ ensure
775
+ obj.gzfile_ensure_close()
776
+ end
777
+ else
778
+ return obj
779
+ end
780
+ end
781
+
782
+ def to_io
783
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
784
+ @gz.io
785
+ end
786
+
787
+ def crc
788
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
789
+ @gz.crc
790
+ end
791
+
792
+ def mtime
793
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
794
+ Time.at(@gz.mtime)
795
+ end
796
+
797
+ def level
798
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
799
+ @gz.level
800
+ end
801
+
802
+ def os_code
803
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
804
+ @gz.os_code
805
+ end
806
+
807
+ def orig_name
808
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
809
+ @gz.orig_name ? @gz.orig_name.dup : nil
810
+ end
811
+
812
+ def comment
813
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
814
+ @gz.comment ? @gz.comment.dup : nil
815
+ end
816
+
817
+ def close
818
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
819
+ gzfile_close(true)
820
+ @gz.io
821
+ end
822
+
823
+ def finish
824
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
825
+ gzfile_close(false)
826
+ @gz.io
827
+ end
828
+
829
+ def closed?
830
+ @gz.io.nil?
831
+ end
832
+
833
+ def sync
834
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
835
+ !(@gz.z.flags & GZFILE_FLAG_SYNC).zero?
836
+ end
837
+
838
+ def sync=(mode)
839
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
840
+ if(mode)
841
+ @gz.z.flags |= GZFILE_FLAG_SYNC
842
+ else
843
+ @gz.z.flags &= ~GZFILE_FLAG_SYNC
844
+ end
845
+ mode
846
+ end
847
+
848
+ def self.gzfile_s_open(filename,mode,level,strategy,&blk)
849
+ io = File.open(filename,mode)
850
+ self.wrap(io,level,strategy,&blk)
851
+ end
852
+
853
+ private
854
+
855
+ def gzfile_new(funcs,endfunc)
856
+ @gz = Gzfile.new
857
+ @gz.z = ZStream.new
858
+ @gz.z.zstream_init(funcs)
859
+ @gz.io = nil
860
+ @gz.level = 0
861
+ @gz.mtime = 0
862
+ @gz.os_code = OS_CODE
863
+ @gz.orig_name = nil
864
+ @gz.comment = nil
865
+ @gz.crc = crc32(0,nil,0)
866
+ @gz.lineno = 0
867
+ @gz.ungetc = 0
868
+ @gz.end = endfunc
869
+ self
870
+ end
871
+
872
+ def gzfile_reset()
873
+ @gz.z.zstream_reset
874
+ @gz.crc = crc32(0,nil,0)
875
+ @gz.lineno = 0
876
+ @gz.ungetc = 0
877
+ end
878
+
879
+ def gzfile_get16(src)
880
+ src.unpack('S').first
881
+ end
882
+
883
+ def gzfile_get32(src)
884
+ src.unpack('L').first
885
+ end
886
+
887
+ def gzfile_set32(n)
888
+ [n].pack('L')
889
+ end
890
+
891
+ def gzfile_make_header
892
+ buf = 0.chr * 10
893
+ flags = 0
894
+ extraflags = 0
895
+ if @gz.orig_name
896
+ flags |= GZ_FLAG_ORIG_NAME
897
+ end
898
+ if @gz.comment
899
+ flags |= GZ_FLAG_COMMENT
900
+ end
901
+ if @gz.mtime.zero?
902
+ @gz.mtime = Time.now.to_i
903
+ end
904
+ if (@gz.level == Z_BEST_SPEED)
905
+ extraflags |= GZ_EXTRAFLAG_FAST
906
+ elsif (@gz.level == Z_BEST_COMPRESSION)
907
+ extraflags |= GZ_EXTRAFLAG_SLOW
908
+ end
909
+ buf[0] = GZ_MAGIC1.chr
910
+ buf[1] = GZ_MAGIC2.chr
911
+ buf[2] = GZ_METHOD_DEFLATE.chr
912
+ buf[3] = flags.chr
913
+ buf[4,4] = gzfile_set32(@gz.mtime)
914
+ buf[8] = extraflags.chr
915
+ buf[9] = @gz.os_code.chr
916
+ @gz.z.zstream_append_buffer(buf,buf.length)
917
+
918
+ if @gz.orig_name
919
+ @gz.z.zstream_append_buffer(@gz.orig_name,@gz.orig_name.length)
920
+ @gz.z.zstream_append_buffer("\0", 1)
921
+ end
922
+ if @gz.comment
923
+ @gz.z.zstream_append_buffer(@gz.comment,@gz.comment.length)
924
+ @gz.z.zstream_append_buffer("\0", 1)
925
+ end
926
+
927
+ @gz.z.flags |= GZFILE_FLAG_HEADER_FINISHED
928
+ end
929
+
930
+ def gzfile_make_footer()
931
+ buf = 0.chr * 8
932
+ buf[0,4] = gzfile_set32(@gz.crc)
933
+ buf[4,4] = gzfile_set32(@gz.z.stream.total_in)
934
+ @gz.z.zstream_append_buffer(buf, buf.length)
935
+ @gz.z.flags |= GZFILE_FLAG_FOOTER_FINISHED
936
+ end
937
+
938
+ def gzfile_read_header()
939
+ if !gzfile_read_raw_ensure(10)
940
+ raise GzipFile::Error, "not in gzip format"
941
+ end
942
+
943
+ head = @gz.z.input
944
+
945
+ if (head[0].ord != GZ_MAGIC1 || head[1].ord != GZ_MAGIC2)
946
+ raise GzipFile::Error, "not in gzip format"
947
+ end
948
+ if (head[2].ord != GZ_METHOD_DEFLATE)
949
+ raise GzipFile::Error, "unsupported compression method #{head[2].ord}"
950
+ end
951
+
952
+ flags = head[3].ord
953
+ if (flags & GZ_FLAG_MULTIPART).nonzero?
954
+ raise GzipFile::Error, "multi-part gzip file is not supported"
955
+ elsif (flags & GZ_FLAG_ENCRYPT).nonzero?
956
+ raise GzipFile::Error, "encrypted gzip file is not supported"
957
+ elsif (flags & GZ_FLAG_UNKNOWN_MASK).nonzero?
958
+ raise GzipFile::Error, "unknown flags 0x%02x" % flags
959
+ end
960
+
961
+ if (head[8].ord & GZ_EXTRAFLAG_FAST).nonzero?
962
+ @gz.level = Z_BEST_SPEED
963
+ elsif (head[8].ord & GZ_EXTRAFLAG_SLOW).nonzero?
964
+ @gz.level = Z_BEST_COMPRESSION
965
+ else
966
+ @gz.level = Z_DEFAULT_COMPRESSION
967
+ end
968
+
969
+ @gz.mtime = gzfile_get32(head[4,4])
970
+ @gz.os_code = head[9].ord
971
+ @gz.z.zstream_discard_input(10)
972
+
973
+ if (flags & GZ_FLAG_EXTRA).nonzero?
974
+ if !gzfile_read_raw_ensure(2)
975
+ raise GzipFile::Error, "unexpected end of file"
976
+ end
977
+ len = gzfile_get16(@gz.z.input)
978
+ if !gzfile_read_raw_ensure(2 + len)
979
+ raise GzipFile::Error, "unexpected end of file"
980
+ end
981
+ @gz.z.zstream_discard_input(2 + len)
982
+ end
983
+ if (flags & GZ_FLAG_ORIG_NAME).nonzero?
984
+ ap = gzfile_read_raw_until_zero(0)
985
+ len = ap
986
+ @gz.orig_name = @gz.z.input[0,len]
987
+ @gz.z.zstream_discard_input(len + 1)
988
+ end
989
+ if (flags & GZ_FLAG_COMMENT).nonzero?
990
+ ap = gzfile_read_raw_until_zero(0)
991
+ len = ap
992
+ @gz.comment = @gz.z.input[0,len]
993
+ @gz.z.zstream_discard_input(len + 1)
994
+ end
995
+
996
+ if (@gz.z.input && @gz.z.input.length > 0)
997
+ @gz.z.zstream_run(0, 0, Z_SYNC_FLUSH)
998
+ end
999
+ end
1000
+
1001
+ def gzfile_check_footer()
1002
+ @gz.z.flags |= GZFILE_FLAG_FOOTER_FINISHED
1003
+
1004
+ if (!gzfile_read_raw_ensure(8))
1005
+ raise NoFooter, "footer is not found"
1006
+ end
1007
+ crc = gzfile_get32(@gz.z.input)
1008
+ length = gzfile_get32(@gz.z.input[4,4])
1009
+ @gz.z.stream.total_in += 8
1010
+ @gz.z.zstream_discard_input(8)
1011
+ if (@gz.crc != crc)
1012
+ raise CRCError, "invalid compressed data -- crc error"
1013
+ end
1014
+ if (@gz.z.stream.total_out != length)
1015
+ raise LengthError, "invalid compressed data -- length error"
1016
+ end
1017
+ end
1018
+
1019
+ def gzfile_calc_crc(str)
1020
+ if (str.length <= @gz.ungetc)
1021
+ @gz.ungetc -= str.length
1022
+ else
1023
+ @gz.crc = crc32(@gz.crc, str[@gz.ungetc,str.length - @gz.ungetc],
1024
+ str.length - @gz.ungetc)
1025
+ @gz.ungetc = 0
1026
+ end
1027
+ end
1028
+
1029
+ end
1030
+
1031
+ class GzipWriter < GzipFile
1032
+
1033
+ def mtime=(mtime)
1034
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1035
+
1036
+ if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).nonzero?
1037
+ raise GzipFile::Error,"header is already written"
1038
+ end
1039
+
1040
+ @gz.mtime = mtime.to_i
1041
+ end
1042
+
1043
+ def orig_name=(str)
1044
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1045
+
1046
+ if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).nonzero?
1047
+ raise GzipFile::Error,"header is already written"
1048
+ end
1049
+
1050
+ ap = str[0.chr]
1051
+ @gz.orig_name = ap ? str[0,ap] : str.dup
1052
+ end
1053
+
1054
+ def comment=(str)
1055
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1056
+
1057
+ if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).nonzero?
1058
+ raise GzipFile::Error,"header is already written"
1059
+ end
1060
+
1061
+ @gz.comment = str.dup
1062
+ end
1063
+
1064
+ def pos
1065
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1066
+ @gz.z.stream.total_in
1067
+ end
1068
+
1069
+ alias tell :pos
1070
+
1071
+ def self.open(filename, level=Z_DEFAULT_COMPRESSION, strategy=Z_DEFAULT_STRATEGY, &blk)
1072
+ GzipWriter.gzfile_s_open(filename, 'wb', level, strategy, &blk)
1073
+ end
1074
+
1075
+ def initialize(io, level=nil, strategy=nil)
1076
+ level = Z_DEFAULT_COMPRESSION if level.nil?
1077
+ strategy = Z_DEFAULT_STRATEGY if strategy.nil?
1078
+
1079
+ gzfile_new(DeflateFuncs, :gzfile_writer_end)
1080
+ @gz.level = level
1081
+
1082
+ err = deflateInit2(
1083
+ @gz.z.stream,
1084
+ @gz.level,
1085
+ Z_DEFLATED,
1086
+ -MAX_WBITS,
1087
+ DEF_MEM_LEVEL,
1088
+ strategy
1089
+ )
1090
+
1091
+ if err != Z_OK
1092
+ raise_zlib_error(err, @gz.stream.msg)
1093
+ end
1094
+
1095
+ @gz.io = io
1096
+ @gz.z.ZSTREAM_READY()
1097
+ end
1098
+
1099
+ def flush(v_flush=Z_SYNC_FLUSH)
1100
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1101
+
1102
+ if v_flush != Z_NO_FLUSH
1103
+ @gz.z.zstream_run("", 0, v_flush)
1104
+ end
1105
+
1106
+ gzfile_write_raw()
1107
+
1108
+ if defined?(@gz.io.flush)
1109
+ @gz.io.flush()
1110
+ end
1111
+
1112
+ self
1113
+ end
1114
+
1115
+ def write(str)
1116
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1117
+ str = str.to_s
1118
+ gzfile_write(str, str.length)
1119
+ str.length
1120
+ end
1121
+
1122
+ def putc(ch)
1123
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1124
+ gzfile_write(ch.chr, 1)
1125
+ ch
1126
+ end
1127
+
1128
+ def <<(str)
1129
+ @gz.io << str
1130
+ end
1131
+
1132
+ def printf(*arg)
1133
+ @gz.io.printf(*arg)
1134
+ end
1135
+
1136
+ def print(*arg)
1137
+ @gz.io.print(*arg)
1138
+ end
1139
+
1140
+ def puts(str)
1141
+ @gz.io.puts(str)
1142
+ end
1143
+
1144
+ def gzfile_write_raw
1145
+ if (@gz.z.buf.offset > 0)
1146
+ str = @gz.z.zstream_detach_buffer()
1147
+ @gz.io.write(str)
1148
+ if ((@gz.z.flags & GZFILE_FLAG_SYNC).nonzero? && defined?(@gz.io.flush))
1149
+ @gz.io.flush()
1150
+ end
1151
+ end
1152
+ end
1153
+
1154
+ private :gzfile_write_raw
1155
+
1156
+ def gzfile_write(str,len)
1157
+ if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).zero?
1158
+ gzfile_make_header()
1159
+ end
1160
+
1161
+ if (len > 0 || (@gz.z.flags & GZFILE_FLAG_SYNC))
1162
+ @gz.crc = crc32(@gz.crc, str, len)
1163
+ @gz.z.zstream_run(str, len, (@gz.z.flags & GZFILE_FLAG_SYNC).nonzero? ?
1164
+ Z_SYNC_FLUSH : Z_NO_FLUSH)
1165
+ end
1166
+ gzfile_write_raw()
1167
+ end
1168
+
1169
+ private :gzfile_write
1170
+
1171
+ def gzfile_writer_end_run
1172
+ if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).zero?
1173
+ gzfile_make_header()
1174
+ end
1175
+ @gz.z.zstream_run("", 0, Z_FINISH)
1176
+ gzfile_make_footer()
1177
+ gzfile_write_raw()
1178
+
1179
+ return nil
1180
+ end
1181
+
1182
+ def gzfile_writer_end
1183
+ return if @gz.z.ZSTREAM_IS_CLOSING()
1184
+ @gz.z.flags |= ZSTREAM_FLAG_CLOSING
1185
+ begin
1186
+ gzfile_writer_end_run()
1187
+ ensure
1188
+ @gz.z.zstream_end()
1189
+ end
1190
+ end
1191
+ end
1192
+
1193
+ class GzipReader < GzipFile
1194
+ include Enumerable
1195
+
1196
+ def lineno
1197
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1198
+ @gz.lineno
1199
+ end
1200
+
1201
+ def lineno=(lineno)
1202
+ raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1203
+ @gz.lineno = lineno
1204
+ end
1205
+
1206
+ def eof
1207
+ raise GzipFile::Error,"closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1208
+ GZFILE_IS_FINISHED(@gz)
1209
+ end
1210
+ alias eof? :eof
1211
+
1212
+ def pos
1213
+ if @gz.z.buf.nil?
1214
+ @gz.z.stream.total_out
1215
+ else
1216
+ @gz.z.stream.total_out - @gz.z.buf.offset
1217
+ end
1218
+ end
1219
+ alias tell :pos
1220
+
1221
+ def self.open(filename,level=Z_DEFAULT_COMPRESSION,strategy=Z_DEFAULT_STRATEGY,&blk)
1222
+ GzipReader.gzfile_s_open(filename,"rb",level=Z_DEFAULT_COMPRESSION,strategy=Z_DEFAULT_STRATEGY,&blk)
1223
+ end
1224
+
1225
+ def initialize(io,level=Z_DEFAULT_COMPRESSION,strategy=Z_DEFAULT_STRATEGY)
1226
+ gzfile_new(InflateFuncs, :gzfile_reader_end)
1227
+ @gz.level = level
1228
+ err = inflateInit2(@gz.z.stream, -MAX_WBITS)
1229
+ if (err != Z_OK)
1230
+ raise_zlib_error(err, @gz.stream.msg)
1231
+ end
1232
+ @gz.io = io
1233
+ @gz.z.ZSTREAM_READY()
1234
+ gzfile_read_header()
1235
+ self
1236
+ end
1237
+
1238
+ def rewind()
1239
+ gzfile_reader_rewind()
1240
+ return 0
1241
+ end
1242
+
1243
+ def unused()
1244
+ gzfile_reader_get_unused()
1245
+ end
1246
+
1247
+ def read(len=nil)
1248
+ if len.nil?
1249
+ return gzfile_read_all()
1250
+ end
1251
+
1252
+ if len < 0
1253
+ raise ArgumentError, "negative length #{len} given"
1254
+ end
1255
+
1256
+ return gzfile_read(len)
1257
+ end
1258
+
1259
+ def getc()
1260
+ dst = gzfile_read(1)
1261
+ dst ? dst[0] : dst
1262
+ end
1263
+
1264
+ def readchar()
1265
+ dst = getc()
1266
+ if dst.nil?
1267
+ raise EOFError, "end of file reached"
1268
+ end
1269
+ dst
1270
+ end
1271
+
1272
+ def each_byte()
1273
+ while (c = getc)
1274
+ yield(c)
1275
+ end
1276
+ nil
1277
+ end
1278
+
1279
+ def ungetc(ch)
1280
+ gzfile_ungetc(ch)
1281
+ nil
1282
+ end
1283
+
1284
+ def gets(rs=$/)
1285
+ dst = gzreader_gets(rs)
1286
+ $_ = dst if dst
1287
+ dst
1288
+ end
1289
+
1290
+ def readline(rs=$/)
1291
+ gets(rs)
1292
+ end
1293
+
1294
+ def each(rs=$/)
1295
+ while (str = gzreader_gets(rs))
1296
+ yield(str)
1297
+ end
1298
+ self
1299
+ end
1300
+ alias each_line :each
1301
+
1302
+ def readlines(rs=$/)
1303
+ dst = []
1304
+ while str = gzreader_gets(rs)
1305
+ dst.push(str)
1306
+ end
1307
+ dst
1308
+ end
1309
+
1310
+ private
1311
+
1312
+ def gzfile_reader_end_run()
1313
+ if (GZFILE_IS_FINISHED(@gz) && (@gz.z.flags &
1314
+ GZFILE_FLAG_FOOTER_FINISHED).zero?)
1315
+ gzfile_check_footer()
1316
+ end
1317
+ nil
1318
+ end
1319
+
1320
+ def gzfile_reader_end()
1321
+ return if @gz.z.ZSTREAM_IS_CLOSING()
1322
+ @gz.z.flags |= ZSTREAM_FLAG_CLOSING
1323
+ begin
1324
+ gzfile_reader_end_run()
1325
+ ensure
1326
+ @gz.z.zstream_end()
1327
+ end
1328
+ end
1329
+
1330
+ def gzfile_ungetc(c)
1331
+ @gz.z.zstream_buffer_ungetc(c)
1332
+ @gz.ungetc+=1
1333
+ end
1334
+
1335
+ def gzfile_reader_rewind
1336
+ n = @gz.z.stream.total_in
1337
+ if @gz.z.input
1338
+ n += @gz.z.input.length
1339
+ end
1340
+ @gz.io.seek(-n,1)
1341
+ gzfile_reset()
1342
+ end
1343
+
1344
+ def gzfile_reader_get_unused()
1345
+ return nil if (!@gz.z.ZSTREAM_IS_READY())
1346
+ return nil if (!GZFILE_IS_FINISHED(@gz))
1347
+ if (@gz.z.flags & GZFILE_FLAG_FOOTER_FINISHED).zero?
1348
+ gzfile_check_footer()
1349
+ end
1350
+ return nil if @gz.z.input.nil?
1351
+ @gz.z.input.dup
1352
+ end
1353
+
1354
+ def rscheck(rsptr,rslen,rs)
1355
+ raise RuntimeError, "rs modified" if rs != rsptr
1356
+ end
1357
+
1358
+ def gzreader_gets(rs=$/)
1359
+ if rs && rs.class != String
1360
+ raise TypeError,"wrong argument type #{rs.class} (expected String)"
1361
+ end
1362
+ if rs.nil?
1363
+ dst = gzfile_read_all()
1364
+ @gz.lineno += 1 if dst.length.nonzero?
1365
+ return dst
1366
+ end
1367
+ if rs.length.zero?
1368
+ rsptr = "\n\n"
1369
+ rslen = 2
1370
+ rspara = true
1371
+ else
1372
+ rsptr = rs
1373
+ rslen = rs.length
1374
+ rspara = false
1375
+ end
1376
+ if rspara
1377
+ gzreader_skip_linebreaks
1378
+ end
1379
+ while (@gz.z.buf.offset < rslen)
1380
+ if (@gz.z.ZSTREAM_IS_FINISHED())
1381
+ @gz.lineno+=1 if (@gz.z.buf.offset > 0)
1382
+ return gzfile_read(rslen)
1383
+ end
1384
+ gzfile_read_more()
1385
+ end
1386
+
1387
+ ap = 0
1388
+ n = rslen
1389
+ loop do
1390
+ if (n > @gz.z.buf.offset)
1391
+ break if (@gz.z.ZSTREAM_IS_FINISHED())
1392
+ gzfile_read_more()
1393
+ ap = n - rslen
1394
+ end
1395
+
1396
+ rscheck(rsptr, rslen, rs) if (!rspara)
1397
+ res = @gz.z.buf.buffer[ap,@gz.z.buf.offset - n + 1].index(rsptr[0])
1398
+
1399
+ if res.nil?
1400
+ n = @gz.z.buf.offset + 1
1401
+ else
1402
+ n += (res - ap)
1403
+ ap = res
1404
+ break if (rslen == 1 || @gz.z.buf.buffer[ap,rslen]==rsptr)
1405
+ ap+=1
1406
+ n+=1
1407
+ end
1408
+ end
1409
+
1410
+ @gz.lineno+=1
1411
+ dst = gzfile_read(n)
1412
+ if (rspara)
1413
+ gzreader_skip_linebreaks()
1414
+ end
1415
+ dst
1416
+ end
1417
+
1418
+ def gzfile_read(len)
1419
+ if len < 0
1420
+ raise ArgumentError, "negative length #{len} given"
1421
+ end
1422
+
1423
+ if len.zero?
1424
+ return ""
1425
+ end
1426
+
1427
+ while (!@gz.z.ZSTREAM_IS_FINISHED() && @gz.z.buf.offset < len)
1428
+ gzfile_read_more()
1429
+ end
1430
+
1431
+ if (GZFILE_IS_FINISHED(@gz))
1432
+ if (@gz.z.flags & GZFILE_FLAG_FOOTER_FINISHED).zero?
1433
+ gzfile_check_footer()
1434
+ end
1435
+ return nil
1436
+ end
1437
+
1438
+ dst = @gz.z.zstream_shift_buffer(len)
1439
+ gzfile_calc_crc(dst)
1440
+ dst
1441
+ end
1442
+
1443
+ def gzfile_read_all()
1444
+ while (!@gz.z.ZSTREAM_IS_FINISHED())
1445
+ gzfile_read_more()
1446
+ end
1447
+ if (GZFILE_IS_FINISHED(@gz))
1448
+ if (@gz.z.flags & GZFILE_FLAG_FOOTER_FINISHED).zero?
1449
+ gzfile_check_footer()
1450
+ end
1451
+ return ''
1452
+ end
1453
+
1454
+ dst = @gz.z.zstream_detach_buffer()
1455
+ gzfile_calc_crc(dst)
1456
+ dst
1457
+ end
1458
+
1459
+ def gzfile_read_raw()
1460
+ str = @gz.io.read(GZFILE_READ_SIZE)
1461
+ if str && str.class != String
1462
+ raise TypeError,"wrong argument type #{rs.class} (expected String)"
1463
+ end
1464
+ str
1465
+ end
1466
+
1467
+ def gzfile_read_raw_ensure(size)
1468
+ while @gz.z.input.nil? || @gz.z.input.length < size
1469
+ str = gzfile_read_raw()
1470
+ return false if str.nil?
1471
+ @gz.z.zstream_append_input(str,str.length)
1472
+ end
1473
+ true
1474
+ end
1475
+
1476
+ def gzfile_read_raw_until_zero(offset)
1477
+ ap = nil
1478
+
1479
+ loop do
1480
+ ap = @gz.z.input[offset, @gz.z.input.length-offset].index(0.chr)
1481
+ break if ap
1482
+ str = gzfile_read_raw()
1483
+
1484
+ raise Error, "unexpected end of file" if str.nil?
1485
+
1486
+ offset = @gz.z.input.length
1487
+ @gz.z.zstream_append_input(str,str.length)
1488
+ end
1489
+
1490
+ ap
1491
+ end
1492
+
1493
+ def gzfile_read_more
1494
+ while (!@gz.z.ZSTREAM_IS_FINISHED())
1495
+ str = gzfile_read_raw()
1496
+ if str.nil?
1497
+ if (!@gz.z.ZSTREAM_IS_FINISHED())
1498
+ raise Error, "unexpected end of file"
1499
+ end
1500
+ break
1501
+ end
1502
+ if (str.length > 0)
1503
+ @gz.z.zstream_run(str, str.length,Z_SYNC_FLUSH)
1504
+ end
1505
+ break if (@gz.z.buf.offset > 0)
1506
+ end
1507
+ @gz.z.buf.offset
1508
+ end
1509
+ end
1510
+
1511
+ module_function
1512
+
1513
+ def zlib_version
1514
+ zlibVersion()
1515
+ end
1516
+
1517
+ def adler32(string=nil, adler=nil)
1518
+ if adler
1519
+ check_long_range adler
1520
+ sum = adler
1521
+ elsif string.nil?
1522
+ sum = 0
1523
+ else
1524
+ sum = Rbzlib.adler32(0,nil)
1525
+ end
1526
+
1527
+ if string.nil?
1528
+ sum = Rbzlib.adler32(sum,nil)
1529
+ else
1530
+ sum = Rbzlib.adler32(sum,string,string.length)
1531
+ end
1532
+ sum
1533
+ end
1534
+
1535
+ def crc32(string=nil, crc=nil)
1536
+ if crc
1537
+ check_long_range crc
1538
+ sum = crc
1539
+ elsif string.nil?
1540
+ sum = 0
1541
+ else
1542
+ sum = Rbzlib.crc32(0,nil)
1543
+ end
1544
+
1545
+ if string.nil?
1546
+ sum = Rbzlib.crc32(sum,nil)
1547
+ else
1548
+ sum = Rbzlib.crc32(sum,string,string.length)
1549
+ end
1550
+ sum
1551
+ end
1552
+
1553
+ def crc_table
1554
+ get_crc_table
1555
+ end
1556
+
1557
+ private
1558
+
1559
+ LONG_MAX = 2**64 - 1
1560
+ LONG_MIN = -2**63
1561
+
1562
+ def self.check_long_range(num)
1563
+ # the error says 'unsigned', but this seems to be the range actually accepted
1564
+ raise RangeError, 'bignum too big to convert into `unsigned long\'' if num < LONG_MIN || num > LONG_MAX
1565
+ end
1566
+
1567
+ end