pr-zlib 1.0.0

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