pr-zlib 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,1550 +1,1554 @@
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.1'
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
- dst
660
- end
661
-
662
- def <<(src)
663
- if @z.ZSTREAM_IS_FINISHED()
664
- if src
665
- @z.zstream_append_buffer(src,src.length)
666
- end
667
- else
668
- do_inflate(src)
669
- if @z.ZSTREAM_IS_FINISHED()
670
- @z.zstream_passthrough_input()
671
- end
672
- end
673
- self
674
- end
675
-
676
- def sync
677
- raise GzipFile::Error,"closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
678
- return @z.zstream_sync(src,src.length)
679
- end
680
-
681
- def sync_point?()
682
- err = inflateSyncPoint(@z.stream)
683
- return true if err == 1
684
-
685
- if err != Z_OK
686
- raise_zlib_error(err, @z.stream.msg)
687
- end
688
-
689
- false
690
- end
691
-
692
- def set_dictionary(dic)
693
- src = dic
694
- err = inflateSetDictionary(@z.stream,src,src.length)
695
-
696
- if err != Z_OK
697
- raise_zlib_error(err, @z.stream.msg)
698
- end
699
-
700
- dic
701
- end
702
-
703
- end
704
-
705
- class GzipFile
706
- GZ_MAGIC1 = 0x1f
707
- GZ_MAGIC2 = 0x8b
708
- GZ_METHOD_DEFLATE = 8
709
- GZ_FLAG_MULTIPART = 0x2
710
- GZ_FLAG_EXTRA = 0x4
711
- GZ_FLAG_ORIG_NAME = 0x8
712
- GZ_FLAG_COMMENT = 0x10
713
- GZ_FLAG_ENCRYPT = 0x20
714
- GZ_FLAG_UNKNOWN_MASK = 0xc0
715
-
716
- GZ_EXTRAFLAG_FAST = 0x4
717
- GZ_EXTRAFLAG_SLOW = 0x2
718
-
719
- OS_CODE = OS_UNIX
720
-
721
- GZFILE_FLAG_SYNC = ZSTREAM_FLAG_UNUSED
722
- GZFILE_FLAG_HEADER_FINISHED = (ZSTREAM_FLAG_UNUSED << 1)
723
- GZFILE_FLAG_FOOTER_FINISHED = (ZSTREAM_FLAG_UNUSED << 2)
724
-
725
- def GZFILE_IS_FINISHED(gz)
726
- gz.z.ZSTREAM_IS_FINISHED() && (gz.z.buf.nil? || gz.z.buf.offset.zero?)
727
- end
728
-
729
- GZFILE_READ_SIZE = 2048
730
-
731
- class Error < Zlib::Error
732
- end
733
-
734
- class NoFooter < Error
735
- end
736
-
737
- class CRCError < Error
738
- end
739
-
740
- class LengthError < Error
741
- end
742
-
743
- Gzfile = Struct.new(:z,:io,:level,:mtime,:os_code,:orig_name,:comment,:crc,:lineno,:ungetc,:end)
744
-
745
- def gzfile_close(closeflag)
746
- io = @gz.io
747
- send(@gz.end)
748
-
749
- @gz.io = nil
750
- @gz.orig_name = nil
751
- @gz.comment = nil
752
-
753
- if closeflag && defined?(io.close)
754
- io.close
755
- end
756
- end
757
-
758
- def gzfile_ensure_close()
759
- if @gz.z.ZSTREAM_IS_READY()
760
- gzfile_close(true)
761
- end
762
- nil
763
- end
764
-
765
- def self.wrap(io, level=Z_DEFAULT_COMPRESSION, strategy=Z_DEFAULT_STRATEGY)
766
- obj = new(io,level,strategy)
767
- if block_given?
768
- begin
769
- yield(obj)
770
- ensure
771
- obj.gzfile_ensure_close()
772
- end
773
- else
774
- return obj
775
- end
776
- end
777
-
778
- def to_io
779
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
780
- @gz.io
781
- end
782
-
783
- def crc
784
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
785
- @gz.crc
786
- end
787
-
788
- def mtime
789
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
790
- Time.at(@gz.mtime)
791
- end
792
-
793
- def level
794
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
795
- @gz.level
796
- end
797
-
798
- def os_code
799
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
800
- @gz.os_code
801
- end
802
-
803
- def orig_name
804
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
805
- @gz.orig_name ? @gz.orig_name.dup : nil
806
- end
807
-
808
- def comment
809
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
810
- @gz.comment ? @gz.comment.dup : nil
811
- end
812
-
813
- def close
814
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
815
- gzfile_close(true)
816
- @gz.io
817
- end
818
-
819
- def finish
820
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
821
- gzfile_close(false)
822
- @gz.io
823
- end
824
-
825
- def closed?
826
- @gz.io.nil?
827
- end
828
-
829
- def sync
830
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
831
- !(@gz.z.flags & GZFILE_FLAG_SYNC).zero?
832
- end
833
-
834
- def sync=(mode)
835
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
836
- if(mode)
837
- @gz.z.flags |= GZFILE_FLAG_SYNC
838
- else
839
- @gz.z.flags &= ~GZFILE_FLAG_SYNC
840
- end
841
- mode
842
- end
843
-
844
- def self.gzfile_s_open(filename,mode,level,strategy,&blk)
845
- io = File.open(filename,mode)
846
- self.wrap(io,level,strategy,&blk)
847
- end
848
-
849
- private
850
-
851
- def gzfile_new(funcs,endfunc)
852
- @gz = Gzfile.new
853
- @gz.z = ZStream.new
854
- @gz.z.zstream_init(funcs)
855
- @gz.io = nil
856
- @gz.level = 0
857
- @gz.mtime = 0
858
- @gz.os_code = OS_CODE
859
- @gz.orig_name = nil
860
- @gz.comment = nil
861
- @gz.crc = crc32(0,nil,0)
862
- @gz.lineno = 0
863
- @gz.ungetc = 0
864
- @gz.end = endfunc
865
- self
866
- end
867
-
868
- def gzfile_reset()
869
- @gz.z.zstream_reset
870
- @gz.crc = crc32(0,nil,0)
871
- @gz.lineno = 0
872
- @gz.ungetc = 0
873
- end
874
-
875
- def gzfile_get16(src)
876
- src.unpack('S').first
877
- end
878
-
879
- def gzfile_get32(src)
880
- src.unpack('L').first
881
- end
882
-
883
- def gzfile_set32(n)
884
- [n].pack('L')
885
- end
886
-
887
- def gzfile_make_header
888
- buf = 0.chr * 10
889
- flags = 0
890
- extraflags = 0
891
- if @gz.orig_name
892
- flags |= GZ_FLAG_ORIG_NAME
893
- end
894
- if @gz.comment
895
- flags |= GZ_FLAG_COMMENT
896
- end
897
- if @gz.mtime.zero?
898
- @gz.mtime = Time.now.to_i
899
- end
900
- if (@gz.level == Z_BEST_SPEED)
901
- extraflags |= GZ_EXTRAFLAG_FAST
902
- elsif (@gz.level == Z_BEST_COMPRESSION)
903
- extraflags |= GZ_EXTRAFLAG_SLOW
904
- end
905
- buf[0] = GZ_MAGIC1.chr
906
- buf[1] = GZ_MAGIC2.chr
907
- buf[2] = GZ_METHOD_DEFLATE.chr
908
- buf[3] = flags.chr
909
- buf[4,4] = gzfile_set32(@gz.mtime)
910
- buf[8] = extraflags.chr
911
- buf[9] = @gz.os_code.chr
912
- @gz.z.zstream_append_buffer(buf,buf.length)
913
-
914
- if @gz.orig_name
915
- @gz.z.zstream_append_buffer(@gz.orig_name,@gz.orig_name.length)
916
- @gz.z.zstream_append_buffer("\0", 1)
917
- end
918
- if @gz.comment
919
- @gz.z.zstream_append_buffer(@gz.comment,@gz.comment.length)
920
- @gz.z.zstream_append_buffer("\0", 1)
921
- end
922
-
923
- @gz.z.flags |= GZFILE_FLAG_HEADER_FINISHED
924
- end
925
-
926
- def gzfile_make_footer()
927
- buf = 0.chr * 8
928
- buf[0,4] = gzfile_set32(@gz.crc)
929
- buf[4,4] = gzfile_set32(@gz.z.stream.total_in)
930
- @gz.z.zstream_append_buffer(buf, buf.length)
931
- @gz.z.flags |= GZFILE_FLAG_FOOTER_FINISHED
932
- end
933
-
934
- def gzfile_read_header()
935
- if !gzfile_read_raw_ensure(10)
936
- raise GzipFile::Error, "not in gzip format"
937
- end
938
-
939
- head = @gz.z.input
940
-
941
- if (head[0].ord != GZ_MAGIC1 || head[1].ord != GZ_MAGIC2)
942
- raise GzipFile::Error, "not in gzip format"
943
- end
944
- if (head[2].ord != GZ_METHOD_DEFLATE)
945
- raise GzipFile::Error, "unsupported compression method #{head[2].ord}"
946
- end
947
-
948
- flags = head[3].ord
949
- if (flags & GZ_FLAG_MULTIPART).nonzero?
950
- raise GzipFile::Error, "multi-part gzip file is not supported"
951
- elsif (flags & GZ_FLAG_ENCRYPT).nonzero?
952
- raise GzipFile::Error, "encrypted gzip file is not supported"
953
- elsif (flags & GZ_FLAG_UNKNOWN_MASK).nonzero?
954
- raise GzipFile::Error, "unknown flags 0x%02x" % flags
955
- end
956
-
957
- if (head[8].ord & GZ_EXTRAFLAG_FAST).nonzero?
958
- @gz.level = Z_BEST_SPEED
959
- elsif (head[8].ord & GZ_EXTRAFLAG_SLOW).nonzero?
960
- @gz.level = Z_BEST_COMPRESSION
961
- else
962
- @gz.level = Z_DEFAULT_COMPRESSION
963
- end
964
-
965
- @gz.mtime = gzfile_get32(head[4,4])
966
- @gz.os_code = head[9].ord
967
- @gz.z.zstream_discard_input(10)
968
-
969
- if (flags & GZ_FLAG_EXTRA).nonzero?
970
- if !gzfile_read_raw_ensure(2)
971
- raise GzipFile::Error, "unexpected end of file"
972
- end
973
- len = gzfile_get16(@gz.z.input)
974
- if !gzfile_read_raw_ensure(2 + len)
975
- raise GzipFile::Error, "unexpected end of file"
976
- end
977
- @gz.z.zstream_discard_input(2 + len)
978
- end
979
- if (flags & GZ_FLAG_ORIG_NAME).nonzero?
980
- ap = gzfile_read_raw_until_zero(0)
981
- len = ap
982
- @gz.orig_name = @gz.z.input[0,len]
983
- @gz.z.zstream_discard_input(len + 1)
984
- end
985
- if (flags & GZ_FLAG_COMMENT).nonzero?
986
- ap = gzfile_read_raw_until_zero(0)
987
- len = ap
988
- @gz.comment = @gz.z.input[0,len]
989
- @gz.z.zstream_discard_input(len + 1)
990
- end
991
-
992
- if (@gz.z.input && @gz.z.input.length > 0)
993
- @gz.z.zstream_run(0, 0, Z_SYNC_FLUSH)
994
- end
995
- end
996
-
997
- def gzfile_check_footer()
998
- @gz.z.flags |= GZFILE_FLAG_FOOTER_FINISHED
999
-
1000
- if (!gzfile_read_raw_ensure(8))
1001
- raise NoFooter, "footer is not found"
1002
- end
1003
- crc = gzfile_get32(@gz.z.input)
1004
- length = gzfile_get32(@gz.z.input[4,4])
1005
- @gz.z.stream.total_in += 8
1006
- @gz.z.zstream_discard_input(8)
1007
- if (@gz.crc != crc)
1008
- raise CRCError, "invalid compressed data -- crc error"
1009
- end
1010
- if (@gz.z.stream.total_out != length)
1011
- raise LengthError, "invalid compressed data -- length error"
1012
- end
1013
- end
1014
-
1015
- def gzfile_calc_crc(str)
1016
- if (str.length <= @gz.ungetc)
1017
- @gz.ungetc -= str.length
1018
- else
1019
- @gz.crc = crc32(@gz.crc, str[@gz.ungetc,str.length - @gz.ungetc],
1020
- str.length - @gz.ungetc)
1021
- @gz.ungetc = 0
1022
- end
1023
- end
1024
-
1025
- end
1026
-
1027
- class GzipWriter < GzipFile
1028
-
1029
- def mtime=(mtime)
1030
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1031
-
1032
- if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).nonzero?
1033
- raise GzipFile::Error,"header is already written"
1034
- end
1035
-
1036
- @gz.mtime = mtime.to_i
1037
- end
1038
-
1039
- def orig_name=(str)
1040
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1041
-
1042
- if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).nonzero?
1043
- raise GzipFile::Error,"header is already written"
1044
- end
1045
-
1046
- ap = str[0.chr]
1047
- @gz.orig_name = ap ? str[0,ap] : str.dup
1048
- end
1049
-
1050
- def comment=(str)
1051
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1052
-
1053
- if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).nonzero?
1054
- raise GzipFile::Error,"header is already written"
1055
- end
1056
-
1057
- @gz.comment = str.dup
1058
- end
1059
-
1060
- def pos
1061
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1062
- @gz.z.stream.total_in
1063
- end
1064
-
1065
- alias tell :pos
1066
-
1067
- def self.open(filename, level=Z_DEFAULT_COMPRESSION, strategy=Z_DEFAULT_STRATEGY, &blk)
1068
- GzipWriter.gzfile_s_open(filename, 'wb', level, strategy, &blk)
1069
- end
1070
-
1071
- def initialize(io, level=Z_DEFAULT_COMPRESSION, strategy=Z_DEFAULT_STRATEGY)
1072
- gzfile_new(DeflateFuncs, :gzfile_writer_end)
1073
- @gz.level = level
1074
-
1075
- err = deflateInit2(
1076
- @gz.z.stream,
1077
- @gz.level,
1078
- Z_DEFLATED,
1079
- -MAX_WBITS,
1080
- DEF_MEM_LEVEL,
1081
- strategy
1082
- )
1083
-
1084
- if err != Z_OK
1085
- raise_zlib_error(err, @gz.stream.msg)
1086
- end
1087
-
1088
- @gz.io = io
1089
- @gz.z.ZSTREAM_READY()
1090
- end
1091
-
1092
- def flush(v_flush=Z_SYNC_FLUSH)
1093
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1094
-
1095
- if v_flush != Z_NO_FLUSH
1096
- @gz.z.zstream_run("", 0, v_flush)
1097
- end
1098
-
1099
- gzfile_write_raw()
1100
-
1101
- if defined?(@gz.io.flush)
1102
- @gz.io.flush()
1103
- end
1104
-
1105
- self
1106
- end
1107
-
1108
- def write(str)
1109
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1110
- str = str.to_s
1111
- gzfile_write(str, str.length)
1112
- str.length
1113
- end
1114
-
1115
- def putc(ch)
1116
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1117
- gzfile_write(ch.chr, 1)
1118
- ch
1119
- end
1120
-
1121
- def <<(str)
1122
- @gz.io << str
1123
- end
1124
-
1125
- def printf(*arg)
1126
- @gz.io.printf(*arg)
1127
- end
1128
-
1129
- def print(*arg)
1130
- @gz.io.print(*arg)
1131
- end
1132
-
1133
- def puts(str)
1134
- @gz.io.puts(str)
1135
- end
1136
-
1137
- def gzfile_write_raw
1138
- if (@gz.z.buf.offset > 0)
1139
- str = @gz.z.zstream_detach_buffer()
1140
- @gz.io.write(str)
1141
- if ((@gz.z.flags & GZFILE_FLAG_SYNC).nonzero? && defined?(@gz.io.flush))
1142
- @gz.io.flush()
1143
- end
1144
- end
1145
- end
1146
-
1147
- private :gzfile_write_raw
1148
-
1149
- def gzfile_write(str,len)
1150
- if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).zero?
1151
- gzfile_make_header()
1152
- end
1153
-
1154
- if (len > 0 || (@gz.z.flags & GZFILE_FLAG_SYNC))
1155
- @gz.crc = crc32(@gz.crc, str, len)
1156
- @gz.z.zstream_run(str, len, (@gz.z.flags & GZFILE_FLAG_SYNC).nonzero? ?
1157
- Z_SYNC_FLUSH : Z_NO_FLUSH)
1158
- end
1159
- gzfile_write_raw()
1160
- end
1161
-
1162
- private :gzfile_write
1163
-
1164
- def gzfile_writer_end_run
1165
- if (@gz.z.flags & GZFILE_FLAG_HEADER_FINISHED).zero?
1166
- gzfile_make_header()
1167
- end
1168
- @gz.z.zstream_run("", 0, Z_FINISH)
1169
- gzfile_make_footer()
1170
- gzfile_write_raw()
1171
-
1172
- return nil
1173
- end
1174
-
1175
- def gzfile_writer_end
1176
- return if @gz.z.ZSTREAM_IS_CLOSING()
1177
- @gz.z.flags |= ZSTREAM_FLAG_CLOSING
1178
- begin
1179
- gzfile_writer_end_run()
1180
- ensure
1181
- @gz.z.zstream_end()
1182
- end
1183
- end
1184
- end
1185
-
1186
- class GzipReader < GzipFile
1187
- include Enumerable
1188
-
1189
- def lineno
1190
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1191
- @gz.lineno
1192
- end
1193
-
1194
- def lineno=(lineno)
1195
- raise GzipFile::Error, "closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1196
- @gz.lineno = lineno
1197
- end
1198
-
1199
- def eof
1200
- raise GzipFile::Error,"closed gzip stream" unless @gz.z.ZSTREAM_IS_READY()
1201
- GZFILE_IS_FINISHED(@gz)
1202
- end
1203
- alias eof? :eof
1204
-
1205
- def pos
1206
- if @gz.z.buf.nil?
1207
- @gz.z.stream.total_out
1208
- else
1209
- @gz.z.stream.total_out - @gz.z.buf.offset
1210
- end
1211
- end
1212
- alias tell :pos
1213
-
1214
- def self.open(filename,level=Z_DEFAULT_COMPRESSION,strategy=Z_DEFAULT_STRATEGY,&blk)
1215
- GzipReader.gzfile_s_open(filename,"rb",level=Z_DEFAULT_COMPRESSION,strategy=Z_DEFAULT_STRATEGY,&blk)
1216
- end
1217
-
1218
- def initialize(io,level=Z_DEFAULT_COMPRESSION,strategy=Z_DEFAULT_STRATEGY)
1219
- gzfile_new(InflateFuncs, :gzfile_reader_end)
1220
- @gz.level = level
1221
- err = inflateInit2(@gz.z.stream, -MAX_WBITS)
1222
- if (err != Z_OK)
1223
- raise_zlib_error(err, @gz.stream.msg)
1224
- end
1225
- @gz.io = io
1226
- @gz.z.ZSTREAM_READY()
1227
- gzfile_read_header()
1228
- self
1229
- end
1230
-
1231
- def rewind()
1232
- gzfile_reader_rewind()
1233
- return 0
1234
- end
1235
-
1236
- def unused()
1237
- gzfile_reader_get_unused()
1238
- end
1239
-
1240
- def read(len=nil)
1241
- if len.nil?
1242
- return gzfile_read_all()
1243
- end
1244
-
1245
- if len < 0
1246
- raise ArgumentError, "negative length #{len} given"
1247
- end
1248
-
1249
- return gzfile_read(len)
1250
- end
1251
-
1252
- def getc()
1253
- dst = gzfile_read(1)
1254
- dst ? dst[0] : dst
1255
- end
1256
-
1257
- def readchar()
1258
- dst = getc()
1259
- if dst.nil?
1260
- raise EOFError, "end of file reached"
1261
- end
1262
- dst
1263
- end
1264
-
1265
- def each_byte()
1266
- while (c = getc)
1267
- yield(c)
1268
- end
1269
- nil
1270
- end
1271
-
1272
- def ungetc(ch)
1273
- gzfile_ungetc(ch)
1274
- nil
1275
- end
1276
-
1277
- def gets(rs=$/)
1278
- dst = gzreader_gets(rs)
1279
- $_ = dst if dst
1280
- dst
1281
- end
1282
-
1283
- def readline(rs=$/)
1284
- gets(rs)
1285
- end
1286
-
1287
- def each(rs=$/)
1288
- while (str = gzreader_gets(rs))
1289
- yield(str)
1290
- end
1291
- self
1292
- end
1293
- alias each_line :each
1294
-
1295
- def readlines(rs=$/)
1296
- dst = []
1297
- while str = gzreader_gets(rs)
1298
- dst.push(str)
1299
- end
1300
- dst
1301
- end
1302
-
1303
- private
1304
-
1305
- def gzfile_reader_end_run()
1306
- if (GZFILE_IS_FINISHED(@gz) && (@gz.z.flags &
1307
- GZFILE_FLAG_FOOTER_FINISHED).zero?)
1308
- gzfile_check_footer()
1309
- end
1310
- nil
1311
- end
1312
-
1313
- def gzfile_reader_end()
1314
- return if @gz.z.ZSTREAM_IS_CLOSING()
1315
- @gz.z.flags |= ZSTREAM_FLAG_CLOSING
1316
- begin
1317
- gzfile_reader_end_run()
1318
- ensure
1319
- @gz.z.zstream_end()
1320
- end
1321
- end
1322
-
1323
- def gzfile_ungetc(c)
1324
- @gz.z.zstream_buffer_ungetc(c)
1325
- @gz.ungetc+=1
1326
- end
1327
-
1328
- def gzfile_reader_rewind
1329
- n = @gz.z.stream.total_in
1330
- if @gz.z.input
1331
- n += @gz.z.input.length
1332
- end
1333
- @gz.io.seek(-n,1)
1334
- gzfile_reset()
1335
- end
1336
-
1337
- def gzfile_reader_get_unused()
1338
- return nil if (!@gz.z.ZSTREAM_IS_READY())
1339
- return nil if (!GZFILE_IS_FINISHED(@gz))
1340
- if (@gz.z.flags & GZFILE_FLAG_FOOTER_FINISHED).zero?
1341
- gzfile_check_footer()
1342
- end
1343
- return nil if @gz.z.input.nil?
1344
- @gz.z.input.dup
1345
- end
1346
-
1347
- def rscheck(rsptr,rslen,rs)
1348
- raise RuntimeError, "rs modified" if rs != rsptr
1349
- end
1350
-
1351
- def gzreader_gets(rs=$/)
1352
- if rs && rs.class != String
1353
- raise TypeError,"wrong argument type #{rs.class} (expected String)"
1354
- end
1355
- if rs.nil?
1356
- dst = gzfile_read_all()
1357
- @gz.lineno += 1 if dst.length.nonzero?
1358
- return dst
1359
- end
1360
- if rs.length.zero?
1361
- rsptr = "\n\n"
1362
- rslen = 2
1363
- rspara = true
1364
- else
1365
- rsptr = rs
1366
- rslen = rs.length
1367
- rspara = false
1368
- end
1369
- if rspara
1370
- gzreader_skip_linebreaks
1371
- end
1372
- while (@gz.z.buf.offset < rslen)
1373
- if (@gz.z.ZSTREAM_IS_FINISHED())
1374
- @gz.lineno+=1 if (@gz.z.buf.offset > 0)
1375
- return gzfile_read(rslen)
1376
- end
1377
- gzfile_read_more()
1378
- end
1379
-
1380
- ap = 0
1381
- n = rslen
1382
- loop do
1383
- if (n > @gz.z.buf.offset)
1384
- break if (@gz.z.ZSTREAM_IS_FINISHED())
1385
- gzfile_read_more()
1386
- ap = n - rslen
1387
- end
1388
-
1389
- rscheck(rsptr, rslen, rs) if (!rspara)
1390
- res = @gz.z.buf.buffer[ap,@gz.z.buf.offset - n + 1].index(rsptr[0])
1391
-
1392
- if res.nil?
1393
- n = @gz.z.buf.offset + 1
1394
- else
1395
- n += (res - ap)
1396
- ap = res
1397
- break if (rslen == 1 || @gz.z.buf.buffer[ap,rslen]==rsptr)
1398
- ap+=1
1399
- n+=1
1400
- end
1401
- end
1402
-
1403
- @gz.lineno+=1
1404
- dst = gzfile_read(n)
1405
- if (rspara)
1406
- gzreader_skip_linebreaks()
1407
- end
1408
- dst
1409
- end
1410
-
1411
- def gzfile_read(len)
1412
- if len < 0
1413
- raise ArgumentError, "negative length #{len} given"
1414
- end
1415
-
1416
- if len.zero?
1417
- return ""
1418
- end
1419
-
1420
- while (!@gz.z.ZSTREAM_IS_FINISHED() && @gz.z.buf.offset < len)
1421
- gzfile_read_more()
1422
- end
1423
-
1424
- if (GZFILE_IS_FINISHED(@gz))
1425
- if (@gz.z.flags & GZFILE_FLAG_FOOTER_FINISHED).zero?
1426
- gzfile_check_footer()
1427
- end
1428
- return nil
1429
- end
1430
-
1431
- dst = @gz.z.zstream_shift_buffer(len)
1432
- gzfile_calc_crc(dst)
1433
- dst
1434
- end
1435
-
1436
- def gzfile_read_all()
1437
- while (!@gz.z.ZSTREAM_IS_FINISHED())
1438
- gzfile_read_more()
1439
- end
1440
- if (GZFILE_IS_FINISHED(@gz))
1441
- if (@gz.z.flags & GZFILE_FLAG_FOOTER_FINISHED).zero?
1442
- gzfile_check_footer()
1443
- end
1444
- return ''
1445
- end
1446
-
1447
- dst = @gz.z.zstream_detach_buffer()
1448
- gzfile_calc_crc(dst)
1449
- dst
1450
- end
1451
-
1452
- def gzfile_read_raw()
1453
- str = @gz.io.read(GZFILE_READ_SIZE)
1454
- if str && str.class != String
1455
- raise TypeError,"wrong argument type #{rs.class} (expected String)"
1456
- end
1457
- str
1458
- end
1459
-
1460
- def gzfile_read_raw_ensure(size)
1461
- while @gz.z.input.nil? || @gz.z.input.length < size
1462
- str = gzfile_read_raw()
1463
- return false if str.nil?
1464
- @gz.z.zstream_append_input(str,str.length)
1465
- end
1466
- true
1467
- end
1468
-
1469
- def gzfile_read_raw_until_zero(offset)
1470
- ap = nil
1471
-
1472
- loop do
1473
- ap = @gz.z.input[offset, @gz.z.input.length-offset].index(0.chr)
1474
- break if ap
1475
- str = gzfile_read_raw()
1476
-
1477
- raise Error, "unexpected end of file" if str.nil?
1478
-
1479
- offset = @gz.z.input.length
1480
- @gz.z.zstream_append_input(str,str.length)
1481
- end
1482
-
1483
- ap
1484
- end
1485
-
1486
- def gzfile_read_more
1487
- while (!@gz.z.ZSTREAM_IS_FINISHED())
1488
- str = gzfile_read_raw()
1489
- if str.nil?
1490
- if (!@gz.z.ZSTREAM_IS_FINISHED())
1491
- raise Error, "unexpected end of file"
1492
- end
1493
- break
1494
- end
1495
- if (str.length > 0)
1496
- @gz.z.zstream_run(str, str.length,Z_SYNC_FLUSH)
1497
- end
1498
- break if (@gz.z.buf.offset > 0)
1499
- end
1500
- @gz.z.buf.offset
1501
- end
1502
- end
1503
-
1504
- module_function
1505
-
1506
- def zlib_version
1507
- zlibVersion()
1508
- end
1509
-
1510
- def adler32(string=nil, adler=nil)
1511
- if adler
1512
- [adler].pack('L') # check range
1513
- sum = adler
1514
- elsif string.nil?
1515
- sum = 0
1516
- else
1517
- sum = Rbzlib.adler32(0,nil)
1518
- end
1519
-
1520
- if string.nil?
1521
- sum = Rbzlib.adler32(sum,nil)
1522
- else
1523
- sum = Rbzlib.adler32(sum,string,string.length)
1524
- end
1525
- sum
1526
- end
1527
-
1528
- def crc32(string=nil, adler=nil)
1529
- if adler
1530
- [adler].pack('L') # check range
1531
- sum = adler
1532
- elsif string.nil?
1533
- sum = 0
1534
- else
1535
- sum = Rbzlib.crc32(0,nil)
1536
- end
1537
-
1538
- if string.nil?
1539
- sum = Rbzlib.crc32(sum,nil)
1540
- else
1541
- sum = Rbzlib.crc32(sum,string,string.length)
1542
- end
1543
- sum
1544
- end
1545
-
1546
- def crc_table
1547
- get_crc_table
1548
- end
1549
-
1550
- 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 '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