rubysl-zlib 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5c8834ce05136d4bccc980b8340f08ffdc55b2b8
4
- data.tar.gz: 89e1a54194e94a79c962cf8e51d97375cc09fcce
3
+ metadata.gz: 1076e7a2ba523e3a8345ea34fe039b2184052466
4
+ data.tar.gz: c6b070cd9a773dd02db9ef613f373fc800abeae8
5
5
  SHA512:
6
- metadata.gz: 89d136000290cdc485aba19fa7608df7ca633502d397c53bf5f1d21dfd4958e0d5cb89d40a746d72b0b9ce45673d866c33c993d44754f7245bc66dbc0c4ad222
7
- data.tar.gz: 9cfc9b259bc9d8ad304457cda99e27c628dc78bf79ceb7268828c6f6adb3741f2f5c97b354dff6d7d755a0929808b6615684184f5e28b0524a55f70518fb17b9
6
+ metadata.gz: 415ef09bc699e6de21edae923dd75f8384e96b2851d428071fc454cab229224e0e7e7140d99175a69ee21524eff8f61dc63133054ee3274894a38c1396337d29
7
+ data.tar.gz: 0d111deffcf2c356940db2e85ca7cb230febafb2efa210b074a7340c8b9c6c6173160f1d15d84c0510782552b391bedc700d5e2c46a710ab955a0573f2c5de52
@@ -1,7 +1,9 @@
1
1
  language: ruby
2
+ before_install:
3
+ - rvm use $RVM --install --binary --fuzzy
4
+ - gem update --system
5
+ - gem --version
6
+ - gem install rubysl-bundler
2
7
  env:
3
- - RUBYLIB=lib
4
- script: bundle exec mspec
5
- rvm:
6
- - 1.9.3
7
- - rbx-nightly-19mode
8
+ - RVM=rbx-nightly-d21 RUBYLIB=lib
9
+ script: bundle exec mspec spec
@@ -1,7 +1,7 @@
1
1
  #
2
2
  # extconf.rb
3
3
  #
4
- # $Id: extconf.rb 26353 2010-01-19 05:14:29Z usa $
4
+ # $Id: extconf.rb 37527 2012-11-06 18:50:53Z luislavena $
5
5
  #
6
6
 
7
7
  require 'mkmf'
@@ -10,12 +10,12 @@ require 'rbconfig'
10
10
  dir_config 'zlib'
11
11
 
12
12
 
13
- if %w'z libz zlib1 zlib zdll'.find {|z| have_library(z, 'deflateReset')} and
13
+ if %w'z libz zlib1 zlib zdll zlibwapi'.find {|z| have_library(z, 'deflateReset')} and
14
14
  have_header('zlib.h') then
15
15
 
16
16
  defines = []
17
17
 
18
- message 'checking for kind of operating system... '
18
+ Logging::message 'checking for kind of operating system... '
19
19
  os_code = with_config('os-code') ||
20
20
  case RUBY_PLATFORM.split('-',2)[1]
21
21
  when 'amigaos' then
@@ -48,14 +48,11 @@ if %w'z libz zlib1 zlib zdll'.find {|z| have_library(z, 'deflateReset')} and
48
48
  'OS_UNKNOWN' => 'Unknown',
49
49
  }
50
50
  unless OS_NAMES.key? os_code then
51
- puts "invalid OS_CODE `#{os_code}'"
52
- exit
51
+ raise "invalid OS_CODE `#{os_code}'"
53
52
  end
54
- message "#{OS_NAMES[os_code]}\n"
53
+ Logging::message "#{OS_NAMES[os_code]}\n"
55
54
  defines << "OS_CODE=#{os_code}"
56
55
 
57
- $CFLAGS += " -Wno-pointer-sign"
58
-
59
56
  $defs.concat(defines.collect{|d|' -D'+d})
60
57
 
61
58
  have_func('crc32_combine', 'zlib.h')
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Copyright (C) UENO Katsuhiro 2000-2003
5
5
  *
6
- * $Id: zlib.c 34544 2012-02-10 18:37:45Z naruse $
6
+ * $Id: zlib.c 42720 2013-08-28 20:36:21Z drbrain $
7
7
  */
8
8
 
9
9
  #define RSTRING_NOT_MODIFIED 1
@@ -12,6 +12,7 @@
12
12
  #include <zlib.h>
13
13
  #include <time.h>
14
14
  #include <ruby/io.h>
15
+ #include <ruby/thread.h>
15
16
 
16
17
  #ifdef HAVE_VALGRIND_MEMCHECK_H
17
18
  # include <valgrind/memcheck.h>
@@ -22,8 +23,8 @@
22
23
  # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) VALGRIND_MAKE_WRITABLE((p), (n))
23
24
  # endif
24
25
  #else
25
- # define VALGRIND_MAKE_MEM_DEFINED(p, n) /* empty */
26
- # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) /* empty */
26
+ # define VALGRIND_MAKE_MEM_DEFINED(p, n) 0
27
+ # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
27
28
  #endif
28
29
 
29
30
  #define RUBY_ZLIB_VERSION "0.6.0"
@@ -58,6 +59,8 @@ max_uint(long n)
58
59
 
59
60
  #define sizeof(x) ((int)sizeof(x))
60
61
 
62
+ static ID id_dictionaries;
63
+
61
64
  /*--------- Prototypes --------*/
62
65
 
63
66
  static NORETURN(void raise_zlib_error(int, const char*));
@@ -72,6 +75,7 @@ static void finalizer_warn(const char*);
72
75
 
73
76
  struct zstream;
74
77
  struct zstream_funcs;
78
+ struct zstream_run_args;
75
79
  static void zstream_init(struct zstream*, const struct zstream_funcs*);
76
80
  static void zstream_expand_buffer(struct zstream*);
77
81
  static void zstream_expand_buffer_into(struct zstream*, unsigned long);
@@ -224,9 +228,50 @@ static VALUE rb_gzreader_readlines(int, VALUE*, VALUE);
224
228
  /*
225
229
  * Document-module: Zlib
226
230
  *
227
- * == Overview
231
+ * This module provides access to the {zlib library}[http://zlib.net]. Zlib is
232
+ * designed to be a portable, free, general-purpose, legally unencumbered --
233
+ * that is, not covered by any patents -- lossless data-compression library
234
+ * for use on virtually any computer hardware and operating system.
235
+ *
236
+ * The zlib compression library provides in-memory compression and
237
+ * decompression functions, including integrity checks of the uncompressed
238
+ * data.
239
+ *
240
+ * The zlib compressed data format is described in RFC 1950, which is a
241
+ * wrapper around a deflate stream which is described in RFC 1951.
242
+ *
243
+ * The library also supports reading and writing files in gzip (.gz) format
244
+ * with an interface similar to that of IO. The gzip format is described in
245
+ * RFC 1952 which is also a wrapper around a deflate stream.
246
+ *
247
+ * The zlib format was designed to be compact and fast for use in memory and on
248
+ * communications channels. The gzip format was designed for single-file
249
+ * compression on file systems, has a larger header than zlib to maintain
250
+ * directory information, and uses a different, slower check method than zlib.
251
+ *
252
+ * See your system's zlib.h for further information about zlib
253
+ *
254
+ * == Sample usage
255
+ *
256
+ * Using the wrapper to compress strings with default parameters is quite
257
+ * simple:
258
+ *
259
+ * require "zlib"
260
+ *
261
+ * data_to_compress = File.read("don_quixote.txt")
262
+ *
263
+ * puts "Input size: #{data_to_compress.size}"
264
+ * #=> Input size: 2347740
265
+ *
266
+ * data_compressed = Zlib::Deflate.deflate(data_to_compress)
267
+ *
268
+ * puts "Compressed size: #{data_compressed.size}"
269
+ * #=> Compressed size: 887238
270
+ *
271
+ * uncompressed_data = Zlib::Inflate.inflate(data_compressed)
228
272
  *
229
- * Access to the zlib library.
273
+ * puts "Uncompressed data is: #{uncompressed_data}"
274
+ * #=> Uncompressed data is: The Project Gutenberg EBook of Don Quixote...
230
275
  *
231
276
  * == Class tree
232
277
  *
@@ -251,8 +296,6 @@ static VALUE rb_gzreader_readlines(int, VALUE*, VALUE);
251
296
  * - Zlib::GzipFile::CRCError
252
297
  * - Zlib::GzipFile::NoFooter
253
298
  *
254
- * see also zlib.h
255
- *
256
299
  */
257
300
  void Init_zlib(void);
258
301
 
@@ -267,39 +310,39 @@ raise_zlib_error(int err, const char *msg)
267
310
  VALUE exc;
268
311
 
269
312
  if (!msg) {
270
- msg = zError(err);
313
+ msg = zError(err);
271
314
  }
272
315
 
273
316
  switch(err) {
274
317
  case Z_STREAM_END:
275
- exc = rb_exc_new2(cStreamEnd, msg);
276
- break;
318
+ exc = rb_exc_new2(cStreamEnd, msg);
319
+ break;
277
320
  case Z_NEED_DICT:
278
- exc = rb_exc_new2(cNeedDict, msg);
279
- break;
321
+ exc = rb_exc_new2(cNeedDict, msg);
322
+ break;
280
323
  case Z_STREAM_ERROR:
281
- exc = rb_exc_new2(cStreamError, msg);
282
- break;
324
+ exc = rb_exc_new2(cStreamError, msg);
325
+ break;
283
326
  case Z_DATA_ERROR:
284
- exc = rb_exc_new2(cDataError, msg);
285
- break;
327
+ exc = rb_exc_new2(cDataError, msg);
328
+ break;
286
329
  case Z_BUF_ERROR:
287
- exc = rb_exc_new2(cBufError, msg);
288
- break;
330
+ exc = rb_exc_new2(cBufError, msg);
331
+ break;
289
332
  case Z_VERSION_ERROR:
290
- exc = rb_exc_new2(cVersionError, msg);
291
- break;
333
+ exc = rb_exc_new2(cVersionError, msg);
334
+ break;
292
335
  case Z_MEM_ERROR:
293
- exc = rb_exc_new2(cMemError, msg);
294
- break;
336
+ exc = rb_exc_new2(cMemError, msg);
337
+ break;
295
338
  case Z_ERRNO:
296
- rb_sys_fail(msg);
297
- /* no return */
339
+ rb_sys_fail(msg);
340
+ /* no return */
298
341
  default:
299
342
  {
300
- char buf[BUFSIZ];
301
- snprintf(buf, BUFSIZ, "unknown zlib error %d: %s", err, msg);
302
- exc = rb_exc_new2(cZError, buf);
343
+ char buf[BUFSIZ];
344
+ snprintf(buf, BUFSIZ, "unknown zlib error %d: %s", err, msg);
345
+ exc = rb_exc_new2(cZError, buf);
303
346
  }
304
347
  }
305
348
 
@@ -338,11 +381,11 @@ static uLong
338
381
  checksum_long(uLong (*func)(uLong, const Bytef*, uInt), uLong sum, const Bytef *ptr, long len)
339
382
  {
340
383
  if (len > UINT_MAX) {
341
- do {
342
- sum = func(sum, ptr, UINT_MAX);
343
- ptr += UINT_MAX;
344
- len -= UINT_MAX;
345
- } while (len >= UINT_MAX);
384
+ do {
385
+ sum = func(sum, ptr, UINT_MAX);
386
+ ptr += UINT_MAX;
387
+ len -= UINT_MAX;
388
+ } while (len >= UINT_MAX);
346
389
  }
347
390
  if (len > 0) sum = func(sum, ptr, (uInt)len);
348
391
  return sum;
@@ -363,21 +406,21 @@ do_checksum(argc, argv, func)
363
406
  rb_scan_args(argc, argv, "02", &str, &vsum);
364
407
 
365
408
  if (!NIL_P(vsum)) {
366
- sum = NUM2ULONG(vsum);
409
+ sum = NUM2ULONG(vsum);
367
410
  }
368
411
  else if (NIL_P(str)) {
369
- sum = 0;
412
+ sum = 0;
370
413
  }
371
414
  else {
372
- sum = func(0, Z_NULL, 0);
415
+ sum = func(0, Z_NULL, 0);
373
416
  }
374
417
 
375
418
  if (NIL_P(str)) {
376
- sum = func(sum, Z_NULL, 0);
419
+ sum = func(sum, Z_NULL, 0);
377
420
  }
378
421
  else {
379
- StringValue(str);
380
- sum = checksum_long(func, sum, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
422
+ StringValue(str);
423
+ sum = checksum_long(func, sum, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
381
424
  }
382
425
  return rb_uint2inum(sum);
383
426
  }
@@ -414,7 +457,7 @@ static VALUE
414
457
  rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2)
415
458
  {
416
459
  return ULONG2NUM(
417
- adler32_combine(NUM2ULONG(adler1), NUM2ULONG(adler2), NUM2LONG(len2)));
460
+ adler32_combine(NUM2ULONG(adler1), NUM2ULONG(adler2), NUM2LONG(len2)));
418
461
  }
419
462
  #else
420
463
  #define rb_zlib_adler32_combine rb_f_notimplement
@@ -452,7 +495,7 @@ static VALUE
452
495
  rb_zlib_crc32_combine(VALUE klass, VALUE crc1, VALUE crc2, VALUE len2)
453
496
  {
454
497
  return ULONG2NUM(
455
- crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2)));
498
+ crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2)));
456
499
  }
457
500
  #else
458
501
  #define rb_zlib_crc32_combine rb_f_notimplement
@@ -478,7 +521,7 @@ rb_zlib_crc_table(VALUE obj)
478
521
  dst = rb_ary_new2(256);
479
522
 
480
523
  for (i = 0; i < 256; i++) {
481
- rb_ary_push(dst, rb_uint2inum(crctbl[i]));
524
+ rb_ary_push(dst, rb_uint2inum(crctbl[i]));
482
525
  }
483
526
  return dst;
484
527
  }
@@ -494,9 +537,9 @@ struct zstream {
494
537
  VALUE input;
495
538
  z_stream stream;
496
539
  const struct zstream_funcs {
497
- int (*reset)(z_streamp);
498
- int (*end)(z_streamp);
499
- int (*run)(z_streamp, int);
540
+ int (*reset)(z_streamp);
541
+ int (*end)(z_streamp);
542
+ int (*run)(z_streamp, int);
500
543
  } *func;
501
544
  };
502
545
 
@@ -504,16 +547,22 @@ struct zstream {
504
547
  #define ZSTREAM_FLAG_IN_STREAM 0x2
505
548
  #define ZSTREAM_FLAG_FINISHED 0x4
506
549
  #define ZSTREAM_FLAG_CLOSING 0x8
507
- #define ZSTREAM_FLAG_UNUSED 0x10
550
+ #define ZSTREAM_FLAG_GZFILE 0x10 /* disallows yield from expand_buffer for
551
+ gzip*/
552
+ #define ZSTREAM_FLAG_UNUSED 0x20
508
553
 
509
554
  #define ZSTREAM_READY(z) ((z)->flags |= ZSTREAM_FLAG_READY)
510
555
  #define ZSTREAM_IS_READY(z) ((z)->flags & ZSTREAM_FLAG_READY)
511
556
  #define ZSTREAM_IS_FINISHED(z) ((z)->flags & ZSTREAM_FLAG_FINISHED)
512
557
  #define ZSTREAM_IS_CLOSING(z) ((z)->flags & ZSTREAM_FLAG_CLOSING)
558
+ #define ZSTREAM_IS_GZFILE(z) ((z)->flags & ZSTREAM_FLAG_GZFILE)
559
+
560
+ #define ZSTREAM_EXPAND_BUFFER_OK 0
513
561
 
514
562
  /* I think that more better value should be found,
515
563
  but I gave up finding it. B) */
516
564
  #define ZSTREAM_INITIAL_BUFSIZE 1024
565
+ /* Allow a quick return when the thread is interrupted */
517
566
  #define ZSTREAM_AVAIL_OUT_STEP_MAX 16384
518
567
  #define ZSTREAM_AVAIL_OUT_STEP_MIN 2048
519
568
 
@@ -525,6 +574,13 @@ static const struct zstream_funcs inflate_funcs = {
525
574
  inflateReset, inflateEnd, inflate,
526
575
  };
527
576
 
577
+ struct zstream_run_args {
578
+ struct zstream * z;
579
+ int flush; /* stream flush value for inflate() or deflate() */
580
+ int interrupt; /* stop processing the stream and return to ruby */
581
+ int jump_state; /* for buffer expansion block break or exception */
582
+ int stream_output; /* for streaming zlib processing */
583
+ };
528
584
 
529
585
  static voidpf
530
586
  zlib_mem_alloc(voidpf opaque, uInt items, uInt size)
@@ -534,7 +590,7 @@ zlib_mem_alloc(voidpf opaque, uInt items, uInt size)
534
590
  deflate is performing a conditional jump that depends on an
535
591
  uninitialized value. Isn't that a bug?
536
592
  http://www.zlib.net/zlib_faq.html#faq36 */
537
- VALGRIND_MAKE_MEM_DEFINED(p, items * size);
593
+ (void)VALGRIND_MAKE_MEM_DEFINED(p, items * size);
538
594
  return p;
539
595
  }
540
596
 
@@ -568,75 +624,106 @@ zstream_init(struct zstream *z, const struct zstream_funcs *func)
568
624
  static void
569
625
  zstream_expand_buffer(struct zstream *z)
570
626
  {
571
- long inc;
572
-
573
627
  if (NIL_P(z->buf)) {
574
- /* I uses rb_str_new here not rb_str_buf_new because
575
- rb_str_buf_new makes a zero-length string. */
576
- z->buf = rb_str_new(0, ZSTREAM_INITIAL_BUFSIZE);
577
- z->buf_filled = 0;
578
- z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
579
- z->stream.avail_out = ZSTREAM_INITIAL_BUFSIZE;
580
- return;
628
+ zstream_expand_buffer_into(z, ZSTREAM_INITIAL_BUFSIZE);
629
+ return;
581
630
  }
582
631
 
583
- if (RSTRING_LEN(z->buf) - z->buf_filled >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
584
- /* to keep other threads from freezing */
585
- z->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;
632
+ if (!ZSTREAM_IS_GZFILE(z) && rb_block_given_p()) {
633
+ if (z->buf_filled >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
634
+ int state = 0;
635
+ VALUE self = (VALUE)z->stream.opaque;
636
+
637
+ rb_str_resize(z->buf, z->buf_filled);
638
+ rb_obj_reveal(z->buf, rb_cString);
639
+ OBJ_INFECT(z->buf, self);
640
+
641
+ rb_protect(rb_yield, z->buf, &state);
642
+
643
+ z->buf = Qnil;
644
+ zstream_expand_buffer_into(z, ZSTREAM_AVAIL_OUT_STEP_MAX);
645
+
646
+ if (state)
647
+ rb_jump_tag(state);
648
+
649
+ return;
650
+ }
651
+ else {
652
+ zstream_expand_buffer_into(z,
653
+ ZSTREAM_AVAIL_OUT_STEP_MAX - z->buf_filled);
654
+ }
586
655
  }
587
656
  else {
588
- inc = z->buf_filled / 2;
589
- if (inc < ZSTREAM_AVAIL_OUT_STEP_MIN) {
590
- inc = ZSTREAM_AVAIL_OUT_STEP_MIN;
591
- }
592
- rb_str_resize(z->buf, z->buf_filled + inc);
593
- z->stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?
594
- (int)inc : ZSTREAM_AVAIL_OUT_STEP_MAX;
657
+ if (RSTRING_LEN(z->buf) - z->buf_filled >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
658
+ z->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;
659
+ }
660
+ else {
661
+ long inc = z->buf_filled / 2;
662
+ if (inc < ZSTREAM_AVAIL_OUT_STEP_MIN) {
663
+ inc = ZSTREAM_AVAIL_OUT_STEP_MIN;
664
+ }
665
+ rb_str_resize(z->buf, z->buf_filled + inc);
666
+ z->stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?
667
+ (int)inc : ZSTREAM_AVAIL_OUT_STEP_MAX;
668
+ }
669
+ z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
595
670
  }
596
- z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
597
671
  }
598
672
 
599
673
  static void
600
674
  zstream_expand_buffer_into(struct zstream *z, unsigned long size)
601
675
  {
602
676
  if (NIL_P(z->buf)) {
603
- /* I uses rb_str_new here not rb_str_buf_new because
604
- rb_str_buf_new makes a zero-length string. */
605
- z->buf = rb_str_new(0, size);
606
- z->buf_filled = 0;
607
- z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
608
- z->stream.avail_out = MAX_UINT(size);
677
+ /* I uses rb_str_new here not rb_str_buf_new because
678
+ rb_str_buf_new makes a zero-length string. */
679
+ z->buf = rb_str_new(0, size);
680
+ z->buf_filled = 0;
681
+ z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
682
+ z->stream.avail_out = MAX_UINT(size);
683
+ rb_obj_hide(z->buf);
609
684
  }
610
685
  else if (z->stream.avail_out != size) {
611
- rb_str_resize(z->buf, z->buf_filled + size);
612
- z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
613
- z->stream.avail_out = MAX_UINT(size);
686
+ rb_str_resize(z->buf, z->buf_filled + size);
687
+ z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
688
+ z->stream.avail_out = MAX_UINT(size);
614
689
  }
615
690
  }
616
691
 
692
+ static void *
693
+ zstream_expand_buffer_protect(void *ptr)
694
+ {
695
+ struct zstream *z = (struct zstream *)ptr;
696
+ int state = 0;
697
+
698
+ rb_protect((VALUE (*)(VALUE))zstream_expand_buffer, (VALUE)z, &state);
699
+
700
+ return (void *)(VALUE)state;
701
+ }
702
+
617
703
  static void
618
704
  zstream_append_buffer(struct zstream *z, const Bytef *src, long len)
619
705
  {
620
706
  if (NIL_P(z->buf)) {
621
- z->buf = rb_str_buf_new(len);
622
- rb_str_buf_cat(z->buf, (const char*)src, len);
623
- z->buf_filled = len;
624
- z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
625
- z->stream.avail_out = 0;
626
- return;
707
+ z->buf = rb_str_buf_new(len);
708
+ rb_str_buf_cat(z->buf, (const char*)src, len);
709
+ z->buf_filled = len;
710
+ z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
711
+ z->stream.avail_out = 0;
712
+ rb_obj_hide(z->buf);
713
+ return;
627
714
  }
628
715
 
629
716
  if (RSTRING_LEN(z->buf) < z->buf_filled + len) {
630
- rb_str_resize(z->buf, z->buf_filled + len);
631
- z->stream.avail_out = 0;
717
+ rb_str_resize(z->buf, z->buf_filled + len);
718
+ z->stream.avail_out = 0;
632
719
  }
633
720
  else {
634
- if (z->stream.avail_out >= (uInt)len) {
635
- z->stream.avail_out -= (uInt)len;
636
- }
637
- else {
638
- z->stream.avail_out = 0;
639
- }
721
+ if (z->stream.avail_out >= (uInt)len) {
722
+ z->stream.avail_out -= (uInt)len;
723
+ }
724
+ else {
725
+ z->stream.avail_out = 0;
726
+ }
640
727
  }
641
728
  memcpy(RSTRING_PTR(z->buf) + z->buf_filled, src, len);
642
729
  z->buf_filled += len;
@@ -649,20 +736,36 @@ zstream_append_buffer(struct zstream *z, const Bytef *src, long len)
649
736
  static VALUE
650
737
  zstream_detach_buffer(struct zstream *z)
651
738
  {
652
- VALUE dst;
739
+ VALUE dst, self = (VALUE)z->stream.opaque;
740
+
741
+ if (!ZSTREAM_IS_FINISHED(z) && !ZSTREAM_IS_GZFILE(z) &&
742
+ rb_block_given_p()) {
743
+ /* prevent tiny yields mid-stream, save for next
744
+ * zstream_expand_buffer() or stream end */
745
+ return Qnil;
746
+ }
653
747
 
654
748
  if (NIL_P(z->buf)) {
655
- dst = rb_str_new(0, 0);
749
+ dst = rb_str_new(0, 0);
656
750
  }
657
751
  else {
658
- dst = z->buf;
659
- rb_str_resize(dst, z->buf_filled);
752
+ dst = z->buf;
753
+ rb_str_resize(dst, z->buf_filled);
754
+ rb_obj_reveal(dst, rb_cString);
660
755
  }
661
756
 
757
+ OBJ_INFECT(dst, self);
758
+
662
759
  z->buf = Qnil;
663
760
  z->buf_filled = 0;
664
761
  z->stream.next_out = 0;
665
762
  z->stream.avail_out = 0;
763
+
764
+ if (!ZSTREAM_IS_GZFILE(z) && rb_block_given_p()) {
765
+ rb_yield(dst);
766
+ dst = Qnil;
767
+ }
768
+
666
769
  return dst;
667
770
  }
668
771
 
@@ -673,17 +776,18 @@ zstream_shift_buffer(struct zstream *z, long len)
673
776
  long buflen;
674
777
 
675
778
  if (z->buf_filled <= len) {
676
- return zstream_detach_buffer(z);
779
+ return zstream_detach_buffer(z);
677
780
  }
678
781
 
679
782
  dst = rb_str_subseq(z->buf, 0, len);
783
+ rb_obj_reveal(dst, rb_cString);
680
784
  z->buf_filled -= len;
681
785
  memmove(RSTRING_PTR(z->buf), RSTRING_PTR(z->buf) + len,
682
- z->buf_filled);
786
+ z->buf_filled);
683
787
  z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
684
788
  buflen = RSTRING_LEN(z->buf) - z->buf_filled;
685
789
  if (buflen > ZSTREAM_AVAIL_OUT_STEP_MAX) {
686
- buflen = ZSTREAM_AVAIL_OUT_STEP_MAX;
790
+ buflen = ZSTREAM_AVAIL_OUT_STEP_MAX;
687
791
  }
688
792
  z->stream.avail_out = (uInt)buflen;
689
793
 
@@ -694,16 +798,16 @@ static void
694
798
  zstream_buffer_ungets(struct zstream *z, const Bytef *b, unsigned long len)
695
799
  {
696
800
  if (NIL_P(z->buf) || RSTRING_LEN(z->buf) - z->buf_filled == 0) {
697
- zstream_expand_buffer_into(z, len);
801
+ zstream_expand_buffer_into(z, len);
698
802
  }
699
803
 
700
804
  memmove(RSTRING_PTR(z->buf) + len, RSTRING_PTR(z->buf), z->buf_filled);
701
805
  memmove(RSTRING_PTR(z->buf), b, len);
702
806
  z->buf_filled+=len;
703
807
  if (z->stream.avail_out > 0) {
704
- if (len > z->stream.avail_out) len = z->stream.avail_out;
705
- z->stream.next_out+=len;
706
- z->stream.avail_out-=(uInt)len;
808
+ if (len > z->stream.avail_out) len = z->stream.avail_out;
809
+ z->stream.next_out+=len;
810
+ z->stream.avail_out-=(uInt)len;
707
811
  }
708
812
  }
709
813
 
@@ -711,15 +815,15 @@ static void
711
815
  zstream_buffer_ungetbyte(struct zstream *z, int c)
712
816
  {
713
817
  if (NIL_P(z->buf) || RSTRING_LEN(z->buf) - z->buf_filled == 0) {
714
- zstream_expand_buffer(z);
818
+ zstream_expand_buffer(z);
715
819
  }
716
820
 
717
821
  memmove(RSTRING_PTR(z->buf) + 1, RSTRING_PTR(z->buf), z->buf_filled);
718
822
  RSTRING_PTR(z->buf)[0] = (char)c;
719
823
  z->buf_filled++;
720
824
  if (z->stream.avail_out > 0) {
721
- z->stream.next_out++;
722
- z->stream.avail_out--;
825
+ z->stream.next_out++;
826
+ z->stream.avail_out--;
723
827
  }
724
828
  }
725
829
 
@@ -729,28 +833,29 @@ zstream_append_input(struct zstream *z, const Bytef *src, long len)
729
833
  if (len <= 0) return;
730
834
 
731
835
  if (NIL_P(z->input)) {
732
- z->input = rb_str_buf_new(len);
733
- rb_str_buf_cat(z->input, (const char*)src, len);
836
+ z->input = rb_str_buf_new(len);
837
+ rb_str_buf_cat(z->input, (const char*)src, len);
838
+ rb_obj_hide(z->input);
734
839
  }
735
840
  else {
736
- rb_str_buf_cat(z->input, (const char*)src, len);
841
+ rb_str_buf_cat(z->input, (const char*)src, len);
737
842
  }
738
843
  }
739
844
 
740
845
  #define zstream_append_input2(z,v)\
741
- RB_GC_GUARD(v) = v,\
846
+ RB_GC_GUARD(v),\
742
847
  zstream_append_input((z), (Bytef*)RSTRING_PTR(v), RSTRING_LEN(v))
743
848
 
744
849
  static void
745
850
  zstream_discard_input(struct zstream *z, long len)
746
851
  {
747
852
  if (NIL_P(z->input) || RSTRING_LEN(z->input) <= len) {
748
- z->input = Qnil;
853
+ z->input = Qnil;
749
854
  }
750
855
  else {
751
- memmove(RSTRING_PTR(z->input), RSTRING_PTR(z->input) + len,
752
- RSTRING_LEN(z->input) - len);
753
- rb_str_resize(z->input, RSTRING_LEN(z->input) - len);
856
+ memmove(RSTRING_PTR(z->input), RSTRING_PTR(z->input) + len,
857
+ RSTRING_LEN(z->input) - len);
858
+ rb_str_resize(z->input, RSTRING_LEN(z->input) - len);
754
859
  }
755
860
  }
756
861
 
@@ -764,8 +869,8 @@ static void
764
869
  zstream_passthrough_input(struct zstream *z)
765
870
  {
766
871
  if (!NIL_P(z->input)) {
767
- zstream_append_buffer2(z, z->input);
768
- z->input = Qnil;
872
+ zstream_append_buffer2(z, z->input);
873
+ z->input = Qnil;
769
874
  }
770
875
  }
771
876
 
@@ -775,12 +880,14 @@ zstream_detach_input(struct zstream *z)
775
880
  VALUE dst;
776
881
 
777
882
  if (NIL_P(z->input)) {
778
- dst = rb_str_new(0, 0);
883
+ dst = rb_str_new(0, 0);
779
884
  }
780
885
  else {
781
- dst = z->input;
886
+ dst = z->input;
887
+ rb_obj_reveal(dst, rb_cString);
782
888
  }
783
889
  z->input = Qnil;
890
+ rb_obj_reveal(dst, rb_cString);
784
891
  return dst;
785
892
  }
786
893
 
@@ -791,7 +898,7 @@ zstream_reset(struct zstream *z)
791
898
 
792
899
  err = z->func->reset(&z->stream);
793
900
  if (err != Z_OK) {
794
- raise_zlib_error(err, z->stream.msg);
901
+ raise_zlib_error(err, z->stream.msg);
795
902
  }
796
903
  z->flags = ZSTREAM_FLAG_READY;
797
904
  z->buf = Qnil;
@@ -807,109 +914,173 @@ zstream_end(struct zstream *z)
807
914
  int err;
808
915
 
809
916
  if (!ZSTREAM_IS_READY(z)) {
810
- rb_warning("attempt to close uninitialized zstream; ignored.");
811
- return Qnil;
917
+ rb_warning("attempt to close uninitialized zstream; ignored.");
918
+ return Qnil;
812
919
  }
813
920
  if (z->flags & ZSTREAM_FLAG_IN_STREAM) {
814
- rb_warning("attempt to close unfinished zstream; reset forced.");
815
- zstream_reset(z);
921
+ rb_warning("attempt to close unfinished zstream; reset forced.");
922
+ zstream_reset(z);
816
923
  }
817
924
 
818
925
  zstream_reset_input(z);
819
926
  err = z->func->end(&z->stream);
820
927
  if (err != Z_OK) {
821
- raise_zlib_error(err, z->stream.msg);
928
+ raise_zlib_error(err, z->stream.msg);
822
929
  }
823
930
  z->flags = 0;
824
931
  return Qnil;
825
932
  }
826
933
 
934
+ static void *
935
+ zstream_run_func(void *ptr)
936
+ {
937
+ struct zstream_run_args *args = (struct zstream_run_args *)ptr;
938
+ int err, state, flush = args->flush;
939
+ struct zstream *z = args->z;
940
+ uInt n;
941
+
942
+ err = Z_OK;
943
+ while (!args->interrupt) {
944
+ n = z->stream.avail_out;
945
+ err = z->func->run(&z->stream, flush);
946
+ z->buf_filled += n - z->stream.avail_out;
947
+
948
+ if (err == Z_STREAM_END) {
949
+ z->flags &= ~ZSTREAM_FLAG_IN_STREAM;
950
+ z->flags |= ZSTREAM_FLAG_FINISHED;
951
+ break;
952
+ }
953
+
954
+ if (err != Z_OK && err != Z_BUF_ERROR)
955
+ break;
956
+
957
+ if (z->stream.avail_out > 0) {
958
+ z->flags |= ZSTREAM_FLAG_IN_STREAM;
959
+ break;
960
+ }
961
+
962
+ if (z->stream.avail_in == 0 && z->func == &inflate_funcs) {
963
+ /* break here because inflate() return Z_BUF_ERROR when avail_in == 0. */
964
+ /* but deflate() could be called with avail_in == 0 (there's hidden buffer
965
+ in zstream->state) */
966
+ z->flags |= ZSTREAM_FLAG_IN_STREAM;
967
+ break;
968
+ }
969
+
970
+ state = (int)(VALUE)rb_thread_call_with_gvl(zstream_expand_buffer_protect,
971
+ (void *)z);
972
+
973
+ if (state) {
974
+ err = Z_OK; /* buffer expanded but stream processing was stopped */
975
+ args->jump_state = state;
976
+ break;
977
+ }
978
+ }
979
+
980
+ return (void *)(VALUE)err;
981
+ }
982
+
983
+ /*
984
+ * There is no safe way to interrupt z->run->func().
985
+ */
986
+ static void
987
+ zstream_unblock_func(void *ptr)
988
+ {
989
+ struct zstream_run_args *args = (struct zstream_run_args *)ptr;
990
+
991
+ args->interrupt = 1;
992
+ }
993
+
827
994
  static void
828
995
  zstream_run(struct zstream *z, Bytef *src, long len, int flush)
829
996
  {
830
- uInt n;
997
+ struct zstream_run_args args;
831
998
  int err;
832
999
  volatile VALUE guard = Qnil;
833
1000
 
1001
+ args.z = z;
1002
+ args.flush = flush;
1003
+ args.interrupt = 0;
1004
+ args.jump_state = 0;
1005
+ args.stream_output = !ZSTREAM_IS_GZFILE(z) && rb_block_given_p();
1006
+
834
1007
  if (NIL_P(z->input) && len == 0) {
835
- z->stream.next_in = (Bytef*)"";
836
- z->stream.avail_in = 0;
1008
+ z->stream.next_in = (Bytef*)"";
1009
+ z->stream.avail_in = 0;
837
1010
  }
838
1011
  else {
839
- zstream_append_input(z, src, len);
840
- z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
841
- z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input));
842
- /* keep reference to `z->input' so as not to be garbage collected
843
- after zstream_reset_input() and prevent `z->stream.next_in'
844
- from dangling. */
845
- guard = z->input;
1012
+ zstream_append_input(z, src, len);
1013
+ z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
1014
+ z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input));
1015
+ /* keep reference to `z->input' so as not to be garbage collected
1016
+ after zstream_reset_input() and prevent `z->stream.next_in'
1017
+ from dangling. */
1018
+ guard = z->input;
846
1019
  }
847
1020
 
848
1021
  if (z->stream.avail_out == 0) {
849
- zstream_expand_buffer(z);
1022
+ zstream_expand_buffer(z);
850
1023
  }
851
1024
 
852
- for (;;) {
853
- /* VC allocates err and guard to same address. accessing err and guard
854
- in same scope prevents it. */
855
- RB_GC_GUARD(guard) = guard;
856
- n = z->stream.avail_out;
857
- err = z->func->run(&z->stream, flush);
858
- z->buf_filled += n - z->stream.avail_out;
859
- rb_thread_schedule();
860
-
861
- if (err == Z_STREAM_END) {
862
- z->flags &= ~ZSTREAM_FLAG_IN_STREAM;
863
- z->flags |= ZSTREAM_FLAG_FINISHED;
864
- break;
865
- }
866
- if (err != Z_OK) {
867
- if (flush != Z_FINISH && err == Z_BUF_ERROR
868
- && z->stream.avail_out > 0) {
869
- z->flags |= ZSTREAM_FLAG_IN_STREAM;
870
- break;
871
- }
872
- zstream_reset_input(z);
873
- if (z->stream.avail_in > 0) {
874
- zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
875
- }
876
- raise_zlib_error(err, z->stream.msg);
877
- }
878
- if (z->stream.avail_out > 0) {
879
- z->flags |= ZSTREAM_FLAG_IN_STREAM;
880
- break;
881
- }
882
- zstream_expand_buffer(z);
1025
+ loop:
1026
+ err = (int)(VALUE)rb_thread_call_without_gvl(zstream_run_func, (void *)&args,
1027
+ zstream_unblock_func, (void *)&args);
1028
+
1029
+ if (flush != Z_FINISH && err == Z_BUF_ERROR
1030
+ && z->stream.avail_out > 0) {
1031
+ z->flags |= ZSTREAM_FLAG_IN_STREAM;
883
1032
  }
884
1033
 
885
1034
  zstream_reset_input(z);
1035
+
1036
+ if (err != Z_OK && err != Z_STREAM_END) {
1037
+ if (z->stream.avail_in > 0) {
1038
+ zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
1039
+ }
1040
+ if (err == Z_NEED_DICT) {
1041
+ VALUE self = (VALUE)z->stream.opaque;
1042
+ if (self) {
1043
+ VALUE dicts = rb_ivar_get(self, id_dictionaries);
1044
+ VALUE dict = rb_hash_aref(dicts, rb_uint2inum(z->stream.adler));
1045
+ if (!NIL_P(dict)) {
1046
+ rb_inflate_set_dictionary(self, dict);
1047
+ goto loop;
1048
+ }
1049
+ }
1050
+ }
1051
+ raise_zlib_error(err, z->stream.msg);
1052
+ }
1053
+
886
1054
  if (z->stream.avail_in > 0) {
887
- zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
888
- guard = Qnil; /* prevent tail call to make guard effective */
1055
+ zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
1056
+ RB_GC_GUARD(guard) = Qnil; /* prevent tail call to make guard effective */
889
1057
  }
1058
+
1059
+ if (args.jump_state)
1060
+ rb_jump_tag(args.jump_state);
890
1061
  }
891
1062
 
892
1063
  static VALUE
893
1064
  zstream_sync(struct zstream *z, Bytef *src, long len)
894
1065
  {
895
- VALUE rest;
1066
+ /* VALUE rest; */
896
1067
  int err;
897
1068
 
898
1069
  if (!NIL_P(z->input)) {
899
- z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
900
- z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input));
901
- err = inflateSync(&z->stream);
902
- if (err == Z_OK) {
903
- zstream_discard_input(z,
904
- RSTRING_LEN(z->input) - z->stream.avail_in);
905
- zstream_append_input(z, src, len);
906
- return Qtrue;
907
- }
908
- zstream_reset_input(z);
909
- if (err != Z_DATA_ERROR) {
910
- rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in);
911
- raise_zlib_error(err, z->stream.msg);
912
- }
1070
+ z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
1071
+ z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input));
1072
+ err = inflateSync(&z->stream);
1073
+ if (err == Z_OK) {
1074
+ zstream_discard_input(z,
1075
+ RSTRING_LEN(z->input) - z->stream.avail_in);
1076
+ zstream_append_input(z, src, len);
1077
+ return Qtrue;
1078
+ }
1079
+ zstream_reset_input(z);
1080
+ if (err != Z_DATA_ERROR) {
1081
+ /* rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in); */
1082
+ raise_zlib_error(err, z->stream.msg);
1083
+ }
913
1084
  }
914
1085
 
915
1086
  if (len <= 0) return Qfalse;
@@ -918,12 +1089,12 @@ zstream_sync(struct zstream *z, Bytef *src, long len)
918
1089
  z->stream.avail_in = MAX_UINT(len);
919
1090
  err = inflateSync(&z->stream);
920
1091
  if (err == Z_OK) {
921
- zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
922
- return Qtrue;
1092
+ zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
1093
+ return Qtrue;
923
1094
  }
924
1095
  if (err != Z_DATA_ERROR) {
925
- rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in);
926
- raise_zlib_error(err, z->stream.msg);
1096
+ /* rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in); */
1097
+ raise_zlib_error(err, z->stream.msg);
927
1098
  }
928
1099
  return Qfalse;
929
1100
  }
@@ -940,16 +1111,16 @@ zstream_finalize(struct zstream *z)
940
1111
  {
941
1112
  int err = z->func->end(&z->stream);
942
1113
  if (err == Z_STREAM_ERROR)
943
- finalizer_warn("the stream state was inconsistent.");
1114
+ finalizer_warn("the stream state was inconsistent.");
944
1115
  if (err == Z_DATA_ERROR)
945
- finalizer_warn("the stream was freed prematurely.");
1116
+ finalizer_warn("the stream was freed prematurely.");
946
1117
  }
947
1118
 
948
1119
  static void
949
1120
  zstream_free(struct zstream *z)
950
1121
  {
951
1122
  if (ZSTREAM_IS_READY(z)) {
952
- zstream_finalize(z);
1123
+ zstream_finalize(z);
953
1124
  }
954
1125
  xfree(z);
955
1126
  }
@@ -961,8 +1132,9 @@ zstream_new(VALUE klass, const struct zstream_funcs *funcs)
961
1132
  struct zstream *z;
962
1133
 
963
1134
  obj = Data_Make_Struct(klass, struct zstream,
964
- zstream_mark, zstream_free, z);
1135
+ zstream_mark, zstream_free, z);
965
1136
  zstream_init(z, funcs);
1137
+ z->stream.opaque = (voidpf)obj;
966
1138
  return obj;
967
1139
  }
968
1140
 
@@ -976,7 +1148,7 @@ get_zstream(VALUE obj)
976
1148
 
977
1149
  Data_Get_Struct(obj, struct zstream, z);
978
1150
  if (!ZSTREAM_IS_READY(z)) {
979
- rb_raise(cZError, "stream is not ready");
1151
+ rb_raise(cZError, "stream is not ready");
980
1152
  }
981
1153
  return z;
982
1154
  }
@@ -1068,24 +1240,28 @@ rb_zstream_reset(VALUE obj)
1068
1240
  }
1069
1241
 
1070
1242
  /*
1071
- * Finishes the stream and flushes output buffer. See Zlib::Deflate#finish and
1072
- * Zlib::Inflate#finish for details of this behavior.
1243
+ * call-seq:
1244
+ * finish -> String
1245
+ * finish { |chunk| ... } -> nil
1246
+ *
1247
+ * Finishes the stream and flushes output buffer. If a block is given each
1248
+ * chunk is yielded to the block until the input buffer has been flushed to
1249
+ * the output buffer.
1073
1250
  */
1074
1251
  static VALUE
1075
1252
  rb_zstream_finish(VALUE obj)
1076
1253
  {
1077
1254
  struct zstream *z = get_zstream(obj);
1078
- VALUE dst;
1079
1255
 
1080
1256
  zstream_run(z, (Bytef*)"", 0, Z_FINISH);
1081
- dst = zstream_detach_buffer(z);
1082
1257
 
1083
- OBJ_INFECT(dst, obj);
1084
- return dst;
1258
+ return zstream_detach_buffer(z);
1085
1259
  }
1086
1260
 
1087
1261
  /*
1088
- * Flushes input buffer and returns all data in that buffer.
1262
+ * call-seq:
1263
+ * flush_next_in -> input
1264
+ *
1089
1265
  */
1090
1266
  static VALUE
1091
1267
  rb_zstream_flush_next_in(VALUE obj)
@@ -1100,18 +1276,22 @@ rb_zstream_flush_next_in(VALUE obj)
1100
1276
  }
1101
1277
 
1102
1278
  /*
1103
- * Flushes output buffer and returns all data in that buffer.
1279
+ * call-seq:
1280
+ * flush_next_out -> String
1281
+ * flush_next_out { |chunk| ... } -> nil
1282
+ *
1283
+ * Flushes output buffer and returns all data in that buffer. If a block is
1284
+ * given each chunk is yielded to the block until the current output buffer
1285
+ * has been flushed.
1104
1286
  */
1105
1287
  static VALUE
1106
1288
  rb_zstream_flush_next_out(VALUE obj)
1107
1289
  {
1108
1290
  struct zstream *z;
1109
- VALUE dst;
1110
1291
 
1111
1292
  Data_Get_Struct(obj, struct zstream, z);
1112
- dst = zstream_detach_buffer(z);
1113
- OBJ_INFECT(dst, obj);
1114
- return dst;
1293
+
1294
+ return zstream_detach_buffer(z);
1115
1295
  }
1116
1296
 
1117
1297
  /*
@@ -1188,7 +1368,7 @@ rb_zstream_data_type(VALUE obj)
1188
1368
  static VALUE
1189
1369
  rb_zstream_adler(VALUE obj)
1190
1370
  {
1191
- return rb_uint2inum(get_zstream(obj)->stream.adler);
1371
+ return rb_uint2inum(get_zstream(obj)->stream.adler);
1192
1372
  }
1193
1373
 
1194
1374
  /*
@@ -1241,60 +1421,73 @@ rb_deflate_s_allocate(VALUE klass)
1241
1421
  /*
1242
1422
  * Document-method: Zlib::Deflate.new
1243
1423
  *
1244
- * call-seq: Zlib::Deflate.new(level=nil, windowBits=nil, memlevel=nil, strategy=nil)
1424
+ * call-seq:
1425
+ * Zlib::Deflate.new(level=DEFAULT_COMPRESSION, window_bits=MAX_WBITS, mem_level=DEF_MEM_LEVEL, strategy=DEFAULT_STRATEGY)
1426
+ *
1427
+ * Creates a new deflate stream for compression. If a given argument is nil,
1428
+ * the default value of that argument is used.
1245
1429
  *
1246
- * == Arguments
1430
+ * The +level+ sets the compression level for the deflate stream between 0 (no
1431
+ * compression) and 9 (best compression. The following constants have been
1432
+ * defined to make code more readable:
1247
1433
  *
1248
- * +level+::
1249
- * An Integer compression level between
1250
- * BEST_SPEED and BEST_COMPRESSION
1251
- * +windowBits+::
1252
- * An Integer for the windowBits size. Should be
1253
- * in the range 8..15, larger values of this parameter
1254
- * result in better at the expense of memory usage.
1255
- * +memlevel+::
1256
- * Specifies how much memory should be allocated for
1257
- * the internal compression state.
1258
- * Between DEF_MEM_LEVEL and MAX_MEM_LEVEL
1259
- * +strategy+::
1260
- * A parameter to tune the compression algorithm. Use the
1261
- * DEFAULT_STRATEGY for normal data, FILTERED for data produced by a
1262
- * filter (or predictor), HUFFMAN_ONLY to force Huffman encoding only (no
1263
- * string match).
1434
+ * * Zlib::NO_COMPRESSION = 0
1435
+ * * Zlib::BEST_SPEED = 1
1436
+ * * Zlib::DEFAULT_COMPRESSION = 6
1437
+ * * Zlib::BEST_COMPRESSION = 9
1264
1438
  *
1265
- * == Description
1439
+ * The +window_bits+ sets the size of the history buffer and should be between
1440
+ * 8 and 15. Larger values of this parameter result in better compression at
1441
+ * the expense of memory usage.
1266
1442
  *
1267
- * Creates a new deflate stream for compression. See zlib.h for details of
1268
- * each argument. If an argument is nil, the default value of that argument is
1269
- * used.
1443
+ * The +mem_level+ specifies how much memory should be allocated for the
1444
+ * internal compression state. 1 uses minimum memory but is slow and reduces
1445
+ * compression ratio while 9 uses maximum memory for optimal speed. The
1446
+ * default value is 8. Two constants are defined:
1270
1447
  *
1448
+ * * Zlib::DEF_MEM_LEVEL
1449
+ * * Zlib::MAX_MEM_LEVEL
1271
1450
  *
1272
- * == examples
1451
+ * The +strategy+ sets the deflate compression strategy. The following
1452
+ * strategies are available:
1273
1453
  *
1274
- * === basic
1454
+ * Zlib::DEFAULT_STRATEGY:: For normal data
1455
+ * Zlib::FILTERED:: For data produced by a filter or predictor
1456
+ * Zlib::FIXED:: Prevents dynamic Huffman codes
1457
+ * Zlib::HUFFMAN_ONLY:: Prevents string matching
1458
+ * Zlib::RLE:: Designed for better compression of PNG image data
1275
1459
  *
1276
- * f = File.new("compressed.file","w+")
1277
- * #=> #<File:compressed.file>
1278
- * f << Zlib::Deflate.new().deflate(File.read("big.file"))
1279
- * #=> #<File:compressed.file>
1280
- * f.close
1281
- * #=> nil
1460
+ * See the constants for further description.
1282
1461
  *
1283
- * === a little more robust
1462
+ * == Examples
1284
1463
  *
1285
- * compressed_file = File.open("compressed.file", "w+")
1286
- * #=> #<File:compressed.file>
1287
- * zd = Zlib::Deflate.new(Zlib::BEST_COMPRESSION, 15, Zlib::MAX_MEM_LEVEL, Zlib::HUFFMAN_ONLY)
1288
- * #=> #<Zlib::Deflate:0x000000008610a0>
1289
- * compressed_file << zd.deflate(File.read("big.file"))
1290
- * #=> "\xD4z\xC6\xDE\b\xA1K\x1Ej\x8A ..."
1291
- * compressed_file.close
1292
- * #=> nil
1293
- * zd.close
1294
- * #=> nil
1464
+ * === Basic
1295
1465
  *
1296
- * (while this example will work, for best optimization the flags need to be reviewed for your specific function)
1466
+ * open "compressed.file", "w+" do |io|
1467
+ * io << Zlib::Deflate.new.deflate(File.read("big.file"))
1468
+ * end
1469
+ *
1470
+ * === Custom compression
1471
+ *
1472
+ * open "compressed.file", "w+" do |compressed_io|
1473
+ * deflate = Zlib::Deflate.new(Zlib::BEST_COMPRESSION,
1474
+ * Zlib::MAX_WBITS,
1475
+ * Zlib::MAX_MEM_LEVEL,
1476
+ * Zlib::HUFFMAN_ONLY)
1477
+ *
1478
+ * begin
1479
+ * open "big.file" do |big_io|
1480
+ * until big_io.eof? do
1481
+ * compressed_io << zd.deflate(big_io.read(16384))
1482
+ * end
1483
+ * end
1484
+ * ensure
1485
+ * deflate.close
1486
+ * end
1487
+ * end
1297
1488
  *
1489
+ * While this example will work, for best optimization review the flags for
1490
+ * your specific time, memory usage and output space requirements.
1298
1491
  */
1299
1492
  static VALUE
1300
1493
  rb_deflate_initialize(int argc, VALUE *argv, VALUE obj)
@@ -1307,10 +1500,10 @@ rb_deflate_initialize(int argc, VALUE *argv, VALUE obj)
1307
1500
  Data_Get_Struct(obj, struct zstream, z);
1308
1501
 
1309
1502
  err = deflateInit2(&z->stream, ARG_LEVEL(level), Z_DEFLATED,
1310
- ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel),
1311
- ARG_STRATEGY(strategy));
1503
+ ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel),
1504
+ ARG_STRATEGY(strategy));
1312
1505
  if (err != Z_OK) {
1313
- raise_zlib_error(err, z->stream.msg);
1506
+ raise_zlib_error(err, z->stream.msg);
1314
1507
  }
1315
1508
  ZSTREAM_READY(z);
1316
1509
 
@@ -1333,7 +1526,7 @@ rb_deflate_init_copy(VALUE self, VALUE orig)
1333
1526
 
1334
1527
  err = deflateCopy(&z1->stream, &z2->stream);
1335
1528
  if (err != Z_OK) {
1336
- raise_zlib_error(err, 0);
1529
+ raise_zlib_error(err, 0);
1337
1530
  }
1338
1531
  z1->input = NIL_P(z2->input) ? Qnil : rb_str_dup(z2->input);
1339
1532
  z1->buf = NIL_P(z2->buf) ? Qnil : rb_str_dup(z2->buf);
@@ -1356,19 +1549,19 @@ deflate_run(VALUE args)
1356
1549
  /*
1357
1550
  * Document-method: Zlib::Deflate.deflate
1358
1551
  *
1359
- * call-seq: Zlib.deflate(string[, level])
1360
- * Zlib::Deflate.deflate(string[, level])
1552
+ * call-seq:
1553
+ * Zlib.deflate(string[, level])
1554
+ * Zlib::Deflate.deflate(string[, level])
1361
1555
  *
1362
1556
  * Compresses the given +string+. Valid values of level are
1363
- * <tt>NO_COMPRESSION</tt>, <tt>BEST_SPEED</tt>,
1364
- * <tt>BEST_COMPRESSION</tt>, <tt>DEFAULT_COMPRESSION</tt>, and an
1365
- * integer from 0 to 9 (the default is 6).
1557
+ * Zlib::NO_COMPRESSION, Zlib::BEST_SPEED, Zlib::BEST_COMPRESSION,
1558
+ * Zlib::DEFAULT_COMPRESSION, or an integer from 0 to 9 (the default is 6).
1366
1559
  *
1367
1560
  * This method is almost equivalent to the following code:
1368
1561
  *
1369
1562
  * def deflate(string, level)
1370
1563
  * z = Zlib::Deflate.new(level)
1371
- * dst = z.deflate(string, Zlib::NO_FLUSH)
1564
+ * dst = z.deflate(string, Zlib::FINISH)
1372
1565
  * z.close
1373
1566
  * dst
1374
1567
  * end
@@ -1390,7 +1583,7 @@ rb_deflate_s_deflate(int argc, VALUE *argv, VALUE klass)
1390
1583
  zstream_init_deflate(&z);
1391
1584
  err = deflateInit(&z.stream, lev);
1392
1585
  if (err != Z_OK) {
1393
- raise_zlib_error(err, z.stream.msg);
1586
+ raise_zlib_error(err, z.stream.msg);
1394
1587
  }
1395
1588
  ZSTREAM_READY(&z);
1396
1589
 
@@ -1406,65 +1599,56 @@ static void
1406
1599
  do_deflate(struct zstream *z, VALUE src, int flush)
1407
1600
  {
1408
1601
  if (NIL_P(src)) {
1409
- zstream_run(z, (Bytef*)"", 0, Z_FINISH);
1410
- return;
1602
+ zstream_run(z, (Bytef*)"", 0, Z_FINISH);
1603
+ return;
1411
1604
  }
1412
1605
  StringValue(src);
1413
1606
  if (flush != Z_NO_FLUSH || RSTRING_LEN(src) > 0) { /* prevent BUF_ERROR */
1414
- zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), flush);
1607
+ zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), flush);
1415
1608
  }
1416
1609
  }
1417
1610
 
1418
1611
  /*
1419
- * Document-method: Zlib.deflate
1612
+ * Document-method: Zlib::Deflate#deflate
1420
1613
  *
1421
- * call-seq: deflate(string[, flush])
1422
- *
1423
- * == Arguments
1424
- *
1425
- * +string+::
1426
- * String
1427
- *
1428
- * +flush+::
1429
- * Integer representing a flush code. Either NO_FLUSH,
1430
- * SYNC_FLUSH, FULL_FLUSH, or FINISH. See zlib.h for details.
1431
- * Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
1432
- * decide how much data to accumulate before producing output, in order to
1433
- * maximize compression.
1434
- *
1435
- * == Description
1614
+ * call-seq:
1615
+ * z.deflate(string, flush = Zlib::NO_FLUSH) -> String
1616
+ * z.deflate(string, flush = Zlib::NO_FLUSH) { |chunk| ... } -> nil
1436
1617
  *
1437
1618
  * Inputs +string+ into the deflate stream and returns the output from the
1438
1619
  * stream. On calling this method, both the input and the output buffers of
1439
- * the stream are flushed.
1440
- *
1441
- * If +string+ is nil, this method finishes the
1620
+ * the stream are flushed. If +string+ is nil, this method finishes the
1442
1621
  * stream, just like Zlib::ZStream#finish.
1443
1622
  *
1444
- * == Usage
1623
+ * If a block is given consecutive deflated chunks from the +string+ are
1624
+ * yielded to the block and +nil+ is returned.
1625
+ *
1626
+ * The +flush+ parameter specifies the flush mode. The following constants
1627
+ * may be used:
1445
1628
  *
1446
- * comp = Zlib.deflate(File.read("big.file"))
1447
- * or
1448
- * comp = Zlib.deflate(File.read("big.file"), Zlib::FULL_FLUSH)
1629
+ * Zlib::NO_FLUSH:: The default
1630
+ * Zlib::SYNC_FLUSH:: Flushes the output to a byte boundary
1631
+ * Zlib::FULL_FLUSH:: SYNC_FLUSH + resets the compression state
1632
+ * Zlib::FINISH:: Pending input is processed, pending output is flushed.
1633
+ *
1634
+ * See the constants for further description.
1449
1635
  *
1450
1636
  */
1451
1637
  static VALUE
1452
1638
  rb_deflate_deflate(int argc, VALUE *argv, VALUE obj)
1453
1639
  {
1454
1640
  struct zstream *z = get_zstream(obj);
1455
- VALUE src, flush, dst;
1641
+ VALUE src, flush;
1456
1642
 
1457
1643
  rb_scan_args(argc, argv, "11", &src, &flush);
1458
1644
  OBJ_INFECT(obj, src);
1459
1645
  do_deflate(z, src, ARG_FLUSH(flush));
1460
- dst = zstream_detach_buffer(z);
1461
1646
 
1462
- OBJ_INFECT(dst, obj);
1463
- return dst;
1647
+ return zstream_detach_buffer(z);
1464
1648
  }
1465
1649
 
1466
1650
  /*
1467
- * Document-method: Zlib::Deflate.<<
1651
+ * Document-method: Zlib::Deflate#<<
1468
1652
  *
1469
1653
  * call-seq: << string
1470
1654
  *
@@ -1483,31 +1667,32 @@ rb_deflate_addstr(VALUE obj, VALUE src)
1483
1667
  /*
1484
1668
  * Document-method: Zlib::Deflate#flush
1485
1669
  *
1486
- * call-seq: flush(flush)
1670
+ * call-seq:
1671
+ * flush(flush = Zlib::SYNC_FLUSH) -> String
1672
+ * flush(flush = Zlib::SYNC_FLUSH) { |chunk| ... } -> nil
1487
1673
  *
1488
- * This method is equivalent to <tt>deflate('', flush)</tt>. If flush is omitted,
1489
- * <tt>SYNC_FLUSH</tt> is used as flush. This method is just provided
1490
- * to improve the readability of your Ruby program.
1491
- *
1492
- * Please visit your zlib.h for a deeper detail on NO_FLUSH, SYNC_FLUSH, FULL_FLUSH, and FINISH
1674
+ * This method is equivalent to <tt>deflate('', flush)</tt>. This method is
1675
+ * just provided to improve the readability of your Ruby program. If a block
1676
+ * is given chunks of deflate output are yielded to the block until the buffer
1677
+ * is flushed.
1493
1678
  *
1679
+ * See Zlib::Deflate#deflate for detail on the +flush+ constants NO_FLUSH,
1680
+ * SYNC_FLUSH, FULL_FLUSH and FINISH.
1494
1681
  */
1495
1682
  static VALUE
1496
1683
  rb_deflate_flush(int argc, VALUE *argv, VALUE obj)
1497
1684
  {
1498
1685
  struct zstream *z = get_zstream(obj);
1499
- VALUE v_flush, dst;
1686
+ VALUE v_flush;
1500
1687
  int flush;
1501
1688
 
1502
1689
  rb_scan_args(argc, argv, "01", &v_flush);
1503
1690
  flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
1504
1691
  if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
1505
- zstream_run(z, (Bytef*)"", 0, flush);
1692
+ zstream_run(z, (Bytef*)"", 0, flush);
1506
1693
  }
1507
- dst = zstream_detach_buffer(z);
1508
1694
 
1509
- OBJ_INFECT(dst, obj);
1510
- return dst;
1695
+ return zstream_detach_buffer(z);
1511
1696
  }
1512
1697
 
1513
1698
  /*
@@ -1515,18 +1700,11 @@ rb_deflate_flush(int argc, VALUE *argv, VALUE obj)
1515
1700
  *
1516
1701
  * call-seq: params(level, strategy)
1517
1702
  *
1518
- * Changes the parameters of the deflate stream. See zlib.h for details. The
1519
- * output from the stream by changing the params is preserved in output
1520
- * buffer.
1703
+ * Changes the parameters of the deflate stream to allow changes between
1704
+ * different types of data that require different types of compression. Any
1705
+ * unprocessed data is flushed before changing the params.
1521
1706
  *
1522
- * +level+::
1523
- * An Integer compression level between
1524
- * BEST_SPEED and BEST_COMPRESSION
1525
- * +strategy+::
1526
- * A parameter to tune the compression algorithm. Use the
1527
- * DEFAULT_STRATEGY for normal data, FILTERED for data produced by a
1528
- * filter (or predictor), HUFFMAN_ONLY to force Huffman encoding only (no
1529
- * string match).
1707
+ * See Zlib::Deflate.new for a description of +level+ and +strategy+.
1530
1708
  *
1531
1709
  */
1532
1710
  static VALUE
@@ -1544,14 +1722,14 @@ rb_deflate_params(VALUE obj, VALUE v_level, VALUE v_strategy)
1544
1722
  err = deflateParams(&z->stream, level, strategy);
1545
1723
  z->buf_filled += n - z->stream.avail_out;
1546
1724
  while (err == Z_BUF_ERROR) {
1547
- rb_warning("deflateParams() returned Z_BUF_ERROR");
1548
- zstream_expand_buffer(z);
1549
- n = z->stream.avail_out;
1550
- err = deflateParams(&z->stream, level, strategy);
1551
- z->buf_filled += n - z->stream.avail_out;
1725
+ rb_warning("deflateParams() returned Z_BUF_ERROR");
1726
+ zstream_expand_buffer(z);
1727
+ n = z->stream.avail_out;
1728
+ err = deflateParams(&z->stream, level, strategy);
1729
+ z->buf_filled += n - z->stream.avail_out;
1552
1730
  }
1553
1731
  if (err != Z_OK) {
1554
- raise_zlib_error(err, z->stream.msg);
1732
+ raise_zlib_error(err, z->stream.msg);
1555
1733
  }
1556
1734
 
1557
1735
  return Qnil;
@@ -1581,9 +1759,9 @@ rb_deflate_set_dictionary(VALUE obj, VALUE dic)
1581
1759
  OBJ_INFECT(obj, dic);
1582
1760
  StringValue(src);
1583
1761
  err = deflateSetDictionary(&z->stream,
1584
- (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
1762
+ (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
1585
1763
  if (err != Z_OK) {
1586
- raise_zlib_error(err, z->stream.msg);
1764
+ raise_zlib_error(err, z->stream.msg);
1587
1765
  }
1588
1766
 
1589
1767
  return dic;
@@ -1600,52 +1778,57 @@ rb_deflate_set_dictionary(VALUE obj, VALUE dic)
1600
1778
  * dup) itself.
1601
1779
  */
1602
1780
 
1603
-
1604
-
1605
1781
  static VALUE
1606
1782
  rb_inflate_s_allocate(VALUE klass)
1607
1783
  {
1608
- return zstream_inflate_new(klass);
1784
+ VALUE inflate = zstream_inflate_new(klass);
1785
+ rb_ivar_set(inflate, id_dictionaries, rb_hash_new());
1786
+ return inflate;
1609
1787
  }
1610
1788
 
1611
1789
  /*
1612
1790
  * Document-method: Zlib::Inflate.new
1613
1791
  *
1614
- * call-seq: Zlib::Inflate.new(window_bits)
1792
+ * call-seq:
1793
+ * Zlib::Inflate.new(window_bits = Zlib::MAX_WBITS)
1615
1794
  *
1616
- * == Arguments
1795
+ * Creates a new inflate stream for decompression. +window_bits+ sets the
1796
+ * size of the history buffer and can have the following values:
1617
1797
  *
1618
- * +windowBits+::
1619
- * An Integer for the windowBits size. Should be
1620
- * in the range 8..15, larger values of this parameter
1621
- * result in better at the expense of memory usage.
1798
+ * 0::
1799
+ * Have inflate use the window size from the zlib header of the compressed
1800
+ * stream.
1622
1801
  *
1623
- * == Description
1802
+ * (8..15)
1803
+ * Overrides the window size of the inflate header in the compressed stream.
1804
+ * The window size must be greater than or equal to the window size of the
1805
+ * compressed stream.
1624
1806
  *
1625
- * Creates a new inflate stream for decompression. See zlib.h for details
1626
- * of the argument. If +window_bits+ is +nil+, the default value is used.
1627
- *
1628
- * == Example
1807
+ * Greater than 15::
1808
+ * Add 32 to window_bits to enable zlib and gzip decoding with automatic
1809
+ * header detection, or add 16 to decode only the gzip format (a
1810
+ * Zlib::DataError will be raised for a non-gzip stream).
1629
1811
  *
1630
- * cf = File.open("compressed.file")
1631
- * ucf = File.open("uncompressed.file", "w+")
1632
- * zi = Zlib::Inflate.new(Zlib::MAX_WBITS)
1812
+ * (-8..-15)::
1813
+ * Enables raw deflate mode which will not generate a check value, and will
1814
+ * not look for any check values for comparison at the end of the stream.
1633
1815
  *
1634
- * ucf << zi.inflate(cf.read)
1816
+ * This is for use with other formats that use the deflate compressed data
1817
+ * format such as zip which provide their own check values.
1635
1818
  *
1636
- * ucf.close
1637
- * zi.close
1638
- * cf.close
1819
+ * == Example
1639
1820
  *
1640
- * or
1821
+ * open "compressed.file" do |compressed_io|
1822
+ * zi = Zlib::Inflate.new(Zlib::MAX_WBITS + 32)
1641
1823
  *
1642
- * File.open("compressed.file") {|cf|
1643
- * zi = Zlib::Inflate.new
1644
- * File.open("uncompressed.file", "w+") {|ucf|
1645
- * ucf << zi.inflate(cf.read)
1646
- * }
1647
- * zi.close
1648
- * }
1824
+ * begin
1825
+ * open "uncompressed.file", "w+" do |uncompressed_io|
1826
+ * uncompressed_io << zi.inflate(compressed_io.read)
1827
+ * end
1828
+ * ensure
1829
+ * zi.close
1830
+ * end
1831
+ * end
1649
1832
  *
1650
1833
  */
1651
1834
  static VALUE
@@ -1660,7 +1843,7 @@ rb_inflate_initialize(int argc, VALUE *argv, VALUE obj)
1660
1843
 
1661
1844
  err = inflateInit2(&z->stream, ARG_WBITS(wbits));
1662
1845
  if (err != Z_OK) {
1663
- raise_zlib_error(err, z->stream.msg);
1846
+ raise_zlib_error(err, z->stream.msg);
1664
1847
  }
1665
1848
  ZSTREAM_READY(z);
1666
1849
 
@@ -1679,9 +1862,11 @@ inflate_run(VALUE args)
1679
1862
  }
1680
1863
 
1681
1864
  /*
1682
- * Document-method: Zlib::Inflate.inflate
1865
+ * Document-method: Zlib::inflate
1683
1866
  *
1684
- * call-seq: Zlib::Inflate.inflate(string)
1867
+ * call-seq:
1868
+ * Zlib.inflate(string)
1869
+ * Zlib::Inflate.inflate(string)
1685
1870
  *
1686
1871
  * Decompresses +string+. Raises a Zlib::NeedDict exception if a preset
1687
1872
  * dictionary is needed for decompression.
@@ -1710,7 +1895,7 @@ rb_inflate_s_inflate(VALUE obj, VALUE src)
1710
1895
  zstream_init_inflate(&z);
1711
1896
  err = inflateInit(&z.stream);
1712
1897
  if (err != Z_OK) {
1713
- raise_zlib_error(err, z.stream.msg);
1898
+ raise_zlib_error(err, z.stream.msg);
1714
1899
  }
1715
1900
  ZSTREAM_READY(&z);
1716
1901
 
@@ -1726,28 +1911,68 @@ static void
1726
1911
  do_inflate(struct zstream *z, VALUE src)
1727
1912
  {
1728
1913
  if (NIL_P(src)) {
1729
- zstream_run(z, (Bytef*)"", 0, Z_FINISH);
1730
- return;
1914
+ zstream_run(z, (Bytef*)"", 0, Z_FINISH);
1915
+ return;
1731
1916
  }
1732
1917
  StringValue(src);
1733
- if (RSTRING_LEN(src) > 0) { /* prevent Z_BUF_ERROR */
1734
- zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_SYNC_FLUSH);
1918
+ if (RSTRING_LEN(src) > 0 || z->stream.avail_in > 0) { /* prevent Z_BUF_ERROR */
1919
+ zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_SYNC_FLUSH);
1735
1920
  }
1736
1921
  }
1737
1922
 
1923
+ /* Document-method: Zlib::Inflate#add_dictionary
1924
+ *
1925
+ * call-seq: add_dictionary(string)
1926
+ *
1927
+ * Provide the inflate stream with a dictionary that may be required in the
1928
+ * future. Multiple dictionaries may be provided. The inflate stream will
1929
+ * automatically choose the correct user-provided dictionary based on the
1930
+ * stream's required dictionary.
1931
+ */
1932
+ static VALUE
1933
+ rb_inflate_add_dictionary(VALUE obj, VALUE dictionary) {
1934
+ VALUE dictionaries = rb_ivar_get(obj, id_dictionaries);
1935
+ VALUE checksum = do_checksum(1, &dictionary, adler32);
1936
+
1937
+ rb_hash_aset(dictionaries, checksum, dictionary);
1938
+
1939
+ return obj;
1940
+ }
1941
+
1738
1942
  /*
1739
1943
  * Document-method: Zlib::Inflate#inflate
1740
1944
  *
1741
- * call-seq: inflate(string)
1945
+ * call-seq:
1946
+ * inflate(deflate_string) -> String
1947
+ * inflate(deflate_string) { |chunk| ... } -> nil
1948
+ *
1949
+ * Inputs +deflate_string+ into the inflate stream and returns the output from
1950
+ * the stream. Calling this method, both the input and the output buffer of
1951
+ * the stream are flushed. If string is +nil+, this method finishes the
1952
+ * stream, just like Zlib::ZStream#finish.
1742
1953
  *
1743
- * Inputs +string+ into the inflate stream and returns the output from the
1744
- * stream. Calling this method, both the input and the output buffer of the
1745
- * stream are flushed. If string is +nil+, this method finishes the stream,
1746
- * just like Zlib::ZStream#finish.
1954
+ * If a block is given consecutive inflated chunks from the +deflate_string+
1955
+ * are yielded to the block and +nil+ is returned.
1747
1956
  *
1748
1957
  * Raises a Zlib::NeedDict exception if a preset dictionary is needed to
1749
1958
  * decompress. Set the dictionary by Zlib::Inflate#set_dictionary and then
1750
- * call this method again with an empty string. (<i>???</i>)
1959
+ * call this method again with an empty string to flush the stream:
1960
+ *
1961
+ * inflater = Zlib::Inflate.new
1962
+ *
1963
+ * begin
1964
+ * out = inflater.inflate compressed
1965
+ * rescue Zlib::NeedDict
1966
+ * # ensure the dictionary matches the stream's required dictionary
1967
+ * raise unless inflater.adler == Zlib.adler32(dictionary)
1968
+ *
1969
+ * inflater.set_dictionary dictionary
1970
+ * inflater.inflate ''
1971
+ * end
1972
+ *
1973
+ * # ...
1974
+ *
1975
+ * inflater.close
1751
1976
  *
1752
1977
  * See also Zlib::Inflate.new
1753
1978
  */
@@ -1760,24 +1985,24 @@ rb_inflate_inflate(VALUE obj, VALUE src)
1760
1985
  OBJ_INFECT(obj, src);
1761
1986
 
1762
1987
  if (ZSTREAM_IS_FINISHED(z)) {
1763
- if (NIL_P(src)) {
1764
- dst = zstream_detach_buffer(z);
1765
- }
1766
- else {
1767
- StringValue(src);
1768
- zstream_append_buffer2(z, src);
1769
- dst = rb_str_new(0, 0);
1770
- }
1988
+ if (NIL_P(src)) {
1989
+ dst = zstream_detach_buffer(z);
1990
+ }
1991
+ else {
1992
+ StringValue(src);
1993
+ zstream_append_buffer2(z, src);
1994
+ dst = rb_str_new(0, 0);
1995
+ OBJ_INFECT(dst, obj);
1996
+ }
1771
1997
  }
1772
1998
  else {
1773
- do_inflate(z, src);
1774
- dst = zstream_detach_buffer(z);
1775
- if (ZSTREAM_IS_FINISHED(z)) {
1776
- zstream_passthrough_input(z);
1777
- }
1999
+ do_inflate(z, src);
2000
+ dst = zstream_detach_buffer(z);
2001
+ if (ZSTREAM_IS_FINISHED(z)) {
2002
+ zstream_passthrough_input(z);
2003
+ }
1778
2004
  }
1779
2005
 
1780
- OBJ_INFECT(dst, obj);
1781
2006
  return dst;
1782
2007
  }
1783
2008
 
@@ -1796,16 +2021,16 @@ rb_inflate_addstr(VALUE obj, VALUE src)
1796
2021
  OBJ_INFECT(obj, src);
1797
2022
 
1798
2023
  if (ZSTREAM_IS_FINISHED(z)) {
1799
- if (!NIL_P(src)) {
1800
- StringValue(src);
1801
- zstream_append_buffer2(z, src);
1802
- }
2024
+ if (!NIL_P(src)) {
2025
+ StringValue(src);
2026
+ zstream_append_buffer2(z, src);
2027
+ }
1803
2028
  }
1804
2029
  else {
1805
- do_inflate(z, src);
1806
- if (ZSTREAM_IS_FINISHED(z)) {
1807
- zstream_passthrough_input(z);
1808
- }
2030
+ do_inflate(z, src);
2031
+ if (ZSTREAM_IS_FINISHED(z)) {
2032
+ zstream_passthrough_input(z);
2033
+ }
1809
2034
  }
1810
2035
 
1811
2036
  return obj;
@@ -1844,10 +2069,10 @@ rb_inflate_sync_point_p(VALUE obj)
1844
2069
 
1845
2070
  err = inflateSyncPoint(&z->stream);
1846
2071
  if (err == 1) {
1847
- return Qtrue;
2072
+ return Qtrue;
1848
2073
  }
1849
2074
  if (err != Z_OK) {
1850
- raise_zlib_error(err, z->stream.msg);
2075
+ raise_zlib_error(err, z->stream.msg);
1851
2076
  }
1852
2077
  return Qfalse;
1853
2078
  }
@@ -1869,9 +2094,9 @@ rb_inflate_set_dictionary(VALUE obj, VALUE dic)
1869
2094
  OBJ_INFECT(obj, dic);
1870
2095
  StringValue(src);
1871
2096
  err = inflateSetDictionary(&z->stream,
1872
- (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
2097
+ (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
1873
2098
  if (err != Z_OK) {
1874
- raise_zlib_error(err, z->stream.msg);
2099
+ raise_zlib_error(err, z->stream.msg);
1875
2100
  }
1876
2101
 
1877
2102
  return dic;
@@ -1979,13 +2204,13 @@ gzfile_free(struct gzfile *gz)
1979
2204
  struct zstream *z = &gz->z;
1980
2205
 
1981
2206
  if (ZSTREAM_IS_READY(z)) {
1982
- if (z->func == &deflate_funcs) {
1983
- finalizer_warn("Zlib::GzipWriter object must be closed explicitly.");
1984
- }
1985
- zstream_finalize(z);
2207
+ if (z->func == &deflate_funcs) {
2208
+ finalizer_warn("Zlib::GzipWriter object must be closed explicitly.");
2209
+ }
2210
+ zstream_finalize(z);
1986
2211
  }
1987
2212
  if (gz->cbuf) {
1988
- xfree(gz->cbuf);
2213
+ xfree(gz->cbuf);
1989
2214
  }
1990
2215
  xfree(gz);
1991
2216
  }
@@ -2001,6 +2226,7 @@ gzfile_new(klass, funcs, endfunc)
2001
2226
 
2002
2227
  obj = Data_Make_Struct(klass, struct gzfile, gzfile_mark, gzfile_free, gz);
2003
2228
  zstream_init(&gz->z, funcs);
2229
+ gz->z.flags |= ZSTREAM_FLAG_GZFILE;
2004
2230
  gz->io = Qnil;
2005
2231
  gz->level = 0;
2006
2232
  gz->mtime = 0;
@@ -2033,11 +2259,10 @@ gzfile_reset(struct gzfile *gz)
2033
2259
  gz->lineno = 0;
2034
2260
  gz->ungetc = 0;
2035
2261
  /* TODO: Encodings
2036
- *
2037
2262
  if (gz->ec) {
2038
- rb_econv_close(gz->ec);
2039
- gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
2040
- gz->ecflags, gz->ecopts);
2263
+ rb_econv_close(gz->ec);
2264
+ gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
2265
+ gz->ecflags, gz->ecopts);
2041
2266
  }
2042
2267
  */
2043
2268
  }
@@ -2052,7 +2277,7 @@ gzfile_close(struct gzfile *gz, int closeflag)
2052
2277
  gz->orig_name = Qnil;
2053
2278
  gz->comment = Qnil;
2054
2279
  if (closeflag && rb_respond_to(io, id_close)) {
2055
- rb_funcall(io, id_close, 0);
2280
+ rb_funcall(io, id_close, 0);
2056
2281
  }
2057
2282
  }
2058
2283
 
@@ -2062,12 +2287,12 @@ gzfile_write_raw(struct gzfile *gz)
2062
2287
  VALUE str;
2063
2288
 
2064
2289
  if (gz->z.buf_filled > 0) {
2065
- str = zstream_detach_buffer(&gz->z);
2066
- OBJ_TAINT(str); /* for safe */
2067
- rb_funcall(gz->io, id_write, 1, str);
2068
- if ((gz->z.flags & GZFILE_FLAG_SYNC)
2069
- && rb_respond_to(gz->io, id_flush))
2070
- rb_funcall(gz->io, id_flush, 0);
2290
+ str = zstream_detach_buffer(&gz->z);
2291
+ OBJ_TAINT(str); /* for safe */
2292
+ rb_funcall(gz->io, id_write, 1, str);
2293
+ if ((gz->z.flags & GZFILE_FLAG_SYNC)
2294
+ && rb_respond_to(gz->io, id_flush))
2295
+ rb_funcall(gz->io, id_flush, 0);
2071
2296
  }
2072
2297
  }
2073
2298
 
@@ -2110,9 +2335,9 @@ gzfile_read_raw_ensure(struct gzfile *gz, long size)
2110
2335
  VALUE str;
2111
2336
 
2112
2337
  while (NIL_P(gz->z.input) || RSTRING_LEN(gz->z.input) < size) {
2113
- str = gzfile_read_raw(gz);
2114
- if (NIL_P(str)) return 0;
2115
- zstream_append_input2(&gz->z, str);
2338
+ str = gzfile_read_raw(gz);
2339
+ if (NIL_P(str)) return 0;
2340
+ zstream_append_input2(&gz->z, str);
2116
2341
  }
2117
2342
  return 1;
2118
2343
  }
@@ -2124,15 +2349,15 @@ gzfile_read_raw_until_zero(struct gzfile *gz, long offset)
2124
2349
  char *p;
2125
2350
 
2126
2351
  for (;;) {
2127
- p = memchr(RSTRING_PTR(gz->z.input) + offset, '\0',
2128
- RSTRING_LEN(gz->z.input) - offset);
2129
- if (p) break;
2130
- str = gzfile_read_raw(gz);
2131
- if (NIL_P(str)) {
2132
- rb_raise(cGzError, "unexpected end of file");
2133
- }
2134
- offset = RSTRING_LEN(gz->z.input);
2135
- zstream_append_input2(&gz->z, str);
2352
+ p = memchr(RSTRING_PTR(gz->z.input) + offset, '\0',
2353
+ RSTRING_LEN(gz->z.input) - offset);
2354
+ if (p) break;
2355
+ str = gzfile_read_raw(gz);
2356
+ if (NIL_P(str)) {
2357
+ rb_raise(cGzError, "unexpected end of file");
2358
+ }
2359
+ offset = RSTRING_LEN(gz->z.input);
2360
+ zstream_append_input2(&gz->z, str);
2136
2361
  }
2137
2362
  return p;
2138
2363
  }
@@ -2171,7 +2396,7 @@ gzfile_raise(struct gzfile *gz, VALUE klass, const char *message)
2171
2396
  {
2172
2397
  VALUE exc = rb_exc_new2(klass, message);
2173
2398
  if (!NIL_P(gz->z.input)) {
2174
- rb_ivar_set(exc, id_input, rb_str_dup(gz->z.input));
2399
+ rb_ivar_set(exc, id_input, rb_str_resurrect(gz->z.input));
2175
2400
  }
2176
2401
  rb_exc_raise(exc);
2177
2402
  }
@@ -2188,10 +2413,10 @@ gzfile_error_inspect(VALUE error)
2188
2413
  VALUE input = rb_attr_get(error, id_input);
2189
2414
 
2190
2415
  if (!NIL_P(input)) {
2191
- rb_str_resize(str, RSTRING_LEN(str)-1);
2192
- rb_str_cat2(str, ", input=");
2193
- rb_str_append(str, rb_str_inspect(input));
2194
- rb_str_cat2(str, ">");
2416
+ rb_str_resize(str, RSTRING_LEN(str)-1);
2417
+ rb_str_cat2(str, ", input=");
2418
+ rb_str_append(str, rb_str_inspect(input));
2419
+ rb_str_cat2(str, ">");
2195
2420
  }
2196
2421
  return str;
2197
2422
  }
@@ -2203,20 +2428,20 @@ gzfile_make_header(struct gzfile *gz)
2203
2428
  unsigned char flags = 0, extraflags = 0;
2204
2429
 
2205
2430
  if (!NIL_P(gz->orig_name)) {
2206
- flags |= GZ_FLAG_ORIG_NAME;
2431
+ flags |= GZ_FLAG_ORIG_NAME;
2207
2432
  }
2208
2433
  if (!NIL_P(gz->comment)) {
2209
- flags |= GZ_FLAG_COMMENT;
2434
+ flags |= GZ_FLAG_COMMENT;
2210
2435
  }
2211
2436
  if (gz->mtime == 0) {
2212
- gz->mtime = time(0);
2437
+ gz->mtime = time(0);
2213
2438
  }
2214
2439
 
2215
2440
  if (gz->level == Z_BEST_SPEED) {
2216
- extraflags |= GZ_EXTRAFLAG_FAST;
2441
+ extraflags |= GZ_EXTRAFLAG_FAST;
2217
2442
  }
2218
2443
  else if (gz->level == Z_BEST_COMPRESSION) {
2219
- extraflags |= GZ_EXTRAFLAG_SLOW;
2444
+ extraflags |= GZ_EXTRAFLAG_SLOW;
2220
2445
  }
2221
2446
 
2222
2447
  buf[0] = GZ_MAGIC1;
@@ -2229,12 +2454,12 @@ gzfile_make_header(struct gzfile *gz)
2229
2454
  zstream_append_buffer(&gz->z, buf, sizeof(buf));
2230
2455
 
2231
2456
  if (!NIL_P(gz->orig_name)) {
2232
- zstream_append_buffer2(&gz->z, gz->orig_name);
2233
- zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
2457
+ zstream_append_buffer2(&gz->z, gz->orig_name);
2458
+ zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
2234
2459
  }
2235
2460
  if (!NIL_P(gz->comment)) {
2236
- zstream_append_buffer2(&gz->z, gz->comment);
2237
- zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
2461
+ zstream_append_buffer2(&gz->z, gz->comment);
2462
+ zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
2238
2463
  }
2239
2464
 
2240
2465
  gz->z.flags |= GZFILE_FLAG_HEADER_FINISHED;
@@ -2259,37 +2484,37 @@ gzfile_read_header(struct gzfile *gz)
2259
2484
  char flags, *p;
2260
2485
 
2261
2486
  if (!gzfile_read_raw_ensure(gz, 10)) { /* 10 is the size of gzip header */
2262
- gzfile_raise(gz, cGzError, "not in gzip format");
2487
+ gzfile_raise(gz, cGzError, "not in gzip format");
2263
2488
  }
2264
2489
 
2265
2490
  head = (unsigned char*)RSTRING_PTR(gz->z.input);
2266
2491
 
2267
2492
  if (head[0] != GZ_MAGIC1 || head[1] != GZ_MAGIC2) {
2268
- gzfile_raise(gz, cGzError, "not in gzip format");
2493
+ gzfile_raise(gz, cGzError, "not in gzip format");
2269
2494
  }
2270
2495
  if (head[2] != GZ_METHOD_DEFLATE) {
2271
- rb_raise(cGzError, "unsupported compression method %d", head[2]);
2496
+ rb_raise(cGzError, "unsupported compression method %d", head[2]);
2272
2497
  }
2273
2498
 
2274
2499
  flags = head[3];
2275
2500
  if (flags & GZ_FLAG_MULTIPART) {
2276
- rb_raise(cGzError, "multi-part gzip file is not supported");
2501
+ rb_raise(cGzError, "multi-part gzip file is not supported");
2277
2502
  }
2278
2503
  else if (flags & GZ_FLAG_ENCRYPT) {
2279
- rb_raise(cGzError, "encrypted gzip file is not supported");
2504
+ rb_raise(cGzError, "encrypted gzip file is not supported");
2280
2505
  }
2281
2506
  else if (flags & GZ_FLAG_UNKNOWN_MASK) {
2282
- rb_raise(cGzError, "unknown flags 0x%02x", flags);
2507
+ rb_raise(cGzError, "unknown flags 0x%02x", flags);
2283
2508
  }
2284
2509
 
2285
2510
  if (head[8] & GZ_EXTRAFLAG_FAST) {
2286
- gz->level = Z_BEST_SPEED;
2511
+ gz->level = Z_BEST_SPEED;
2287
2512
  }
2288
2513
  else if (head[8] & GZ_EXTRAFLAG_SLOW) {
2289
- gz->level = Z_BEST_COMPRESSION;
2514
+ gz->level = Z_BEST_COMPRESSION;
2290
2515
  }
2291
2516
  else {
2292
- gz->level = Z_DEFAULT_COMPRESSION;
2517
+ gz->level = Z_DEFAULT_COMPRESSION;
2293
2518
  }
2294
2519
 
2295
2520
  gz->mtime = gzfile_get32(&head[4]);
@@ -2297,38 +2522,38 @@ gzfile_read_header(struct gzfile *gz)
2297
2522
  zstream_discard_input(&gz->z, 10);
2298
2523
 
2299
2524
  if (flags & GZ_FLAG_EXTRA) {
2300
- if (!gzfile_read_raw_ensure(gz, 2)) {
2301
- rb_raise(cGzError, "unexpected end of file");
2302
- }
2303
- len = gzfile_get16((Bytef*)RSTRING_PTR(gz->z.input));
2304
- if (!gzfile_read_raw_ensure(gz, 2 + len)) {
2305
- rb_raise(cGzError, "unexpected end of file");
2306
- }
2307
- zstream_discard_input(&gz->z, 2 + len);
2525
+ if (!gzfile_read_raw_ensure(gz, 2)) {
2526
+ rb_raise(cGzError, "unexpected end of file");
2527
+ }
2528
+ len = gzfile_get16((Bytef*)RSTRING_PTR(gz->z.input));
2529
+ if (!gzfile_read_raw_ensure(gz, 2 + len)) {
2530
+ rb_raise(cGzError, "unexpected end of file");
2531
+ }
2532
+ zstream_discard_input(&gz->z, 2 + len);
2308
2533
  }
2309
2534
  if (flags & GZ_FLAG_ORIG_NAME) {
2310
- if (!gzfile_read_raw_ensure(gz, 1)) {
2311
- rb_raise(cGzError, "unexpected end of file");
2312
- }
2313
- p = gzfile_read_raw_until_zero(gz, 0);
2314
- len = p - RSTRING_PTR(gz->z.input);
2315
- gz->orig_name = rb_str_new(RSTRING_PTR(gz->z.input), len);
2316
- OBJ_TAINT(gz->orig_name); /* for safe */
2317
- zstream_discard_input(&gz->z, len + 1);
2535
+ if (!gzfile_read_raw_ensure(gz, 1)) {
2536
+ rb_raise(cGzError, "unexpected end of file");
2537
+ }
2538
+ p = gzfile_read_raw_until_zero(gz, 0);
2539
+ len = p - RSTRING_PTR(gz->z.input);
2540
+ gz->orig_name = rb_str_new(RSTRING_PTR(gz->z.input), len);
2541
+ OBJ_TAINT(gz->orig_name); /* for safe */
2542
+ zstream_discard_input(&gz->z, len + 1);
2318
2543
  }
2319
2544
  if (flags & GZ_FLAG_COMMENT) {
2320
- if (!gzfile_read_raw_ensure(gz, 1)) {
2321
- rb_raise(cGzError, "unexpected end of file");
2322
- }
2323
- p = gzfile_read_raw_until_zero(gz, 0);
2324
- len = p - RSTRING_PTR(gz->z.input);
2325
- gz->comment = rb_str_new(RSTRING_PTR(gz->z.input), len);
2326
- OBJ_TAINT(gz->comment); /* for safe */
2327
- zstream_discard_input(&gz->z, len + 1);
2545
+ if (!gzfile_read_raw_ensure(gz, 1)) {
2546
+ rb_raise(cGzError, "unexpected end of file");
2547
+ }
2548
+ p = gzfile_read_raw_until_zero(gz, 0);
2549
+ len = p - RSTRING_PTR(gz->z.input);
2550
+ gz->comment = rb_str_new(RSTRING_PTR(gz->z.input), len);
2551
+ OBJ_TAINT(gz->comment); /* for safe */
2552
+ zstream_discard_input(&gz->z, len + 1);
2328
2553
  }
2329
2554
 
2330
2555
  if (gz->z.input != Qnil && RSTRING_LEN(gz->z.input) > 0) {
2331
- zstream_run(&gz->z, 0, 0, Z_SYNC_FLUSH);
2556
+ zstream_run(&gz->z, 0, 0, Z_SYNC_FLUSH);
2332
2557
  }
2333
2558
  }
2334
2559
 
@@ -2340,7 +2565,7 @@ gzfile_check_footer(struct gzfile *gz)
2340
2565
  gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;
2341
2566
 
2342
2567
  if (!gzfile_read_raw_ensure(gz, 8)) { /* 8 is the size of gzip footer */
2343
- gzfile_raise(gz, cNoFooter, "footer is not found");
2568
+ gzfile_raise(gz, cNoFooter, "footer is not found");
2344
2569
  }
2345
2570
 
2346
2571
  crc = gzfile_get32((Bytef*)RSTRING_PTR(gz->z.input));
@@ -2350,10 +2575,10 @@ gzfile_check_footer(struct gzfile *gz)
2350
2575
  zstream_discard_input(&gz->z, 8);
2351
2576
 
2352
2577
  if (gz->crc != crc) {
2353
- rb_raise(cCRCError, "invalid compressed data -- crc error");
2578
+ rb_raise(cCRCError, "invalid compressed data -- crc error");
2354
2579
  }
2355
2580
  if ((uint32_t)gz->z.stream.total_out != length) {
2356
- rb_raise(cLengthError, "invalid compressed data -- length error");
2581
+ rb_raise(cLengthError, "invalid compressed data -- length error");
2357
2582
  }
2358
2583
  }
2359
2584
 
@@ -2361,13 +2586,13 @@ static void
2361
2586
  gzfile_write(struct gzfile *gz, Bytef *str, long len)
2362
2587
  {
2363
2588
  if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
2364
- gzfile_make_header(gz);
2589
+ gzfile_make_header(gz);
2365
2590
  }
2366
2591
 
2367
2592
  if (len > 0 || (gz->z.flags & GZFILE_FLAG_SYNC)) {
2368
- gz->crc = checksum_long(crc32, gz->crc, str, len);
2369
- zstream_run(&gz->z, str, len, (gz->z.flags & GZFILE_FLAG_SYNC)
2370
- ? Z_SYNC_FLUSH : Z_NO_FLUSH);
2593
+ gz->crc = checksum_long(crc32, gz->crc, str, len);
2594
+ zstream_run(&gz->z, str, len, (gz->z.flags & GZFILE_FLAG_SYNC)
2595
+ ? Z_SYNC_FLUSH : Z_NO_FLUSH);
2371
2596
  }
2372
2597
  gzfile_write_raw(gz);
2373
2598
  }
@@ -2378,18 +2603,18 @@ gzfile_read_more(struct gzfile *gz)
2378
2603
  volatile VALUE str;
2379
2604
 
2380
2605
  while (!ZSTREAM_IS_FINISHED(&gz->z)) {
2381
- str = gzfile_read_raw(gz);
2382
- if (NIL_P(str)) {
2383
- if (!ZSTREAM_IS_FINISHED(&gz->z)) {
2384
- rb_raise(cGzError, "unexpected end of file");
2385
- }
2386
- break;
2387
- }
2388
- if (RSTRING_LEN(str) > 0) { /* prevent Z_BUF_ERROR */
2389
- zstream_run(&gz->z, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str),
2390
- Z_SYNC_FLUSH);
2391
- }
2392
- if (gz->z.buf_filled > 0) break;
2606
+ str = gzfile_read_raw(gz);
2607
+ if (NIL_P(str)) {
2608
+ if (!ZSTREAM_IS_FINISHED(&gz->z)) {
2609
+ rb_raise(cGzError, "unexpected end of file");
2610
+ }
2611
+ break;
2612
+ }
2613
+ if (RSTRING_LEN(str) > 0) { /* prevent Z_BUF_ERROR */
2614
+ zstream_run(&gz->z, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str),
2615
+ Z_SYNC_FLUSH);
2616
+ }
2617
+ if (gz->z.buf_filled > 0) break;
2393
2618
  }
2394
2619
  return gz->z.buf_filled;
2395
2620
  }
@@ -2398,12 +2623,12 @@ static void
2398
2623
  gzfile_calc_crc(struct gzfile *gz, VALUE str)
2399
2624
  {
2400
2625
  if (RSTRING_LEN(str) <= gz->ungetc) {
2401
- gz->ungetc -= RSTRING_LEN(str);
2626
+ gz->ungetc -= RSTRING_LEN(str);
2402
2627
  }
2403
2628
  else {
2404
- gz->crc = checksum_long(crc32, gz->crc, (Bytef*)RSTRING_PTR(str) + gz->ungetc,
2405
- RSTRING_LEN(str) - gz->ungetc);
2406
- gz->ungetc = 0;
2629
+ gz->crc = checksum_long(crc32, gz->crc, (Bytef*)RSTRING_PTR(str) + gz->ungetc,
2630
+ RSTRING_LEN(str) - gz->ungetc);
2631
+ gz->ungetc = 0;
2407
2632
  }
2408
2633
  }
2409
2634
 
@@ -2411,20 +2636,19 @@ static VALUE
2411
2636
  gzfile_newstr(struct gzfile *gz, VALUE str)
2412
2637
  {
2413
2638
  if (!gz->enc2) {
2414
- rb_enc_associate(str, gz->enc);
2415
- OBJ_TAINT(str); /* for safe */
2416
- return str;
2639
+ rb_enc_associate(str, gz->enc);
2640
+ OBJ_TAINT(str); /* for safe */
2641
+ return str;
2417
2642
  }
2418
2643
  /* TODO: Encodings
2419
- *
2420
2644
  if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
2421
2645
  str = rb_econv_str_convert(gz->ec, str, ECONV_PARTIAL_INPUT);
2422
- rb_enc_associate(str, gz->enc);
2423
- OBJ_TAINT(str);
2424
- return str;
2646
+ rb_enc_associate(str, gz->enc);
2647
+ OBJ_TAINT(str);
2648
+ return str;
2425
2649
  }
2426
2650
  return rb_str_conv_enc_opts(str, gz->enc2, gz->enc,
2427
- gz->ecflags, gz->ecopts);
2651
+ gz->ecflags, gz->ecopts);
2428
2652
  */
2429
2653
  return str;
2430
2654
  }
@@ -2435,15 +2659,15 @@ gzfile_fill(struct gzfile *gz, long len)
2435
2659
  if (len < 0)
2436
2660
  rb_raise(rb_eArgError, "negative length %ld given", len);
2437
2661
  if (len == 0)
2438
- return 0;
2662
+ return 0;
2439
2663
  while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled < len) {
2440
- gzfile_read_more(gz);
2664
+ gzfile_read_more(gz);
2441
2665
  }
2442
2666
  if (GZFILE_IS_FINISHED(gz)) {
2443
- if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2444
- gzfile_check_footer(gz);
2445
- }
2446
- return -1;
2667
+ if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2668
+ gzfile_check_footer(gz);
2669
+ }
2670
+ return -1;
2447
2671
  }
2448
2672
  return len < gz->z.buf_filled ? len : gz->z.buf_filled;
2449
2673
  }
@@ -2457,7 +2681,7 @@ gzfile_read(struct gzfile *gz, long len)
2457
2681
  if (len == 0) return rb_str_new(0, 0);
2458
2682
  if (len < 0) return Qnil;
2459
2683
  dst = zstream_shift_buffer(&gz->z, len);
2460
- gzfile_calc_crc(gz, dst);
2684
+ if (!NIL_P(dst)) gzfile_calc_crc(gz, dst);
2461
2685
  return dst;
2462
2686
  }
2463
2687
 
@@ -2470,7 +2694,7 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
2470
2694
  rb_raise(rb_eArgError, "negative length %ld given", len);
2471
2695
 
2472
2696
  if (!NIL_P(outbuf))
2473
- OBJ_TAINT(outbuf);
2697
+ OBJ_TAINT(outbuf);
2474
2698
 
2475
2699
  if (len == 0) {
2476
2700
  if (NIL_P(outbuf))
@@ -2481,15 +2705,15 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
2481
2705
  }
2482
2706
  }
2483
2707
  while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled == 0) {
2484
- gzfile_read_more(gz);
2708
+ gzfile_read_more(gz);
2485
2709
  }
2486
2710
  if (GZFILE_IS_FINISHED(gz)) {
2487
- if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2488
- gzfile_check_footer(gz);
2489
- }
2711
+ if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2712
+ gzfile_check_footer(gz);
2713
+ }
2490
2714
  if (!NIL_P(outbuf))
2491
2715
  rb_str_resize(outbuf, 0);
2492
- rb_raise(rb_eEOFError, "end of file reached");
2716
+ rb_raise(rb_eEOFError, "end of file reached");
2493
2717
  }
2494
2718
 
2495
2719
  dst = zstream_shift_buffer(&gz->z, len);
@@ -2498,7 +2722,7 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
2498
2722
  if (!NIL_P(outbuf)) {
2499
2723
  rb_str_resize(outbuf, RSTRING_LEN(dst));
2500
2724
  memcpy(RSTRING_PTR(outbuf), RSTRING_PTR(dst), RSTRING_LEN(dst));
2501
- dst = outbuf;
2725
+ dst = outbuf;
2502
2726
  }
2503
2727
  OBJ_TAINT(dst); /* for safe */
2504
2728
  return dst;
@@ -2510,16 +2734,17 @@ gzfile_read_all(struct gzfile *gz)
2510
2734
  VALUE dst;
2511
2735
 
2512
2736
  while (!ZSTREAM_IS_FINISHED(&gz->z)) {
2513
- gzfile_read_more(gz);
2737
+ gzfile_read_more(gz);
2514
2738
  }
2515
2739
  if (GZFILE_IS_FINISHED(gz)) {
2516
- if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2517
- gzfile_check_footer(gz);
2518
- }
2519
- return rb_str_new(0, 0);
2740
+ if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2741
+ gzfile_check_footer(gz);
2742
+ }
2743
+ return rb_str_new(0, 0);
2520
2744
  }
2521
2745
 
2522
2746
  dst = zstream_detach_buffer(&gz->z);
2747
+ if (NIL_P(dst)) return dst;
2523
2748
  gzfile_calc_crc(gz, dst);
2524
2749
  OBJ_TAINT(dst);
2525
2750
  return gzfile_newstr(gz, dst);
@@ -2533,47 +2758,46 @@ gzfile_getc(struct gzfile *gz)
2533
2758
 
2534
2759
  len = rb_enc_mbmaxlen(gz->enc);
2535
2760
  while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled < len) {
2536
- gzfile_read_more(gz);
2761
+ gzfile_read_more(gz);
2537
2762
  }
2538
2763
  if (GZFILE_IS_FINISHED(gz)) {
2539
- if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2540
- gzfile_check_footer(gz);
2541
- }
2542
- return Qnil;
2764
+ if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2765
+ gzfile_check_footer(gz);
2766
+ }
2767
+ return Qnil;
2543
2768
  }
2544
2769
 
2545
2770
  /* TODO: Encodings
2546
- *
2547
2771
  if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
2548
- const unsigned char *ss, *sp, *se;
2549
- unsigned char *ds, *dp, *de;
2550
- rb_econv_result_t res;
2772
+ const unsigned char *ss, *sp, *se;
2773
+ unsigned char *ds, *dp, *de;
2551
2774
 
2552
- if (!gz->cbuf) {
2553
- gz->cbuf = ALLOC_N(char, GZFILE_CBUF_CAPA);
2554
- }
2775
+ if (!gz->cbuf) {
2776
+ gz->cbuf = ALLOC_N(char, GZFILE_CBUF_CAPA);
2777
+ }
2555
2778
  ss = sp = (const unsigned char*)RSTRING_PTR(gz->z.buf);
2556
2779
  se = sp + gz->z.buf_filled;
2557
2780
  ds = dp = (unsigned char *)gz->cbuf;
2558
2781
  de = (unsigned char *)ds + GZFILE_CBUF_CAPA;
2559
- res = rb_econv_convert(gz->ec, &sp, se, &dp, de, ECONV_PARTIAL_INPUT|ECONV_AFTER_OUTPUT);
2782
+ (void)rb_econv_convert(gz->ec, &sp, se, &dp, de, ECONV_PARTIAL_INPUT|ECONV_AFTER_OUTPUT);
2560
2783
  rb_econv_check_error(gz->ec);
2561
- dst = zstream_shift_buffer(&gz->z, sp - ss);
2562
- gzfile_calc_crc(gz, dst);
2563
- dst = rb_str_new(gz->cbuf, dp - ds);
2564
- rb_enc_associate(dst, gz->enc);
2565
- OBJ_TAINT(dst);
2566
- return dst;
2784
+ dst = zstream_shift_buffer(&gz->z, sp - ss);
2785
+ gzfile_calc_crc(gz, dst);
2786
+ dst = rb_str_new(gz->cbuf, dp - ds);
2787
+ rb_enc_associate(dst, gz->enc);
2788
+ OBJ_TAINT(dst);
2789
+ return dst;
2567
2790
  }
2568
2791
  else {
2569
2792
  */
2570
- buf = gz->z.buf;
2571
- len = rb_enc_mbclen(RSTRING_PTR(buf), RSTRING_END(buf), gz->enc);
2572
- dst = gzfile_read(gz, len);
2573
- return gzfile_newstr(gz, dst);
2574
- /* TODO: Encodings
2793
+ buf = gz->z.buf;
2794
+ len = rb_enc_mbclen(RSTRING_PTR(buf), RSTRING_END(buf), gz->enc);
2795
+ dst = gzfile_read(gz, len);
2796
+ if (NIL_P(dst)) return dst;
2797
+ return gzfile_newstr(gz, dst);
2798
+ /* TODO: Encodings
2575
2799
  }
2576
- */
2800
+ */
2577
2801
  }
2578
2802
 
2579
2803
  static void
@@ -2596,7 +2820,7 @@ gzfile_writer_end_run(VALUE arg)
2596
2820
  struct gzfile *gz = (struct gzfile *)arg;
2597
2821
 
2598
2822
  if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
2599
- gzfile_make_header(gz);
2823
+ gzfile_make_header(gz);
2600
2824
  }
2601
2825
 
2602
2826
  zstream_run(&gz->z, (Bytef*)"", 0, Z_FINISH);
@@ -2621,8 +2845,8 @@ gzfile_reader_end_run(VALUE arg)
2621
2845
  struct gzfile *gz = (struct gzfile *)arg;
2622
2846
 
2623
2847
  if (GZFILE_IS_FINISHED(gz)
2624
- && !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2625
- gzfile_check_footer(gz);
2848
+ && !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2849
+ gzfile_check_footer(gz);
2626
2850
  }
2627
2851
 
2628
2852
  return Qnil;
@@ -2644,7 +2868,7 @@ gzfile_reader_rewind(struct gzfile *gz)
2644
2868
 
2645
2869
  n = gz->z.stream.total_in;
2646
2870
  if (!NIL_P(gz->z.input)) {
2647
- n += RSTRING_LEN(gz->z.input);
2871
+ n += RSTRING_LEN(gz->z.input);
2648
2872
  }
2649
2873
 
2650
2874
  rb_funcall(gz->io, id_seek, 2, rb_int2inum(-n), INT2FIX(1));
@@ -2659,11 +2883,11 @@ gzfile_reader_get_unused(struct gzfile *gz)
2659
2883
  if (!ZSTREAM_IS_READY(&gz->z)) return Qnil;
2660
2884
  if (!GZFILE_IS_FINISHED(gz)) return Qnil;
2661
2885
  if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2662
- gzfile_check_footer(gz);
2886
+ gzfile_check_footer(gz);
2663
2887
  }
2664
2888
  if (NIL_P(gz->z.input)) return Qnil;
2665
2889
 
2666
- str = rb_str_dup(gz->z.input);
2890
+ str = rb_str_resurrect(gz->z.input);
2667
2891
  OBJ_TAINT(str); /* for safe */
2668
2892
  return str;
2669
2893
  }
@@ -2675,7 +2899,7 @@ get_gzfile(VALUE obj)
2675
2899
 
2676
2900
  Data_Get_Struct(obj, struct gzfile, gz);
2677
2901
  if (!ZSTREAM_IS_READY(&gz->z)) {
2678
- rb_raise(cGzError, "closed gzip stream");
2902
+ rb_raise(cGzError, "closed gzip stream");
2679
2903
  }
2680
2904
  return gz;
2681
2905
  }
@@ -2741,7 +2965,7 @@ gzfile_ensure_close(VALUE obj)
2741
2965
 
2742
2966
  Data_Get_Struct(obj, struct gzfile, gz);
2743
2967
  if (ZSTREAM_IS_READY(&gz->z)) {
2744
- gzfile_close(gz, 1);
2968
+ gzfile_close(gz, 1);
2745
2969
  }
2746
2970
  return Qnil;
2747
2971
  }
@@ -2752,40 +2976,43 @@ gzfile_wrap(int argc, VALUE *argv, VALUE klass, int close_io_on_error)
2752
2976
  VALUE obj;
2753
2977
 
2754
2978
  if (close_io_on_error) {
2755
- int state = 0;
2756
- new_wrap_arg_t arg;
2757
- arg.argc = argc;
2758
- arg.argv = argv;
2759
- arg.klass = klass;
2760
- obj = rb_protect(new_wrap, (VALUE)&arg, &state);
2761
- if (state) {
2762
- rb_io_close(argv[0]);
2763
- rb_jump_tag(state);
2764
- }
2979
+ int state = 0;
2980
+ new_wrap_arg_t arg;
2981
+ arg.argc = argc;
2982
+ arg.argv = argv;
2983
+ arg.klass = klass;
2984
+ obj = rb_protect(new_wrap, (VALUE)&arg, &state);
2985
+ if (state) {
2986
+ rb_io_close(argv[0]);
2987
+ rb_jump_tag(state);
2988
+ }
2765
2989
  }
2766
2990
  else {
2767
- obj = rb_class_new_instance(argc, argv, klass);
2991
+ obj = rb_class_new_instance(argc, argv, klass);
2768
2992
  }
2769
2993
 
2770
2994
  if (rb_block_given_p()) {
2771
- return rb_ensure(rb_yield, obj, gzfile_ensure_close, obj);
2995
+ return rb_ensure(rb_yield, obj, gzfile_ensure_close, obj);
2772
2996
  }
2773
2997
  else {
2774
- return obj;
2998
+ return obj;
2775
2999
  }
2776
3000
  }
2777
3001
 
2778
3002
  /*
2779
3003
  * Document-method: Zlib::GzipFile.wrap
2780
3004
  *
2781
- * call-seq: Zlib::GzipFile.wrap(io) { |gz| ... }
3005
+ * call-seq:
3006
+ * Zlib::GzipReader.wrap(io, ...) { |gz| ... }
3007
+ * Zlib::GzipWriter.wrap(io, ...) { |gz| ... }
2782
3008
  *
2783
- * Creates a GzipFile object associated with +io+, and
2784
- * executes the block with the newly created GzipFile object,
2785
- * just like File.open. The GzipFile object will be closed
2786
- * automatically after executing the block. If you want to keep
2787
- * the associated IO object opening, you may call
2788
- * +Zlib::GzipFile#finish+ method in the block.
3009
+ * Creates a GzipReader or GzipWriter associated with +io+, passing in any
3010
+ * necessary extra options, and executes the block with the newly created
3011
+ * object just like File.open.
3012
+ *
3013
+ * The GzipFile object will be closed automatically after executing the block.
3014
+ * If you want to keep the associated IO object open, you may call
3015
+ * Zlib::GzipFile#finish method in the block.
2789
3016
  */
2790
3017
  static VALUE
2791
3018
  rb_gzfile_s_wrap(int argc, VALUE *argv, VALUE klass)
@@ -2804,7 +3031,7 @@ gzfile_s_open(int argc, VALUE *argv, VALUE klass, const char *mode)
2804
3031
  VALUE io, filename;
2805
3032
 
2806
3033
  if (argc < 1) {
2807
- rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
3034
+ rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
2808
3035
  }
2809
3036
  filename = argv[0];
2810
3037
  io = rb_file_open_str(filename, mode);
@@ -2878,7 +3105,7 @@ rb_gzfile_orig_name(VALUE obj)
2878
3105
  {
2879
3106
  VALUE str = get_gzfile(obj)->orig_name;
2880
3107
  if (!NIL_P(str)) {
2881
- str = rb_str_dup(str);
3108
+ str = rb_str_dup(str);
2882
3109
  }
2883
3110
  OBJ_TAINT(str); /* for safe */
2884
3111
  return str;
@@ -2895,7 +3122,7 @@ rb_gzfile_comment(VALUE obj)
2895
3122
  {
2896
3123
  VALUE str = get_gzfile(obj)->comment;
2897
3124
  if (!NIL_P(str)) {
2898
- str = rb_str_dup(str);
3125
+ str = rb_str_dup(str);
2899
3126
  }
2900
3127
  OBJ_TAINT(str); /* for safe */
2901
3128
  return str;
@@ -2938,16 +3165,12 @@ rb_gzfile_set_mtime(VALUE obj, VALUE mtime)
2938
3165
  VALUE val;
2939
3166
 
2940
3167
  if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
2941
- rb_raise(cGzError, "header is already written");
3168
+ rb_raise(cGzError, "header is already written");
2942
3169
  }
2943
3170
 
2944
- if (FIXNUM_P(mtime)) {
2945
- gz->mtime = FIX2INT(mtime);
2946
- }
2947
- else {
2948
- val = rb_Integer(mtime);
2949
- gz->mtime = FIXNUM_P(val) ? FIX2UINT(val) : rb_big2ulong(val);
2950
- }
3171
+ val = rb_Integer(mtime);
3172
+ gz->mtime = NUM2UINT(val);
3173
+
2951
3174
  return mtime;
2952
3175
  }
2953
3176
 
@@ -2964,12 +3187,12 @@ rb_gzfile_set_orig_name(VALUE obj, VALUE str)
2964
3187
  char *p;
2965
3188
 
2966
3189
  if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
2967
- rb_raise(cGzError, "header is already written");
3190
+ rb_raise(cGzError, "header is already written");
2968
3191
  }
2969
3192
  s = rb_str_dup(rb_str_to_str(str));
2970
3193
  p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
2971
3194
  if (p) {
2972
- rb_str_resize(s, p - RSTRING_PTR(s));
3195
+ rb_str_resize(s, p - RSTRING_PTR(s));
2973
3196
  }
2974
3197
  gz->orig_name = s;
2975
3198
  return str;
@@ -2988,12 +3211,12 @@ rb_gzfile_set_comment(VALUE obj, VALUE str)
2988
3211
  char *p;
2989
3212
 
2990
3213
  if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
2991
- rb_raise(cGzError, "header is already written");
3214
+ rb_raise(cGzError, "header is already written");
2992
3215
  }
2993
3216
  s = rb_str_dup(rb_str_to_str(str));
2994
3217
  p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
2995
3218
  if (p) {
2996
- rb_str_resize(s, p - RSTRING_PTR(s));
3219
+ rb_str_resize(s, p - RSTRING_PTR(s));
2997
3220
  }
2998
3221
  gz->comment = s;
2999
3222
  return str;
@@ -3087,10 +3310,10 @@ rb_gzfile_set_sync(VALUE obj, VALUE mode)
3087
3310
  struct gzfile *gz = get_gzfile(obj);
3088
3311
 
3089
3312
  if (RTEST(mode)) {
3090
- gz->z.flags |= GZFILE_FLAG_SYNC;
3313
+ gz->z.flags |= GZFILE_FLAG_SYNC;
3091
3314
  }
3092
3315
  else {
3093
- gz->z.flags &= ~GZFILE_FLAG_SYNC;
3316
+ gz->z.flags &= ~GZFILE_FLAG_SYNC;
3094
3317
  }
3095
3318
  return mode;
3096
3319
  }
@@ -3137,18 +3360,17 @@ rb_gzfile_path(VALUE obj)
3137
3360
  static void
3138
3361
  rb_gzfile_ecopts(struct gzfile *gz, VALUE opts)
3139
3362
  {
3140
- /* TODO: Encodings
3141
- *
3363
+ /* TODO: Encodings
3142
3364
  if (!NIL_P(opts)) {
3143
- rb_io_extract_encoding_option(opts, &gz->enc, &gz->enc2, NULL);
3365
+ rb_io_extract_encoding_option(opts, &gz->enc, &gz->enc2, NULL);
3144
3366
  }
3145
3367
  if (gz->enc2) {
3146
- gz->ecflags = rb_econv_prepare_opts(opts, &opts);
3147
- gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
3148
- gz->ecflags, opts);
3149
- gz->ecopts = opts;
3368
+ gz->ecflags = rb_econv_prepare_opts(opts, &opts);
3369
+ gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
3370
+ gz->ecflags, opts);
3371
+ gz->ecopts = opts;
3150
3372
  }
3151
- */
3373
+ */
3152
3374
  }
3153
3375
 
3154
3376
  /* ------------------------------------------------------------------------- */
@@ -3206,12 +3428,17 @@ rb_gzwriter_s_open(int argc, VALUE *argv, VALUE klass)
3206
3428
  }
3207
3429
 
3208
3430
  /*
3209
- * call-seq: Zlib::GzipWriter.new(io, level, strategy)
3431
+ * call-seq:
3432
+ * Zlib::GzipWriter.new(io, level = nil, strategy = nil, options = {})
3210
3433
  *
3211
3434
  * Creates a GzipWriter object associated with +io+. +level+ and +strategy+
3212
3435
  * should be the same as the arguments of Zlib::Deflate.new. The GzipWriter
3213
- * object writes gzipped data to +io+. At least, +io+ must respond to the
3214
- * +write+ method that behaves same as write method in IO class.
3436
+ * object writes gzipped data to +io+. +io+ must respond to the
3437
+ * +write+ method that behaves the same as IO#write.
3438
+ *
3439
+ * The +options+ hash may be used to set the encoding of the data.
3440
+ * +:external_encoding+, +:internal_encoding+ and +:encoding+ may be set as in
3441
+ * IO::new.
3215
3442
  */
3216
3443
  static VALUE
3217
3444
  rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
@@ -3221,8 +3448,8 @@ rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
3221
3448
  int err;
3222
3449
 
3223
3450
  if (argc > 1) {
3224
- opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash");
3225
- if (!NIL_P(opt)) argc--;
3451
+ opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash");
3452
+ if (!NIL_P(opt)) argc--;
3226
3453
  }
3227
3454
 
3228
3455
  rb_scan_args(argc, argv, "12", &io, &level, &strategy);
@@ -3231,17 +3458,17 @@ rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
3231
3458
  /* this is undocumented feature of zlib */
3232
3459
  gz->level = ARG_LEVEL(level);
3233
3460
  err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED,
3234
- -MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));
3461
+ -MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));
3235
3462
  if (err != Z_OK) {
3236
- raise_zlib_error(err, gz->z.stream.msg);
3463
+ raise_zlib_error(err, gz->z.stream.msg);
3237
3464
  }
3238
3465
  gz->io = io;
3239
3466
  ZSTREAM_READY(&gz->z);
3240
3467
  rb_gzfile_ecopts(gz, opt);
3241
3468
 
3242
3469
  if (rb_respond_to(io, id_path)) {
3243
- gz->path = rb_funcall(gz->io, id_path, 0);
3244
- rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
3470
+ gz->path = rb_funcall(gz->io, id_path, 0);
3471
+ rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
3245
3472
  }
3246
3473
 
3247
3474
  return obj;
@@ -3265,12 +3492,12 @@ rb_gzwriter_flush(int argc, VALUE *argv, VALUE obj)
3265
3492
 
3266
3493
  flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
3267
3494
  if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
3268
- zstream_run(&gz->z, (Bytef*)"", 0, flush);
3495
+ zstream_run(&gz->z, (Bytef*)"", 0, flush);
3269
3496
  }
3270
3497
 
3271
3498
  gzfile_write_raw(gz);
3272
3499
  if (rb_respond_to(gz->io, id_flush)) {
3273
- rb_funcall(gz->io, id_flush, 0);
3500
+ rb_funcall(gz->io, id_flush, 0);
3274
3501
  }
3275
3502
  return obj;
3276
3503
  }
@@ -3283,10 +3510,10 @@ rb_gzwriter_write(VALUE obj, VALUE str)
3283
3510
  {
3284
3511
  struct gzfile *gz = get_gzfile(obj);
3285
3512
 
3286
- if (TYPE(str) != T_STRING)
3287
- str = rb_obj_as_string(str);
3513
+ if (!RB_TYPE_P(str, T_STRING))
3514
+ str = rb_obj_as_string(str);
3288
3515
  if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
3289
- str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2);
3516
+ str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2);
3290
3517
  }
3291
3518
  gzfile_write(gz, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
3292
3519
  return INT2FIX(RSTRING_LEN(str));
@@ -3335,7 +3562,7 @@ rb_gzwriter_putc(VALUE obj, VALUE ch)
3335
3562
  * Document-class: Zlib::GzipReader
3336
3563
  *
3337
3564
  * Zlib::GzipReader is the class for reading a gzipped file. GzipReader should
3338
- * be used an IO, or -IO-lie, object.
3565
+ * be used an IO, or -IO-like, object.
3339
3566
  *
3340
3567
  * Zlib::GzipReader.open('hoge.gz') {|gz|
3341
3568
  * print gz.read
@@ -3407,11 +3634,16 @@ rb_gzreader_s_open(int argc, VALUE *argv, VALUE klass)
3407
3634
  /*
3408
3635
  * Document-method: Zlib::GzipReader.new
3409
3636
  *
3410
- * call-seq: Zlib::GzipReader.new(io)
3637
+ * call-seq:
3638
+ * Zlib::GzipReader.new(io, options = {})
3411
3639
  *
3412
3640
  * Creates a GzipReader object associated with +io+. The GzipReader object reads
3413
- * gzipped data from +io+, and parses/decompresses them. At least, +io+ must have
3414
- * a +read+ method that behaves same as the +read+ method in IO class.
3641
+ * gzipped data from +io+, and parses/decompresses it. The +io+ must
3642
+ * have a +read+ method that behaves same as the IO#read.
3643
+ *
3644
+ * The +options+ hash may be used to set the encoding of the data.
3645
+ * +:external_encoding+, +:internal_encoding+ and +:encoding+ may be set as in
3646
+ * IO::new.
3415
3647
  *
3416
3648
  * If the gzip file header is incorrect, raises an Zlib::GzipFile::Error
3417
3649
  * exception.
@@ -3429,7 +3661,7 @@ rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj)
3429
3661
  /* this is undocumented feature of zlib */
3430
3662
  err = inflateInit2(&gz->z.stream, -MAX_WBITS);
3431
3663
  if (err != Z_OK) {
3432
- raise_zlib_error(err, gz->z.stream.msg);
3664
+ raise_zlib_error(err, gz->z.stream.msg);
3433
3665
  }
3434
3666
  gz->io = io;
3435
3667
  ZSTREAM_READY(&gz->z);
@@ -3437,8 +3669,8 @@ rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj)
3437
3669
  rb_gzfile_ecopts(gz, opt);
3438
3670
 
3439
3671
  if (rb_respond_to(io, id_path)) {
3440
- gz->path = rb_funcall(gz->io, id_path, 0);
3441
- rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
3672
+ gz->path = rb_funcall(gz->io, id_path, 0);
3673
+ rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
3442
3674
  }
3443
3675
 
3444
3676
  return obj;
@@ -3486,12 +3718,12 @@ rb_gzreader_read(int argc, VALUE *argv, VALUE obj)
3486
3718
 
3487
3719
  rb_scan_args(argc, argv, "01", &vlen);
3488
3720
  if (NIL_P(vlen)) {
3489
- return gzfile_read_all(gz);
3721
+ return gzfile_read_all(gz);
3490
3722
  }
3491
3723
 
3492
3724
  len = NUM2INT(vlen);
3493
3725
  if (len < 0) {
3494
- rb_raise(rb_eArgError, "negative length %ld given", len);
3726
+ rb_raise(rb_eArgError, "negative length %ld given", len);
3495
3727
  }
3496
3728
  return gzfile_read(gz, len);
3497
3729
  }
@@ -3519,7 +3751,7 @@ rb_gzreader_readpartial(int argc, VALUE *argv, VALUE obj)
3519
3751
 
3520
3752
  len = NUM2INT(vlen);
3521
3753
  if (len < 0) {
3522
- rb_raise(rb_eArgError, "negative length %ld given", len);
3754
+ rb_raise(rb_eArgError, "negative length %ld given", len);
3523
3755
  }
3524
3756
  if (!NIL_P(outbuf))
3525
3757
  Check_Type(outbuf, T_STRING);
@@ -3550,7 +3782,7 @@ rb_gzreader_readchar(VALUE obj)
3550
3782
  VALUE dst;
3551
3783
  dst = rb_gzreader_getc(obj);
3552
3784
  if (NIL_P(dst)) {
3553
- rb_raise(rb_eEOFError, "end of file reached");
3785
+ rb_raise(rb_eEOFError, "end of file reached");
3554
3786
  }
3555
3787
  return dst;
3556
3788
  }
@@ -3568,7 +3800,7 @@ rb_gzreader_getbyte(VALUE obj)
3568
3800
 
3569
3801
  dst = gzfile_read(gz, 1);
3570
3802
  if (!NIL_P(dst)) {
3571
- dst = INT2FIX((unsigned int)(RSTRING_PTR(dst)[0]) & 0xff);
3803
+ dst = INT2FIX((unsigned int)(RSTRING_PTR(dst)[0]) & 0xff);
3572
3804
  }
3573
3805
  return dst;
3574
3806
  }
@@ -3584,7 +3816,7 @@ rb_gzreader_readbyte(VALUE obj)
3584
3816
  VALUE dst;
3585
3817
  dst = rb_gzreader_getbyte(obj);
3586
3818
  if (NIL_P(dst)) {
3587
- rb_raise(rb_eEOFError, "end of file reached");
3819
+ rb_raise(rb_eEOFError, "end of file reached");
3588
3820
  }
3589
3821
  return dst;
3590
3822
  }
@@ -3602,7 +3834,7 @@ rb_gzreader_each_char(VALUE obj)
3602
3834
  RETURN_ENUMERATOR(obj, 0, 0);
3603
3835
 
3604
3836
  while (!NIL_P(c = rb_gzreader_getc(obj))) {
3605
- rb_yield(c);
3837
+ rb_yield(c);
3606
3838
  }
3607
3839
  return Qnil;
3608
3840
  }
@@ -3620,11 +3852,25 @@ rb_gzreader_each_byte(VALUE obj)
3620
3852
  RETURN_ENUMERATOR(obj, 0, 0);
3621
3853
 
3622
3854
  while (!NIL_P(c = rb_gzreader_getbyte(obj))) {
3623
- rb_yield(c);
3855
+ rb_yield(c);
3624
3856
  }
3625
3857
  return Qnil;
3626
3858
  }
3627
3859
 
3860
+ /*
3861
+ * Document-method: Zlib::GzipReader#bytes
3862
+ *
3863
+ * This is a deprecated alias for <code>each_byte</code>.
3864
+ */
3865
+ static VALUE
3866
+ rb_gzreader_bytes(VALUE obj)
3867
+ {
3868
+ rb_warn("Zlib::GzipReader#bytes is deprecated; use #each_byte instead");
3869
+ if (!rb_block_given_p())
3870
+ return rb_enumeratorize(obj, ID2SYM(rb_intern("each_byte")), 0, 0);
3871
+ return rb_gzreader_each_byte(obj);
3872
+ }
3873
+
3628
3874
  /*
3629
3875
  * Document-method: Zlib::GzipReader#ungetc
3630
3876
  *
@@ -3636,11 +3882,11 @@ rb_gzreader_ungetc(VALUE obj, VALUE s)
3636
3882
  struct gzfile *gz;
3637
3883
 
3638
3884
  if (FIXNUM_P(s))
3639
- return rb_gzreader_ungetbyte(obj, s);
3885
+ return rb_gzreader_ungetbyte(obj, s);
3640
3886
  gz = get_gzfile(obj);
3641
3887
  StringValue(s);
3642
3888
  if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
3643
- s = rb_str_conv_enc(s, rb_enc_get(s), gz->enc2);
3889
+ s = rb_str_conv_enc(s, rb_enc_get(s), gz->enc2);
3644
3890
  }
3645
3891
  gzfile_ungets(gz, (const Bytef*)RSTRING_PTR(s), RSTRING_LEN(s));
3646
3892
  return Qnil;
@@ -3667,23 +3913,23 @@ gzreader_skip_linebreaks(struct gzfile *gz)
3667
3913
  int n;
3668
3914
 
3669
3915
  while (gz->z.buf_filled == 0) {
3670
- if (GZFILE_IS_FINISHED(gz)) return;
3671
- gzfile_read_more(gz);
3916
+ if (GZFILE_IS_FINISHED(gz)) return;
3917
+ gzfile_read_more(gz);
3672
3918
  }
3673
3919
  n = 0;
3674
3920
  p = RSTRING_PTR(gz->z.buf);
3675
3921
 
3676
3922
  while (n++, *(p++) == '\n') {
3677
- if (n >= gz->z.buf_filled) {
3678
- str = zstream_detach_buffer(&gz->z);
3679
- gzfile_calc_crc(gz, str);
3680
- while (gz->z.buf_filled == 0) {
3681
- if (GZFILE_IS_FINISHED(gz)) return;
3682
- gzfile_read_more(gz);
3683
- }
3684
- n = 0;
3685
- p = RSTRING_PTR(gz->z.buf);
3686
- }
3923
+ if (n >= gz->z.buf_filled) {
3924
+ str = zstream_detach_buffer(&gz->z);
3925
+ gzfile_calc_crc(gz, str);
3926
+ while (gz->z.buf_filled == 0) {
3927
+ if (GZFILE_IS_FINISHED(gz)) return;
3928
+ gzfile_read_more(gz);
3929
+ }
3930
+ n = 0;
3931
+ p = RSTRING_PTR(gz->z.buf);
3932
+ }
3687
3933
  }
3688
3934
 
3689
3935
  str = zstream_shift_buffer(&gz->z, n - 1);
@@ -3694,7 +3940,7 @@ static void
3694
3940
  rscheck(const char *rsptr, long rslen, VALUE rs)
3695
3941
  {
3696
3942
  if (RSTRING_PTR(rs) != rsptr && RSTRING_LEN(rs) != rslen)
3697
- rb_raise(rb_eRuntimeError, "rs modified");
3943
+ rb_raise(rb_eRuntimeError, "rs modified");
3698
3944
  }
3699
3945
 
3700
3946
  static long
@@ -3705,15 +3951,15 @@ gzreader_charboundary(struct gzfile *gz, long n)
3705
3951
  char *p = rb_enc_left_char_head(s, s + n, e, gz->enc);
3706
3952
  long l = p - s;
3707
3953
  if (l < n) {
3708
- n = rb_enc_precise_mbclen(p, e, gz->enc);
3709
- if (ONIGENC_MBCLEN_NEEDMORE_P(n)) {
3710
- if ((l = gzfile_fill(gz, l + ONIGENC_MBCLEN_NEEDMORE_LEN(n))) > 0) {
3711
- return l;
3712
- }
3713
- }
3714
- else if (ONIGENC_MBCLEN_CHARFOUND_P(n)) {
3715
- return l + ONIGENC_MBCLEN_CHARFOUND_LEN(n);
3716
- }
3954
+ n = rb_enc_precise_mbclen(p, e, gz->enc);
3955
+ if (MBCLEN_NEEDMORE_P(n)) {
3956
+ if ((l = gzfile_fill(gz, l + MBCLEN_NEEDMORE_LEN(n))) > 0) {
3957
+ return l;
3958
+ }
3959
+ }
3960
+ else if (MBCLEN_CHARFOUND_P(n)) {
3961
+ return l + MBCLEN_CHARFOUND_LEN(n);
3962
+ }
3717
3963
  }
3718
3964
  return n;
3719
3965
  }
@@ -3732,110 +3978,112 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj)
3732
3978
  int maxlen = rb_enc_mbmaxlen(enc);
3733
3979
 
3734
3980
  if (argc == 0) {
3735
- rs = rb_rs;
3981
+ rs = rb_rs;
3736
3982
  }
3737
3983
  else {
3738
- VALUE lim, tmp;
3739
-
3740
- rb_scan_args(argc, argv, "11", &rs, &lim);
3741
- if (!NIL_P(lim)) {
3742
- if (!NIL_P(rs)) StringValue(rs);
3743
- }
3744
- else if (!NIL_P(rs)) {
3745
- tmp = rb_check_string_type(rs);
3746
- if (NIL_P(tmp)) {
3747
- lim = rs;
3748
- rs = rb_rs;
3749
- }
3750
- else {
3751
- rs = tmp;
3752
- }
3753
- }
3754
- if (!NIL_P(lim)) {
3755
- limit = NUM2LONG(lim);
3756
- if (limit == 0) return rb_str_new(0,0);
3757
- }
3984
+ VALUE lim, tmp;
3985
+
3986
+ rb_scan_args(argc, argv, "11", &rs, &lim);
3987
+ if (!NIL_P(lim)) {
3988
+ if (!NIL_P(rs)) StringValue(rs);
3989
+ }
3990
+ else if (!NIL_P(rs)) {
3991
+ tmp = rb_check_string_type(rs);
3992
+ if (NIL_P(tmp)) {
3993
+ lim = rs;
3994
+ rs = rb_rs;
3995
+ }
3996
+ else {
3997
+ rs = tmp;
3998
+ }
3999
+ }
4000
+ if (!NIL_P(lim)) {
4001
+ limit = NUM2LONG(lim);
4002
+ if (limit == 0) return rb_str_new(0,0);
4003
+ }
3758
4004
  }
3759
4005
 
3760
4006
  if (NIL_P(rs)) {
3761
- if (limit < 0) {
3762
- dst = gzfile_read_all(gz);
3763
- if (RSTRING_LEN(dst) == 0) return Qnil;
3764
- }
3765
- else if ((n = gzfile_fill(gz, limit)) <= 0) {
3766
- return Qnil;
3767
- }
3768
- else {
3769
- if (maxlen > 1 && n >= limit && !GZFILE_IS_FINISHED(gz)) {
3770
- n = gzreader_charboundary(gz, n);
3771
- }
3772
- else {
3773
- n = limit;
3774
- }
3775
- dst = zstream_shift_buffer(&gz->z, n);
3776
- gzfile_calc_crc(gz, dst);
3777
- dst = gzfile_newstr(gz, dst);
3778
- }
3779
- gz->lineno++;
3780
- return dst;
4007
+ if (limit < 0) {
4008
+ dst = gzfile_read_all(gz);
4009
+ if (RSTRING_LEN(dst) == 0) return Qnil;
4010
+ }
4011
+ else if ((n = gzfile_fill(gz, limit)) <= 0) {
4012
+ return Qnil;
4013
+ }
4014
+ else {
4015
+ if (maxlen > 1 && n >= limit && !GZFILE_IS_FINISHED(gz)) {
4016
+ n = gzreader_charboundary(gz, n);
4017
+ }
4018
+ else {
4019
+ n = limit;
4020
+ }
4021
+ dst = zstream_shift_buffer(&gz->z, n);
4022
+ if (NIL_P(dst)) return dst;
4023
+ gzfile_calc_crc(gz, dst);
4024
+ dst = gzfile_newstr(gz, dst);
4025
+ }
4026
+ gz->lineno++;
4027
+ return dst;
3781
4028
  }
3782
4029
 
3783
4030
  if (RSTRING_LEN(rs) == 0) {
3784
- rsptr = "\n\n";
3785
- rslen = 2;
3786
- rspara = 1;
4031
+ rsptr = "\n\n";
4032
+ rslen = 2;
4033
+ rspara = 1;
3787
4034
  } else {
3788
- rsptr = RSTRING_PTR(rs);
3789
- rslen = RSTRING_LEN(rs);
3790
- rspara = 0;
4035
+ rsptr = RSTRING_PTR(rs);
4036
+ rslen = RSTRING_LEN(rs);
4037
+ rspara = 0;
3791
4038
  }
3792
4039
 
3793
4040
  if (rspara) {
3794
- gzreader_skip_linebreaks(gz);
4041
+ gzreader_skip_linebreaks(gz);
3795
4042
  }
3796
4043
 
3797
4044
  while (gz->z.buf_filled < rslen) {
3798
- if (ZSTREAM_IS_FINISHED(&gz->z)) {
3799
- if (gz->z.buf_filled > 0) gz->lineno++;
3800
- return gzfile_read(gz, rslen);
3801
- }
3802
- gzfile_read_more(gz);
4045
+ if (ZSTREAM_IS_FINISHED(&gz->z)) {
4046
+ if (gz->z.buf_filled > 0) gz->lineno++;
4047
+ return gzfile_read(gz, rslen);
4048
+ }
4049
+ gzfile_read_more(gz);
3803
4050
  }
3804
4051
 
3805
4052
  p = RSTRING_PTR(gz->z.buf);
3806
4053
  n = rslen;
3807
4054
  for (;;) {
3808
- long filled;
3809
- if (n > gz->z.buf_filled) {
3810
- if (ZSTREAM_IS_FINISHED(&gz->z)) break;
3811
- gzfile_read_more(gz);
3812
- p = RSTRING_PTR(gz->z.buf) + n - rslen;
3813
- }
3814
- if (!rspara) rscheck(rsptr, rslen, rs);
3815
- filled = gz->z.buf_filled;
3816
- if (limit > 0 && filled >= limit) {
3817
- filled = limit;
3818
- }
3819
- res = memchr(p, rsptr[0], (filled - n + 1));
3820
- if (!res) {
3821
- n = filled;
3822
- if (limit > 0 && filled >= limit) break;
3823
- n++;
3824
- } else {
3825
- n += (long)(res - p);
3826
- p = res;
3827
- if (rslen == 1 || memcmp(p, rsptr, rslen) == 0) break;
3828
- p++, n++;
3829
- }
4055
+ long filled;
4056
+ if (n > gz->z.buf_filled) {
4057
+ if (ZSTREAM_IS_FINISHED(&gz->z)) break;
4058
+ gzfile_read_more(gz);
4059
+ p = RSTRING_PTR(gz->z.buf) + n - rslen;
4060
+ }
4061
+ if (!rspara) rscheck(rsptr, rslen, rs);
4062
+ filled = gz->z.buf_filled;
4063
+ if (limit > 0 && filled >= limit) {
4064
+ filled = limit;
4065
+ }
4066
+ res = memchr(p, rsptr[0], (filled - n + 1));
4067
+ if (!res) {
4068
+ n = filled;
4069
+ if (limit > 0 && filled >= limit) break;
4070
+ n++;
4071
+ } else {
4072
+ n += (long)(res - p);
4073
+ p = res;
4074
+ if (rslen == 1 || memcmp(p, rsptr, rslen) == 0) break;
4075
+ p++, n++;
4076
+ }
3830
4077
  }
3831
4078
  if (maxlen > 1 && n == limit && (gz->z.buf_filled > n || !ZSTREAM_IS_FINISHED(&gz->z))) {
3832
- n = gzreader_charboundary(gz, n);
4079
+ n = gzreader_charboundary(gz, n);
3833
4080
  }
3834
4081
 
3835
4082
  gz->lineno++;
3836
4083
  dst = gzfile_read(gz, n);
4084
+ if (NIL_P(dst)) return dst;
3837
4085
  if (rspara) {
3838
- gzreader_skip_linebreaks(gz);
4086
+ gzreader_skip_linebreaks(gz);
3839
4087
  }
3840
4088
 
3841
4089
  return gzfile_newstr(gz, dst);
@@ -3852,7 +4100,7 @@ rb_gzreader_gets(int argc, VALUE *argv, VALUE obj)
3852
4100
  VALUE dst;
3853
4101
  dst = gzreader_gets(argc, argv, obj);
3854
4102
  if (!NIL_P(dst)) {
3855
- rb_lastline_set(dst);
4103
+ rb_lastline_set(dst);
3856
4104
  }
3857
4105
  return dst;
3858
4106
  }
@@ -3868,7 +4116,7 @@ rb_gzreader_readline(int argc, VALUE *argv, VALUE obj)
3868
4116
  VALUE dst;
3869
4117
  dst = rb_gzreader_gets(argc, argv, obj);
3870
4118
  if (NIL_P(dst)) {
3871
- rb_raise(rb_eEOFError, "end of file reached");
4119
+ rb_raise(rb_eEOFError, "end of file reached");
3872
4120
  }
3873
4121
  return dst;
3874
4122
  }
@@ -3886,11 +4134,25 @@ rb_gzreader_each(int argc, VALUE *argv, VALUE obj)
3886
4134
  RETURN_ENUMERATOR(obj, 0, 0);
3887
4135
 
3888
4136
  while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
3889
- rb_yield(str);
4137
+ rb_yield(str);
3890
4138
  }
3891
4139
  return obj;
3892
4140
  }
3893
4141
 
4142
+ /*
4143
+ * Document-method: Zlib::GzipReader#lines
4144
+ *
4145
+ * This is a deprecated alias for <code>each_line</code>.
4146
+ */
4147
+ static VALUE
4148
+ rb_gzreader_lines(int argc, VALUE *argv, VALUE obj)
4149
+ {
4150
+ rb_warn("Zlib::GzipReader#lines is deprecated; use #each_line instead");
4151
+ if (!rb_block_given_p())
4152
+ return rb_enumeratorize(obj, ID2SYM(rb_intern("each_line")), argc, argv);
4153
+ return rb_gzreader_each(argc, argv, obj);
4154
+ }
4155
+
3894
4156
  /*
3895
4157
  * Document-method: Zlib::GzipReader#readlines
3896
4158
  *
@@ -3902,96 +4164,13 @@ rb_gzreader_readlines(int argc, VALUE *argv, VALUE obj)
3902
4164
  VALUE str, dst;
3903
4165
  dst = rb_ary_new();
3904
4166
  while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
3905
- rb_ary_push(dst, str);
4167
+ rb_ary_push(dst, str);
3906
4168
  }
3907
4169
  return dst;
3908
4170
  }
3909
4171
 
3910
4172
  #endif /* GZIP_SUPPORT */
3911
4173
 
3912
-
3913
-
3914
- /*
3915
- * Document-module: Zlib
3916
- *
3917
- * The Zlib module contains several classes for compressing and decompressing
3918
- * streams, and for working with "gzip" files.
3919
- *
3920
- * == Classes
3921
- *
3922
- * Following are the classes that are most likely to be of interest to the
3923
- * user:
3924
- * Zlib::Inflate
3925
- * Zlib::Deflate
3926
- * Zlib::GzipReader
3927
- * Zlib::GzipWriter
3928
- *
3929
- * There are two important base classes for the classes above: Zlib::ZStream
3930
- * and Zlib::GzipFile. Everything else is an error class.
3931
- *
3932
- * == Constants
3933
- *
3934
- * Here's a list.
3935
- *
3936
- * Zlib::VERSION
3937
- * The Ruby/zlib version string.
3938
- *
3939
- * Zlib::ZLIB_VERSION
3940
- * The string which represents the version of zlib.h.
3941
- *
3942
- * Zlib::BINARY
3943
- * Zlib::ASCII
3944
- * Zlib::UNKNOWN
3945
- * The integers representing data types which Zlib::ZStream#data_type
3946
- * method returns.
3947
- *
3948
- * Zlib::NO_COMPRESSION
3949
- * Zlib::BEST_SPEED
3950
- * Zlib::BEST_COMPRESSION
3951
- * Zlib::DEFAULT_COMPRESSION
3952
- * The integers representing compression levels which are an argument
3953
- * for Zlib::Deflate.new, Zlib::Deflate#deflate, and so on.
3954
- *
3955
- * Zlib::FILTERED
3956
- * Zlib::HUFFMAN_ONLY
3957
- * Zlib::DEFAULT_STRATEGY
3958
- * The integers representing compression methods which are an argument
3959
- * for Zlib::Deflate.new and Zlib::Deflate#params.
3960
- *
3961
- * Zlib::DEF_MEM_LEVEL
3962
- * Zlib::MAX_MEM_LEVEL
3963
- * The integers representing memory levels which are an argument for
3964
- * Zlib::Deflate.new, Zlib::Deflate#params, and so on.
3965
- *
3966
- * Zlib::MAX_WBITS
3967
- * The default value of windowBits which is an argument for
3968
- * Zlib::Deflate.new and Zlib::Inflate.new.
3969
- *
3970
- * Zlib::NO_FLUSH
3971
- * Zlib::SYNC_FLUSH
3972
- * Zlib::FULL_FLUSH
3973
- * Zlib::FINISH
3974
- * The integers to control the output of the deflate stream, which are
3975
- * an argument for Zlib::Deflate#deflate and so on.
3976
- *
3977
- * Zlib::OS_CODE
3978
- * Zlib::OS_MSDOS
3979
- * Zlib::OS_AMIGA
3980
- * Zlib::OS_VMS
3981
- * Zlib::OS_UNIX
3982
- * Zlib::OS_VMCMS
3983
- * Zlib::OS_ATARI
3984
- * Zlib::OS_OS2
3985
- * Zlib::OS_MACOS
3986
- * Zlib::OS_ZSYSTEM
3987
- * Zlib::OS_CPM
3988
- * Zlib::OS_TOPS20
3989
- * Zlib::OS_WIN32
3990
- * Zlib::OS_QDOS
3991
- * Zlib::OS_RISCOS
3992
- * Zlib::OS_UNKNOWN
3993
- * The return values of Zlib::GzipFile#os_code method.
3994
- */
3995
4174
  void
3996
4175
  Init_zlib()
3997
4176
  {
@@ -4002,6 +4181,8 @@ Init_zlib()
4002
4181
 
4003
4182
  mZlib = rb_define_module("Zlib");
4004
4183
 
4184
+ id_dictionaries = rb_intern("@dictionaries");
4185
+
4005
4186
  cZError = rb_define_class_under(mZlib, "Error", rb_eStandardError);
4006
4187
  cStreamEnd = rb_define_class_under(mZlib, "StreamEnd", cZError);
4007
4188
  cNeedDict = rb_define_class_under(mZlib, "NeedDict", cZError);
@@ -4043,14 +4224,29 @@ Init_zlib()
4043
4224
  rb_define_method(cZStream, "flush_next_in", rb_zstream_flush_next_in, 0);
4044
4225
  rb_define_method(cZStream, "flush_next_out", rb_zstream_flush_next_out, 0);
4045
4226
 
4046
- /* Integer representing date types which
4047
- * ZStream#data_type method returns */
4227
+ /* Represents binary data as guessed by deflate.
4228
+ *
4229
+ * See Zlib::Deflate#data_type. */
4048
4230
  rb_define_const(mZlib, "BINARY", INT2FIX(Z_BINARY));
4049
- /* Integer representing date types which
4050
- * ZStream#data_type method returns */
4231
+
4232
+ /* Represents text data as guessed by deflate.
4233
+ *
4234
+ * NOTE: The underlying constant Z_ASCII was deprecated in favor of Z_TEXT
4235
+ * in zlib 1.2.2. New applications should not use this constant.
4236
+ *
4237
+ * See Zlib::Deflate#data_type. */
4051
4238
  rb_define_const(mZlib, "ASCII", INT2FIX(Z_ASCII));
4052
- /* Integer representing date types which
4053
- * ZStream#data_type method returns */
4239
+
4240
+ #ifdef Z_TEXT
4241
+ /* Represents text data as guessed by deflate.
4242
+ *
4243
+ * See Zlib::Deflate#data_type. */
4244
+ rb_define_const(mZlib, "TEXT", INT2FIX(Z_TEXT));
4245
+ #endif
4246
+
4247
+ /* Represents an unknown data type as guessed by deflate.
4248
+ *
4249
+ * See Zlib::Deflate#data_type. */
4054
4250
  rb_define_const(mZlib, "UNKNOWN", INT2FIX(Z_UNKNOWN));
4055
4251
 
4056
4252
  cDeflate = rb_define_class_under(mZlib, "Deflate", cZStream);
@@ -4070,77 +4266,91 @@ Init_zlib()
4070
4266
  rb_define_singleton_method(mZlib, "inflate", rb_inflate_s_inflate, 1);
4071
4267
  rb_define_alloc_func(cInflate, rb_inflate_s_allocate);
4072
4268
  rb_define_method(cInflate, "initialize", rb_inflate_initialize, -1);
4269
+ rb_define_method(cInflate, "add_dictionary", rb_inflate_add_dictionary, 1);
4073
4270
  rb_define_method(cInflate, "inflate", rb_inflate_inflate, 1);
4074
4271
  rb_define_method(cInflate, "<<", rb_inflate_addstr, 1);
4075
4272
  rb_define_method(cInflate, "sync", rb_inflate_sync, 1);
4076
4273
  rb_define_method(cInflate, "sync_point?", rb_inflate_sync_point_p, 0);
4077
4274
  rb_define_method(cInflate, "set_dictionary", rb_inflate_set_dictionary, 1);
4078
4275
 
4079
- /* compression level 0
4080
- *
4081
- * Which is an argument for Deflate.new, Deflate#deflate, and so on. */
4276
+ /* No compression, passes through data untouched. Use this for appending
4277
+ * pre-compressed data to a deflate stream.
4278
+ */
4082
4279
  rb_define_const(mZlib, "NO_COMPRESSION", INT2FIX(Z_NO_COMPRESSION));
4083
- /* compression level 1
4084
- *
4085
- * Which is an argument for Deflate.new, Deflate#deflate, and so on. */
4280
+ /* Fastest compression level, but with with lowest space savings. */
4086
4281
  rb_define_const(mZlib, "BEST_SPEED", INT2FIX(Z_BEST_SPEED));
4087
- /* compression level 9
4088
- *
4089
- * Which is an argument for Deflate.new, Deflate#deflate, and so on. */
4282
+ /* Slowest compression level, but with the best space savings. */
4090
4283
  rb_define_const(mZlib, "BEST_COMPRESSION", INT2FIX(Z_BEST_COMPRESSION));
4091
- /* compression level -1
4092
- *
4093
- * Which is an argument for Deflate.new, Deflate#deflate, and so on. */
4284
+ /* Default compression level which is a good trade-off between space and
4285
+ * time
4286
+ */
4094
4287
  rb_define_const(mZlib, "DEFAULT_COMPRESSION",
4095
- INT2FIX(Z_DEFAULT_COMPRESSION));
4096
-
4097
- /* compression method 1
4098
- *
4099
- * Which is an argument for Deflate.new and Deflate#params. */
4288
+ INT2FIX(Z_DEFAULT_COMPRESSION));
4289
+
4290
+ /* Deflate strategy for data produced by a filter (or predictor). The
4291
+ * effect of FILTERED is to force more Huffman codes and less string
4292
+ * matching; it is somewhat intermediate between DEFAULT_STRATEGY and
4293
+ * HUFFMAN_ONLY. Filtered data consists mostly of small values with a
4294
+ * somewhat random distribution.
4295
+ */
4100
4296
  rb_define_const(mZlib, "FILTERED", INT2FIX(Z_FILTERED));
4101
- /* compression method 2
4102
- *
4103
- * Which is an argument for Deflate.new and Deflate#params. */
4297
+
4298
+ /* Deflate strategy which uses Huffman codes only (no string matching). */
4104
4299
  rb_define_const(mZlib, "HUFFMAN_ONLY", INT2FIX(Z_HUFFMAN_ONLY));
4105
- /* compression method 0
4106
- *
4107
- * Which is an argument for Deflate.new and Deflate#params. */
4300
+
4301
+ #ifdef Z_RLE
4302
+ /* Deflate compression strategy designed to be almost as fast as
4303
+ * HUFFMAN_ONLY, but give better compression for PNG image data.
4304
+ */
4305
+ rb_define_const(mZlib, "RLE", INT2FIX(Z_RLE));
4306
+ #endif
4307
+
4308
+ #ifdef Z_FIXED
4309
+ /* Deflate strategy which prevents the use of dynamic Huffman codes,
4310
+ * allowing for a simpler decoder for specialized applications.
4311
+ */
4312
+ rb_define_const(mZlib, "FIXED", INT2FIX(Z_FIXED));
4313
+ #endif
4314
+
4315
+ /* Default deflate strategy which is used for normal data. */
4108
4316
  rb_define_const(mZlib, "DEFAULT_STRATEGY", INT2FIX(Z_DEFAULT_STRATEGY));
4109
4317
 
4110
- /* The default value of windowBits which is an argument for
4111
- * Deflate.new and Inflate.new.
4112
- */
4318
+ /* The maximum size of the zlib history buffer. Note that zlib allows
4319
+ * larger values to enable different inflate modes. See Zlib::Inflate.new
4320
+ * for details.
4321
+ */
4113
4322
  rb_define_const(mZlib, "MAX_WBITS", INT2FIX(MAX_WBITS));
4114
- /* Default value is 8
4115
- *
4116
- * The integer representing memory levels.
4117
- * Which are an argument for Deflate.new, Deflate#params, and so on. */
4323
+
4324
+ /* The default memory level for allocating zlib deflate compression state.
4325
+ */
4118
4326
  rb_define_const(mZlib, "DEF_MEM_LEVEL", INT2FIX(DEF_MEM_LEVEL));
4119
- /* Maximum level is 9
4120
- *
4121
- * The integers representing memory levels which are an argument for
4122
- * Deflate.new, Deflate#params, and so on. */
4327
+
4328
+ /* The maximum memory level for allocating zlib deflate compression state.
4329
+ */
4123
4330
  rb_define_const(mZlib, "MAX_MEM_LEVEL", INT2FIX(MAX_MEM_LEVEL));
4124
4331
 
4125
- /* Output control - 0
4126
- *
4127
- * The integers to control the output of the deflate stream, which are
4128
- * an argument for Deflate#deflate and so on. */
4332
+ /* NO_FLUSH is the default flush method and allows deflate to decide how
4333
+ * much data to accumulate before producing output in order to maximize
4334
+ * compression.
4335
+ */
4129
4336
  rb_define_const(mZlib, "NO_FLUSH", INT2FIX(Z_NO_FLUSH));
4130
- /* Output control - 2
4131
- *
4132
- * The integers to control the output of the deflate stream, which are
4133
- * an argument for Deflate#deflate and so on. */
4337
+
4338
+ /* The SYNC_FLUSH method flushes all pending output to the output buffer
4339
+ * and the output is aligned on a byte boundary. Flushing may degrade
4340
+ * compression so it should be used only when necessary, such as at a
4341
+ * request or response boundary for a network stream.
4342
+ */
4134
4343
  rb_define_const(mZlib, "SYNC_FLUSH", INT2FIX(Z_SYNC_FLUSH));
4135
- /* Output control - 3
4136
- *
4137
- * The integers to control the output of the deflate stream, which are
4138
- * an argument for Deflate#deflate and so on. */
4344
+
4345
+ /* Flushes all output as with SYNC_FLUSH, and the compression state is
4346
+ * reset so that decompression can restart from this point if previous
4347
+ * compressed data has been damaged or if random access is desired. Like
4348
+ * SYNC_FLUSH, using FULL_FLUSH too often can seriously degrade
4349
+ * compression.
4350
+ */
4139
4351
  rb_define_const(mZlib, "FULL_FLUSH", INT2FIX(Z_FULL_FLUSH));
4140
- /* Oputput control - 4
4141
- *
4142
- * The integers to control the output of the deflate stream, which are
4143
- * an argument for Deflate#deflate and so on. */
4352
+
4353
+ /* Processes all pending input and flushes pending output. */
4144
4354
  rb_define_const(mZlib, "FINISH", INT2FIX(Z_FINISH));
4145
4355
 
4146
4356
  #if GZIP_SUPPORT
@@ -4218,48 +4428,47 @@ Init_zlib()
4218
4428
  rb_define_method(cGzipReader, "readbyte", rb_gzreader_readbyte, 0);
4219
4429
  rb_define_method(cGzipReader, "each_byte", rb_gzreader_each_byte, 0);
4220
4430
  rb_define_method(cGzipReader, "each_char", rb_gzreader_each_char, 0);
4221
- rb_define_method(cGzipReader, "bytes", rb_gzreader_each_byte, 0);
4431
+ rb_define_method(cGzipReader, "bytes", rb_gzreader_bytes, 0);
4222
4432
  rb_define_method(cGzipReader, "ungetc", rb_gzreader_ungetc, 1);
4223
4433
  rb_define_method(cGzipReader, "ungetbyte", rb_gzreader_ungetbyte, 1);
4224
4434
  rb_define_method(cGzipReader, "gets", rb_gzreader_gets, -1);
4225
4435
  rb_define_method(cGzipReader, "readline", rb_gzreader_readline, -1);
4226
4436
  rb_define_method(cGzipReader, "each", rb_gzreader_each, -1);
4227
4437
  rb_define_method(cGzipReader, "each_line", rb_gzreader_each, -1);
4228
- rb_define_method(cGzipReader, "lines", rb_gzreader_each, -1);
4438
+ rb_define_method(cGzipReader, "lines", rb_gzreader_lines, -1);
4229
4439
  rb_define_method(cGzipReader, "readlines", rb_gzreader_readlines, -1);
4230
4440
 
4231
- /* From GzipFile#os_code - code of current host */
4441
+ /* The OS code of current host */
4232
4442
  rb_define_const(mZlib, "OS_CODE", INT2FIX(OS_CODE));
4233
- /* From GzipFile#os_code - 0x00 */
4443
+ /* OS code for MSDOS hosts */
4234
4444
  rb_define_const(mZlib, "OS_MSDOS", INT2FIX(OS_MSDOS));
4235
- /* From GzipFile#os_code - 0x01 */
4445
+ /* OS code for Amiga hosts */
4236
4446
  rb_define_const(mZlib, "OS_AMIGA", INT2FIX(OS_AMIGA));
4237
- /* From GzipFile#os_code - 0x02 */
4447
+ /* OS code for VMS hosts */
4238
4448
  rb_define_const(mZlib, "OS_VMS", INT2FIX(OS_VMS));
4239
- /* From GzipFile#os_code - 0x03 */
4449
+ /* OS code for UNIX hosts */
4240
4450
  rb_define_const(mZlib, "OS_UNIX", INT2FIX(OS_UNIX));
4241
- /* From GzipFile#os_code - 0x05 */
4451
+ /* OS code for Atari hosts */
4242
4452
  rb_define_const(mZlib, "OS_ATARI", INT2FIX(OS_ATARI));
4243
- /* From GzipFile#os_code - 0x06 */
4453
+ /* OS code for OS2 hosts */
4244
4454
  rb_define_const(mZlib, "OS_OS2", INT2FIX(OS_OS2));
4245
- /* From GzipFile#os_code - 0x07 */
4455
+ /* OS code for Mac OS hosts */
4246
4456
  rb_define_const(mZlib, "OS_MACOS", INT2FIX(OS_MACOS));
4247
- /* From GzipFile#os_code - 0x0a */
4457
+ /* OS code for TOPS-20 hosts */
4248
4458
  rb_define_const(mZlib, "OS_TOPS20", INT2FIX(OS_TOPS20));
4249
- /* From GzipFile#os_code - 0x0b */
4459
+ /* OS code for Win32 hosts */
4250
4460
  rb_define_const(mZlib, "OS_WIN32", INT2FIX(OS_WIN32));
4251
-
4252
- /* From GzipFile#os_code - 0x04 */
4461
+ /* OS code for VM OS hosts */
4253
4462
  rb_define_const(mZlib, "OS_VMCMS", INT2FIX(OS_VMCMS));
4254
- /* From GzipFile#os_code - 0x08 */
4463
+ /* OS code for Z-System hosts */
4255
4464
  rb_define_const(mZlib, "OS_ZSYSTEM", INT2FIX(OS_ZSYSTEM));
4256
- /* From GzipFile#os_code - 0x09 */
4465
+ /* OS code for CP/M hosts */
4257
4466
  rb_define_const(mZlib, "OS_CPM", INT2FIX(OS_CPM));
4258
- /* From GzipFile#os_code - 0x0c */
4467
+ /* OS code for QDOS hosts */
4259
4468
  rb_define_const(mZlib, "OS_QDOS", INT2FIX(OS_QDOS));
4260
- /* From GzipFile#os_code - 0x0d */
4469
+ /* OS code for RISC OS hosts */
4261
4470
  rb_define_const(mZlib, "OS_RISCOS", INT2FIX(OS_RISCOS));
4262
- /* From GzipFile#os_code - 0xff */
4471
+ /* OS code for unknown hosts */
4263
4472
  rb_define_const(mZlib, "OS_UNKNOWN", INT2FIX(OS_UNKNOWN));
4264
4473
 
4265
4474
  #endif /* GZIP_SUPPORT */