pr-zlib 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/pr/zlib.rb ADDED
@@ -0,0 +1,1550 @@
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.0'
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
+ dst = @z.zstream_detach_buffer()
487
+ end
488
+
489
+ def flush_next_in
490
+ dst = @z.zstream_detach_input
491
+ end
492
+
493
+ def flush_next_out
494
+ dst = @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
+ dst = @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
+ dst = @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
+ dst = 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