pr-zlib 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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