rubysl-zlib 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 */