Ruby  2.0.0p247(2013-06-27revision41674)
zlib.c
Go to the documentation of this file.
1 /*
2  * zlib.c - An interface for zlib.
3  *
4  * Copyright (C) UENO Katsuhiro 2000-2003
5  *
6  * $Id: zlib.c 41073 2013-06-04 15:44:57Z nagachika $
7  */
8 
9 #include <ruby.h>
10 #include <zlib.h>
11 #include <time.h>
12 #include <ruby/io.h>
13 #include <ruby/thread.h>
14 
15 #ifdef HAVE_VALGRIND_MEMCHECK_H
16 # include <valgrind/memcheck.h>
17 # ifndef VALGRIND_MAKE_MEM_DEFINED
18 # define VALGRIND_MAKE_MEM_DEFINED(p, n) VALGRIND_MAKE_READABLE((p), (n))
19 # endif
20 # ifndef VALGRIND_MAKE_MEM_UNDEFINED
21 # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) VALGRIND_MAKE_WRITABLE((p), (n))
22 # endif
23 #else
24 # define VALGRIND_MAKE_MEM_DEFINED(p, n) 0
25 # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
26 #endif
27 
28 #define RUBY_ZLIB_VERSION "0.6.0"
29 
30 
31 #define OBJ_IS_FREED(val) (RBASIC(val)->flags == 0)
32 
33 #ifndef GZIP_SUPPORT
34 #define GZIP_SUPPORT 1
35 #endif
36 
37 /* from zutil.h */
38 #ifndef DEF_MEM_LEVEL
39 #if MAX_MEM_LEVEL >= 8
40 #define DEF_MEM_LEVEL 8
41 #else
42 #define DEF_MEM_LEVEL MAX_MEM_LEVEL
43 #endif
44 #endif
45 
46 #if SIZEOF_LONG > SIZEOF_INT
47 static inline uInt
48 max_uint(long n)
49 {
50  if (n > UINT_MAX) n = UINT_MAX;
51  return (uInt)n;
52 }
53 #define MAX_UINT(n) max_uint(n)
54 #else
55 #define MAX_UINT(n) (uInt)(n)
56 #endif
57 
58 #define sizeof(x) ((int)sizeof(x))
59 
61 
62 /*--------- Prototypes --------*/
63 
64 static NORETURN(void raise_zlib_error(int, const char*));
66 static VALUE do_checksum(int, VALUE*, uLong (*)(uLong, const Bytef*, uInt));
67 static VALUE rb_zlib_adler32(int, VALUE*, VALUE);
68 static VALUE rb_zlib_crc32(int, VALUE*, VALUE);
70 static voidpf zlib_mem_alloc(voidpf, uInt, uInt);
71 static void zlib_mem_free(voidpf, voidpf);
72 static void finalizer_warn(const char*);
73 
74 struct zstream;
75 struct zstream_funcs;
76 struct zstream_run_args;
77 static void zstream_init(struct zstream*, const struct zstream_funcs*);
78 static void zstream_expand_buffer(struct zstream*);
79 static void zstream_expand_buffer_into(struct zstream*, unsigned long);
80 static void zstream_append_buffer(struct zstream*, const Bytef*, long);
81 static VALUE zstream_detach_buffer(struct zstream*);
82 static VALUE zstream_shift_buffer(struct zstream*, long);
83 static void zstream_buffer_ungets(struct zstream*, const Bytef*, unsigned long);
84 static void zstream_buffer_ungetbyte(struct zstream*, int);
85 static void zstream_append_input(struct zstream*, const Bytef*, long);
86 static void zstream_discard_input(struct zstream*, long);
87 static void zstream_reset_input(struct zstream*);
88 static void zstream_passthrough_input(struct zstream*);
89 static VALUE zstream_detach_input(struct zstream*);
90 static void zstream_reset(struct zstream*);
91 static VALUE zstream_end(struct zstream*);
92 static void zstream_run(struct zstream*, Bytef*, long, int);
93 static VALUE zstream_sync(struct zstream*, Bytef*, long);
94 static void zstream_mark(struct zstream*);
95 static void zstream_free(struct zstream*);
96 static VALUE zstream_new(VALUE, const struct zstream_funcs*);
97 static struct zstream *get_zstream(VALUE);
98 static void zstream_finalize(struct zstream*);
99 
100 static VALUE rb_zstream_end(VALUE);
114 
116 static VALUE rb_deflate_initialize(int, VALUE*, VALUE);
118 static VALUE deflate_run(VALUE);
119 static VALUE rb_deflate_s_deflate(int, VALUE*, VALUE);
120 static void do_deflate(struct zstream*, VALUE, int);
121 static VALUE rb_deflate_deflate(int, VALUE*, VALUE);
123 static VALUE rb_deflate_flush(int, VALUE*, VALUE);
126 
127 static VALUE inflate_run(VALUE);
129 static VALUE rb_inflate_initialize(int, VALUE*, VALUE);
131 static void do_inflate(struct zstream*, VALUE);
137 
138 #if GZIP_SUPPORT
139 struct gzfile;
140 static void gzfile_mark(struct gzfile*);
141 static void gzfile_free(struct gzfile*);
142 static VALUE gzfile_new(VALUE, const struct zstream_funcs*, void (*) _((struct gzfile*)));
143 static void gzfile_reset(struct gzfile*);
144 static void gzfile_close(struct gzfile*, int);
145 static void gzfile_write_raw(struct gzfile*);
148 static VALUE gzfile_read_raw(struct gzfile*);
149 static int gzfile_read_raw_ensure(struct gzfile*, long);
150 static char *gzfile_read_raw_until_zero(struct gzfile*, long);
151 static unsigned int gzfile_get16(const unsigned char*);
152 static unsigned long gzfile_get32(const unsigned char*);
153 static void gzfile_set32(unsigned long n, unsigned char*);
154 static void gzfile_make_header(struct gzfile*);
155 static void gzfile_make_footer(struct gzfile*);
156 static void gzfile_read_header(struct gzfile*);
157 static void gzfile_check_footer(struct gzfile*);
158 static void gzfile_write(struct gzfile*, Bytef*, long);
159 static long gzfile_read_more(struct gzfile*);
160 static void gzfile_calc_crc(struct gzfile*, VALUE);
161 static VALUE gzfile_read(struct gzfile*, long);
162 static VALUE gzfile_read_all(struct gzfile*);
163 static void gzfile_ungets(struct gzfile*, const Bytef*, long);
164 static void gzfile_ungetbyte(struct gzfile*, int);
166 static void gzfile_writer_end(struct gzfile*);
168 static void gzfile_reader_end(struct gzfile*);
169 static void gzfile_reader_rewind(struct gzfile*);
170 static VALUE gzfile_reader_get_unused(struct gzfile*);
171 static struct gzfile *get_gzfile(VALUE);
173 static VALUE rb_gzfile_s_wrap(int, VALUE*, VALUE);
174 static VALUE gzfile_s_open(int, VALUE*, VALUE, const char*);
175 NORETURN(static void gzfile_raise(struct gzfile *, VALUE, const char *));
177 
178 static VALUE rb_gzfile_to_io(VALUE);
179 static VALUE rb_gzfile_crc(VALUE);
180 static VALUE rb_gzfile_mtime(VALUE);
181 static VALUE rb_gzfile_level(VALUE);
190 static VALUE rb_gzfile_close(VALUE);
193 static VALUE rb_gzfile_eof_p(VALUE);
194 static VALUE rb_gzfile_sync(VALUE);
198 static VALUE rb_gzfile_path(VALUE);
199 
201 static VALUE rb_gzwriter_s_open(int, VALUE*, VALUE);
202 static VALUE rb_gzwriter_initialize(int, VALUE*, VALUE);
203 static VALUE rb_gzwriter_flush(int, VALUE*, VALUE);
206 
208 static VALUE rb_gzreader_s_open(int, VALUE*, VALUE);
209 static VALUE rb_gzreader_initialize(int, VALUE*, VALUE);
212 static VALUE rb_gzreader_read(int, VALUE*, VALUE);
218 static void gzreader_skip_linebreaks(struct gzfile*);
219 static VALUE gzreader_gets(int, VALUE*, VALUE);
220 static VALUE rb_gzreader_gets(int, VALUE*, VALUE);
221 static VALUE rb_gzreader_readline(int, VALUE*, VALUE);
222 static VALUE rb_gzreader_each(int, VALUE*, VALUE);
223 static VALUE rb_gzreader_readlines(int, VALUE*, VALUE);
224 #endif /* GZIP_SUPPORT */
225 
226 /*
227  * Document-module: Zlib
228  *
229  * This module provides access to the {zlib library}[http://zlib.net]. Zlib is
230  * designed to be a portable, free, general-purpose, legally unencumbered --
231  * that is, not covered by any patents -- lossless data-compression library
232  * for use on virtually any computer hardware and operating system.
233  *
234  * The zlib compression library provides in-memory compression and
235  * decompression functions, including integrity checks of the uncompressed
236  * data.
237  *
238  * The zlib compressed data format is described in RFC 1950, which is a
239  * wrapper around a deflate stream which is described in RFC 1951.
240  *
241  * The library also supports reading and writing files in gzip (.gz) format
242  * with an interface similar to that of IO. The gzip format is described in
243  * RFC 1952 which is also a wrapper around a deflate stream.
244  *
245  * The zlib format was designed to be compact and fast for use in memory and on
246  * communications channels. The gzip format was designed for single-file
247  * compression on file systems, has a larger header than zlib to maintain
248  * directory information, and uses a different, slower check method than zlib.
249  *
250  * See your system's zlib.h for further information about zlib
251  *
252  * == Sample usage
253  *
254  * Using the wrapper to compress strings with default parameters is quite
255  * simple:
256  *
257  * require "zlib"
258  *
259  * data_to_compress = File.read("don_quixote.txt")
260  *
261  * puts "Input size: #{data_to_compress.size}"
262  * #=> Input size: 2347740
263  *
264  * data_compressed = Zlib::Deflate.deflate(data_to_compress)
265  *
266  * puts "Compressed size: #{data_compressed.size}"
267  * #=> Compressed size: 887238
268  *
269  * uncompressed_data = Zlib::Inflate.inflate(data_compressed)
270  *
271  * puts "Uncompressed data is: #{uncompressed_data}"
272  * #=> Uncompressed data is: The Project Gutenberg EBook of Don Quixote...
273  *
274  * == Class tree
275  *
276  * - Zlib::Deflate
277  * - Zlib::Inflate
278  * - Zlib::ZStream
279  * - Zlib::Error
280  * - Zlib::StreamEnd
281  * - Zlib::NeedDict
282  * - Zlib::DataError
283  * - Zlib::StreamError
284  * - Zlib::MemError
285  * - Zlib::BufError
286  * - Zlib::VersionError
287  *
288  * (if you have GZIP_SUPPORT)
289  * - Zlib::GzipReader
290  * - Zlib::GzipWriter
291  * - Zlib::GzipFile
292  * - Zlib::GzipFile::Error
293  * - Zlib::GzipFile::LengthError
294  * - Zlib::GzipFile::CRCError
295  * - Zlib::GzipFile::NoFooter
296  *
297  */
298 void Init_zlib(void);
299 
300 /*--------- Exceptions --------*/
301 
304 
305 static void
306 raise_zlib_error(int err, const char *msg)
307 {
308  VALUE exc;
309 
310  if (!msg) {
311  msg = zError(err);
312  }
313 
314  switch(err) {
315  case Z_STREAM_END:
316  exc = rb_exc_new2(cStreamEnd, msg);
317  break;
318  case Z_NEED_DICT:
319  exc = rb_exc_new2(cNeedDict, msg);
320  break;
321  case Z_STREAM_ERROR:
322  exc = rb_exc_new2(cStreamError, msg);
323  break;
324  case Z_DATA_ERROR:
325  exc = rb_exc_new2(cDataError, msg);
326  break;
327  case Z_BUF_ERROR:
328  exc = rb_exc_new2(cBufError, msg);
329  break;
330  case Z_VERSION_ERROR:
331  exc = rb_exc_new2(cVersionError, msg);
332  break;
333  case Z_MEM_ERROR:
334  exc = rb_exc_new2(cMemError, msg);
335  break;
336  case Z_ERRNO:
337  rb_sys_fail(msg);
338  /* no return */
339  default:
340  {
341  char buf[BUFSIZ];
342  snprintf(buf, BUFSIZ, "unknown zlib error %d: %s", err, msg);
343  exc = rb_exc_new2(cZError, buf);
344  }
345  }
346 
347  rb_exc_raise(exc);
348 }
349 
350 
351 /*--- Warning (in finalizer) ---*/
352 
353 static void
354 finalizer_warn(const char *msg)
355 {
356  fprintf(stderr, "zlib(finalizer): %s\n", msg);
357 }
358 
359 
360 /*-------- module Zlib --------*/
361 
362 /*
363  * Document-method: Zlib.zlib_version
364  *
365  * Returns the string which represents the version of zlib library.
366  */
367 static VALUE
369 {
370  VALUE str;
371 
372  str = rb_str_new2(zlibVersion());
373  OBJ_TAINT(str); /* for safe */
374  return str;
375 }
376 
377 #if SIZEOF_LONG > SIZEOF_INT
378 static uLong
379 checksum_long(uLong (*func)(uLong, const Bytef*, uInt), uLong sum, const Bytef *ptr, long len)
380 {
381  if (len > UINT_MAX) {
382  do {
383  sum = func(sum, ptr, UINT_MAX);
384  ptr += UINT_MAX;
385  len -= UINT_MAX;
386  } while (len >= UINT_MAX);
387  }
388  if (len > 0) sum = func(sum, ptr, (uInt)len);
389  return sum;
390 }
391 #else
392 #define checksum_long(func, sum, ptr, len) (func)((sum), (ptr), (len))
393 #endif
394 
395 static VALUE
399  uLong (*func)(uLong, const Bytef*, uInt);
400 {
401  VALUE str, vsum;
402  unsigned long sum;
403 
404  rb_scan_args(argc, argv, "02", &str, &vsum);
405 
406  if (!NIL_P(vsum)) {
407  sum = NUM2ULONG(vsum);
408  }
409  else if (NIL_P(str)) {
410  sum = 0;
411  }
412  else {
413  sum = func(0, Z_NULL, 0);
414  }
415 
416  if (NIL_P(str)) {
417  sum = func(sum, Z_NULL, 0);
418  }
419  else {
420  StringValue(str);
421  sum = checksum_long(func, sum, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
422  }
423  return rb_uint2inum(sum);
424 }
425 
426 /*
427  * Document-method: Zlib.adler32
428  *
429  * call-seq: Zlib.adler32(string, adler)
430  *
431  * Calculates Adler-32 checksum for +string+, and returns updated value of
432  * +adler+. If +string+ is omitted, it returns the Adler-32 initial value. If
433  * +adler+ is omitted, it assumes that the initial value is given to +adler+.
434  *
435  * FIXME: expression.
436  */
437 static VALUE
438 rb_zlib_adler32(int argc, VALUE *argv, VALUE klass)
439 {
440  return do_checksum(argc, argv, adler32);
441 }
442 
443 #ifdef HAVE_ADLER32_COMBINE
444 /*
445  * Document-method: Zlib.adler32_combine
446  *
447  * call-seq: Zlib.adler32_combine(adler1, adler2, len2)
448  *
449  * Combine two Adler-32 check values in to one. +alder1+ is the first Adler-32
450  * value, +adler2+ is the second Adler-32 value. +len2+ is the length of the
451  * string used to generate +adler2+.
452  *
453  */
454 static VALUE
455 rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2)
456 {
457  return ULONG2NUM(
458  adler32_combine(NUM2ULONG(adler1), NUM2ULONG(adler2), NUM2LONG(len2)));
459 }
460 #else
461 #define rb_zlib_adler32_combine rb_f_notimplement
462 #endif
463 
464 /*
465  * Document-method: Zlib.crc32
466  *
467  * call-seq: Zlib.crc32(string, adler)
468  *
469  * Calculates CRC checksum for +string+, and returns updated value of +crc+. If
470  * +string+ is omitted, it returns the CRC initial value. If +crc+ is omitted, it
471  * assumes that the initial value is given to +crc+.
472  *
473  * FIXME: expression.
474  */
475 static VALUE
476 rb_zlib_crc32(int argc, VALUE *argv, VALUE klass)
477 {
478  return do_checksum(argc, argv, crc32);
479 }
480 
481 #ifdef HAVE_CRC32_COMBINE
482 /*
483  * Document-method: Zlib.crc32_combine
484  *
485  * call-seq: Zlib.crc32_combine(crc1, crc2, len2)
486  *
487  * Combine two CRC-32 check values in to one. +crc1+ is the first CRC-32
488  * value, +crc2+ is the second CRC-32 value. +len2+ is the length of the
489  * string used to generate +crc2+.
490  *
491  */
492 static VALUE
493 rb_zlib_crc32_combine(VALUE klass, VALUE crc1, VALUE crc2, VALUE len2)
494 {
495  return ULONG2NUM(
496  crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2)));
497 }
498 #else
499 #define rb_zlib_crc32_combine rb_f_notimplement
500 #endif
501 
502 /*
503  * Document-method: Zlib.crc_table
504  *
505  * Returns the table for calculating CRC checksum as an array.
506  */
507 static VALUE
509 {
510 #if !defined(HAVE_TYPE_Z_CRC_T)
511  /* z_crc_t is defined since zlib-1.2.7. */
512  typedef unsigned long z_crc_t;
513 #endif
514  const z_crc_t *crctbl;
515  VALUE dst;
516  int i;
517 
518  crctbl = get_crc_table();
519  dst = rb_ary_new2(256);
520 
521  for (i = 0; i < 256; i++) {
522  rb_ary_push(dst, rb_uint2inum(crctbl[i]));
523  }
524  return dst;
525 }
526 
527 
528 
529 /*-------- zstream - internal APIs --------*/
530 
531 struct zstream {
532  unsigned long flags;
536  z_stream stream;
537  const struct zstream_funcs {
538  int (*reset)(z_streamp);
539  int (*end)(z_streamp);
540  int (*run)(z_streamp, int);
541  } *func;
542 };
543 
544 #define ZSTREAM_FLAG_READY 0x1
545 #define ZSTREAM_FLAG_IN_STREAM 0x2
546 #define ZSTREAM_FLAG_FINISHED 0x4
547 #define ZSTREAM_FLAG_CLOSING 0x8
548 #define ZSTREAM_FLAG_GZFILE 0x10 /* disallows yield from expand_buffer for
549  gzip*/
550 #define ZSTREAM_FLAG_UNUSED 0x20
551 
552 #define ZSTREAM_READY(z) ((z)->flags |= ZSTREAM_FLAG_READY)
553 #define ZSTREAM_IS_READY(z) ((z)->flags & ZSTREAM_FLAG_READY)
554 #define ZSTREAM_IS_FINISHED(z) ((z)->flags & ZSTREAM_FLAG_FINISHED)
555 #define ZSTREAM_IS_CLOSING(z) ((z)->flags & ZSTREAM_FLAG_CLOSING)
556 #define ZSTREAM_IS_GZFILE(z) ((z)->flags & ZSTREAM_FLAG_GZFILE)
557 
558 #define ZSTREAM_EXPAND_BUFFER_OK 0
559 
560 /* I think that more better value should be found,
561  but I gave up finding it. B) */
562 #define ZSTREAM_INITIAL_BUFSIZE 1024
563 /* Allow a quick return when the thread is interrupted */
564 #define ZSTREAM_AVAIL_OUT_STEP_MAX 16384
565 #define ZSTREAM_AVAIL_OUT_STEP_MIN 2048
566 
567 static const struct zstream_funcs deflate_funcs = {
568  deflateReset, deflateEnd, deflate,
569 };
570 
571 static const struct zstream_funcs inflate_funcs = {
572  inflateReset, inflateEnd, inflate,
573 };
574 
576  struct zstream * z;
577  int flush; /* stream flush value for inflate() or deflate() */
578  int interrupt; /* stop processing the stream and return to ruby */
579  int jump_state; /* for buffer expansion block break or exception */
580  int stream_output; /* for streaming zlib processing */
581 };
582 
583 static voidpf
584 zlib_mem_alloc(voidpf opaque, uInt items, uInt size)
585 {
586  voidpf p = xmalloc(items * size);
587  /* zlib FAQ: Valgrind (or some similar memory access checker) says that
588  deflate is performing a conditional jump that depends on an
589  uninitialized value. Isn't that a bug?
590  http://www.zlib.net/zlib_faq.html#faq36 */
591  (void)VALGRIND_MAKE_MEM_DEFINED(p, items * size);
592  return p;
593 }
594 
595 static void
596 zlib_mem_free(voidpf opaque, voidpf address)
597 {
598  xfree(address);
599 }
600 
601 static void
602 zstream_init(struct zstream *z, const struct zstream_funcs *func)
603 {
604  z->flags = 0;
605  z->buf = Qnil;
606  z->buf_filled = 0;
607  z->input = Qnil;
608  z->stream.zalloc = zlib_mem_alloc;
609  z->stream.zfree = zlib_mem_free;
610  z->stream.opaque = Z_NULL;
611  z->stream.msg = Z_NULL;
612  z->stream.next_in = Z_NULL;
613  z->stream.avail_in = 0;
614  z->stream.next_out = Z_NULL;
615  z->stream.avail_out = 0;
616  z->func = func;
617 }
618 
619 #define zstream_init_deflate(z) zstream_init((z), &deflate_funcs)
620 #define zstream_init_inflate(z) zstream_init((z), &inflate_funcs)
621 
622 static void
624 {
625  if (NIL_P(z->buf)) {
627  return;
628  }
629 
630  if (!ZSTREAM_IS_GZFILE(z) && rb_block_given_p()) {
632  int state = 0;
633  VALUE self = (VALUE)z->stream.opaque;
634 
635  rb_str_resize(z->buf, z->buf_filled);
636  RBASIC(z->buf)->klass = rb_cString;
637  OBJ_INFECT(z->buf, self);
638 
639  rb_protect(rb_yield, z->buf, &state);
640 
641  z->buf = Qnil;
643 
644  if (state)
645  rb_jump_tag(state);
646 
647  return;
648  }
649  else {
652  }
653  }
654  else {
656  z->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;
657  }
658  else {
659  long inc = z->buf_filled / 2;
660  if (inc < ZSTREAM_AVAIL_OUT_STEP_MIN) {
662  }
663  rb_str_resize(z->buf, z->buf_filled + inc);
664  z->stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?
665  (int)inc : ZSTREAM_AVAIL_OUT_STEP_MAX;
666  }
667  z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
668  }
669 }
670 
671 static void
672 zstream_expand_buffer_into(struct zstream *z, unsigned long size)
673 {
674  if (NIL_P(z->buf)) {
675  /* I uses rb_str_new here not rb_str_buf_new because
676  rb_str_buf_new makes a zero-length string. */
677  z->buf = rb_str_new(0, size);
678  z->buf_filled = 0;
679  z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
680  z->stream.avail_out = MAX_UINT(size);
681  RBASIC(z->buf)->klass = 0;
682  }
683  else if (z->stream.avail_out != size) {
684  rb_str_resize(z->buf, z->buf_filled + size);
685  z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
686  z->stream.avail_out = MAX_UINT(size);
687  }
688 }
689 
690 static void *
692 {
693  struct zstream *z = (struct zstream *)ptr;
694  int state = 0;
695 
696  rb_protect((VALUE (*)(VALUE))zstream_expand_buffer, (VALUE)z, &state);
697 
698  return (void *)(VALUE)state;
699 }
700 
701 static int
703 {
704  char * new_str;
705  long inc, len;
706 
708  z->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;
709  }
710  else {
711  inc = z->buf_filled / 2;
712  if (inc < ZSTREAM_AVAIL_OUT_STEP_MIN) {
714  }
715 
716  len = z->buf_filled + inc;
717 
718  new_str = ruby_xrealloc(RSTRING(z->buf)->as.heap.ptr, len + 1);
719 
720  /* from rb_str_resize */
721  RSTRING(z->buf)->as.heap.ptr = new_str;
722  RSTRING(z->buf)->as.heap.ptr[len] = '\0'; /* sentinel */
723  RSTRING(z->buf)->as.heap.len =
724  RSTRING(z->buf)->as.heap.aux.capa = len;
725 
726  z->stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?
727  (int)inc : ZSTREAM_AVAIL_OUT_STEP_MAX;
728  }
729  z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
730 
732 }
733 
734 static void
735 zstream_append_buffer(struct zstream *z, const Bytef *src, long len)
736 {
737  if (NIL_P(z->buf)) {
738  z->buf = rb_str_buf_new(len);
739  rb_str_buf_cat(z->buf, (const char*)src, len);
740  z->buf_filled = len;
741  z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
742  z->stream.avail_out = 0;
743  RBASIC(z->buf)->klass = 0;
744  return;
745  }
746 
747  if (RSTRING_LEN(z->buf) < z->buf_filled + len) {
748  rb_str_resize(z->buf, z->buf_filled + len);
749  z->stream.avail_out = 0;
750  }
751  else {
752  if (z->stream.avail_out >= (uInt)len) {
753  z->stream.avail_out -= (uInt)len;
754  }
755  else {
756  z->stream.avail_out = 0;
757  }
758  }
759  memcpy(RSTRING_PTR(z->buf) + z->buf_filled, src, len);
760  z->buf_filled += len;
761  z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
762 }
763 
764 #define zstream_append_buffer2(z,v) \
765  zstream_append_buffer((z),(Bytef*)RSTRING_PTR(v),RSTRING_LEN(v))
766 
767 static VALUE
769 {
770  VALUE dst, self = (VALUE)z->stream.opaque;
771 
773  rb_block_given_p()) {
774  /* prevent tiny yields mid-stream, save for next
775  * zstream_expand_buffer() or stream end */
776  return Qnil;
777  }
778 
779  if (NIL_P(z->buf)) {
780  dst = rb_str_new(0, 0);
781  }
782  else {
783  dst = z->buf;
784  rb_str_resize(dst, z->buf_filled);
785  RBASIC(dst)->klass = rb_cString;
786  }
787 
788  OBJ_INFECT(dst, self);
789 
790  z->buf = Qnil;
791  z->buf_filled = 0;
792  z->stream.next_out = 0;
793  z->stream.avail_out = 0;
794 
795  if (!ZSTREAM_IS_GZFILE(z) && rb_block_given_p()) {
796  rb_yield(dst);
797  dst = Qnil;
798  }
799 
800  return dst;
801 }
802 
803 static VALUE
804 zstream_shift_buffer(struct zstream *z, long len)
805 {
806  VALUE dst;
807  long buflen;
808 
809  if (z->buf_filled <= len) {
810  return zstream_detach_buffer(z);
811  }
812 
813  dst = rb_str_subseq(z->buf, 0, len);
814  RBASIC(dst)->klass = rb_cString;
815  z->buf_filled -= len;
816  memmove(RSTRING_PTR(z->buf), RSTRING_PTR(z->buf) + len,
817  z->buf_filled);
818  z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
819  buflen = RSTRING_LEN(z->buf) - z->buf_filled;
820  if (buflen > ZSTREAM_AVAIL_OUT_STEP_MAX) {
822  }
823  z->stream.avail_out = (uInt)buflen;
824 
825  return dst;
826 }
827 
828 static void
829 zstream_buffer_ungets(struct zstream *z, const Bytef *b, unsigned long len)
830 {
831  if (NIL_P(z->buf) || RSTRING_LEN(z->buf) - z->buf_filled == 0) {
833  }
834 
835  memmove(RSTRING_PTR(z->buf) + len, RSTRING_PTR(z->buf), z->buf_filled);
836  memmove(RSTRING_PTR(z->buf), b, len);
837  z->buf_filled+=len;
838  if (z->stream.avail_out > 0) {
839  if (len > z->stream.avail_out) len = z->stream.avail_out;
840  z->stream.next_out+=len;
841  z->stream.avail_out-=(uInt)len;
842  }
843 }
844 
845 static void
847 {
848  if (NIL_P(z->buf) || RSTRING_LEN(z->buf) - z->buf_filled == 0) {
850  }
851 
852  memmove(RSTRING_PTR(z->buf) + 1, RSTRING_PTR(z->buf), z->buf_filled);
853  RSTRING_PTR(z->buf)[0] = (char)c;
854  z->buf_filled++;
855  if (z->stream.avail_out > 0) {
856  z->stream.next_out++;
857  z->stream.avail_out--;
858  }
859 }
860 
861 static void
862 zstream_append_input(struct zstream *z, const Bytef *src, long len)
863 {
864  if (len <= 0) return;
865 
866  if (NIL_P(z->input)) {
867  z->input = rb_str_buf_new(len);
868  rb_str_buf_cat(z->input, (const char*)src, len);
869  RBASIC(z->input)->klass = 0;
870  }
871  else {
872  rb_str_buf_cat(z->input, (const char*)src, len);
873  }
874 }
875 
876 #define zstream_append_input2(z,v)\
877  RB_GC_GUARD(v),\
878  zstream_append_input((z), (Bytef*)RSTRING_PTR(v), RSTRING_LEN(v))
879 
880 static void
881 zstream_discard_input(struct zstream *z, long len)
882 {
883  if (NIL_P(z->input) || RSTRING_LEN(z->input) <= len) {
884  z->input = Qnil;
885  }
886  else {
887  memmove(RSTRING_PTR(z->input), RSTRING_PTR(z->input) + len,
888  RSTRING_LEN(z->input) - len);
889  rb_str_resize(z->input, RSTRING_LEN(z->input) - len);
890  }
891 }
892 
893 static void
895 {
896  z->input = Qnil;
897 }
898 
899 static void
901 {
902  if (!NIL_P(z->input)) {
904  z->input = Qnil;
905  }
906 }
907 
908 static VALUE
910 {
911  VALUE dst;
912 
913  if (NIL_P(z->input)) {
914  dst = rb_str_new(0, 0);
915  }
916  else {
917  dst = z->input;
918  RBASIC(dst)->klass = rb_cString;
919  }
920  z->input = Qnil;
921  RBASIC(dst)->klass = rb_cString;
922  return dst;
923 }
924 
925 static void
927 {
928  int err;
929 
930  err = z->func->reset(&z->stream);
931  if (err != Z_OK) {
932  raise_zlib_error(err, z->stream.msg);
933  }
935  z->buf = Qnil;
936  z->buf_filled = 0;
937  z->stream.next_out = 0;
938  z->stream.avail_out = 0;
940 }
941 
942 static VALUE
944 {
945  int err;
946 
947  if (!ZSTREAM_IS_READY(z)) {
948  rb_warning("attempt to close uninitialized zstream; ignored.");
949  return Qnil;
950  }
951  if (z->flags & ZSTREAM_FLAG_IN_STREAM) {
952  rb_warning("attempt to close unfinished zstream; reset forced.");
953  zstream_reset(z);
954  }
955 
957  err = z->func->end(&z->stream);
958  if (err != Z_OK) {
959  raise_zlib_error(err, z->stream.msg);
960  }
961  z->flags = 0;
962  return Qnil;
963 }
964 
965 static void *
967 {
968  struct zstream_run_args *args = (struct zstream_run_args *)ptr;
969  int err, state, flush = args->flush;
970  struct zstream *z = args->z;
971  uInt n;
972 
973  err = Z_OK;
974  while (!args->interrupt) {
975  n = z->stream.avail_out;
976  err = z->func->run(&z->stream, flush);
977  z->buf_filled += n - z->stream.avail_out;
978 
979  if (err == Z_STREAM_END) {
982  break;
983  }
984 
985  if (err != Z_OK && err != Z_BUF_ERROR)
986  break;
987 
988  if (z->stream.avail_out > 0) {
990  break;
991  }
992 
993  if (z->stream.avail_in == 0 && z->func == &inflate_funcs) {
994  /* break here because inflate() return Z_BUF_ERROR when avail_in == 0. */
995  /* but deflate() could be called with avail_in == 0 (there's hidden buffer
996  in zstream->state) */
998  break;
999  }
1000 
1001  if (args->stream_output) {
1003  (void *)z);
1004  } else {
1006  }
1007 
1008  if (state) {
1009  err = Z_OK; /* buffer expanded but stream processing was stopped */
1010  args->jump_state = state;
1011  break;
1012  }
1013  }
1014 
1015  return (void *)(VALUE)err;
1016 }
1017 
1018 /*
1019  * There is no safe way to interrupt z->run->func().
1020  */
1021 static void
1023 {
1024  struct zstream_run_args *args = (struct zstream_run_args *)ptr;
1025 
1026  args->interrupt = 1;
1027 }
1028 
1029 static void
1030 zstream_run(struct zstream *z, Bytef *src, long len, int flush)
1031 {
1032  struct zstream_run_args args;
1033  int err;
1034  volatile VALUE guard = Qnil;
1035 
1036  args.z = z;
1037  args.flush = flush;
1038  args.interrupt = 0;
1039  args.jump_state = 0;
1041 
1042  if (NIL_P(z->input) && len == 0) {
1043  z->stream.next_in = (Bytef*)"";
1044  z->stream.avail_in = 0;
1045  }
1046  else {
1047  zstream_append_input(z, src, len);
1048  z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
1049  z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input));
1050  /* keep reference to `z->input' so as not to be garbage collected
1051  after zstream_reset_input() and prevent `z->stream.next_in'
1052  from dangling. */
1053  guard = z->input;
1054  }
1055 
1056  if (z->stream.avail_out == 0) {
1058  }
1059 
1060 loop:
1061  err = (int)(VALUE)rb_thread_call_without_gvl(zstream_run_func, (void *)&args,
1062  zstream_unblock_func, (void *)&args);
1063 
1064  if (flush != Z_FINISH && err == Z_BUF_ERROR
1065  && z->stream.avail_out > 0) {
1067  }
1068 
1070 
1071  if (err != Z_OK && err != Z_STREAM_END) {
1072  if (z->stream.avail_in > 0) {
1073  zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
1074  }
1075  if (err == Z_NEED_DICT) {
1076  VALUE self = (VALUE)z->stream.opaque;
1077  VALUE dicts = rb_ivar_get(self, id_dictionaries);
1078  VALUE dict = rb_hash_aref(dicts, rb_uint2inum(z->stream.adler));
1079  if (!NIL_P(dict)) {
1080  rb_inflate_set_dictionary(self, dict);
1081  goto loop;
1082  }
1083  }
1084  raise_zlib_error(err, z->stream.msg);
1085  }
1086 
1087  if (z->stream.avail_in > 0) {
1088  zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
1089  RB_GC_GUARD(guard) = Qnil; /* prevent tail call to make guard effective */
1090  }
1091 
1092  if (args.jump_state)
1093  rb_jump_tag(args.jump_state);
1094 }
1095 
1096 static VALUE
1097 zstream_sync(struct zstream *z, Bytef *src, long len)
1098 {
1099  /* VALUE rest; */
1100  int err;
1101 
1102  if (!NIL_P(z->input)) {
1103  z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
1104  z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input));
1105  err = inflateSync(&z->stream);
1106  if (err == Z_OK) {
1108  RSTRING_LEN(z->input) - z->stream.avail_in);
1109  zstream_append_input(z, src, len);
1110  return Qtrue;
1111  }
1113  if (err != Z_DATA_ERROR) {
1114  /* rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in); */
1115  raise_zlib_error(err, z->stream.msg);
1116  }
1117  }
1118 
1119  if (len <= 0) return Qfalse;
1120 
1121  z->stream.next_in = src;
1122  z->stream.avail_in = MAX_UINT(len);
1123  err = inflateSync(&z->stream);
1124  if (err == Z_OK) {
1125  zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
1126  return Qtrue;
1127  }
1128  if (err != Z_DATA_ERROR) {
1129  /* rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in); */
1130  raise_zlib_error(err, z->stream.msg);
1131  }
1132  return Qfalse;
1133 }
1134 
1135 static void
1137 {
1138  rb_gc_mark(z->buf);
1139  rb_gc_mark(z->input);
1140 }
1141 
1142 static void
1144 {
1145  int err = z->func->end(&z->stream);
1146  if (err == Z_STREAM_ERROR)
1147  finalizer_warn("the stream state was inconsistent.");
1148  if (err == Z_DATA_ERROR)
1149  finalizer_warn("the stream was freed prematurely.");
1150 }
1151 
1152 static void
1154 {
1155  if (ZSTREAM_IS_READY(z)) {
1156  zstream_finalize(z);
1157  }
1158  xfree(z);
1159 }
1160 
1161 static VALUE
1162 zstream_new(VALUE klass, const struct zstream_funcs *funcs)
1163 {
1164  VALUE obj;
1165  struct zstream *z;
1166 
1167  obj = Data_Make_Struct(klass, struct zstream,
1169  zstream_init(z, funcs);
1170  z->stream.opaque = (voidpf)obj;
1171  return obj;
1172 }
1173 
1174 #define zstream_deflate_new(klass) zstream_new((klass), &deflate_funcs)
1175 #define zstream_inflate_new(klass) zstream_new((klass), &inflate_funcs)
1176 
1177 static struct zstream *
1179 {
1180  struct zstream *z;
1181 
1182  Data_Get_Struct(obj, struct zstream, z);
1183  if (!ZSTREAM_IS_READY(z)) {
1184  rb_raise(cZError, "stream is not ready");
1185  }
1186  return z;
1187 }
1188 
1189 
1190 /* ------------------------------------------------------------------------- */
1191 
1192 /*
1193  * Document-class: Zlib::ZStream
1194  *
1195  * Zlib::ZStream is the abstract class for the stream which handles the
1196  * compressed data. The operations are defined in the subclasses:
1197  * Zlib::Deflate for compression, and Zlib::Inflate for decompression.
1198  *
1199  * An instance of Zlib::ZStream has one stream (struct zstream in the source)
1200  * and two variable-length buffers which associated to the input (next_in) of
1201  * the stream and the output (next_out) of the stream. In this document,
1202  * "input buffer" means the buffer for input, and "output buffer" means the
1203  * buffer for output.
1204  *
1205  * Data input into an instance of Zlib::ZStream are temporally stored into
1206  * the end of input buffer, and then data in input buffer are processed from
1207  * the beginning of the buffer until no more output from the stream is
1208  * produced (i.e. until avail_out > 0 after processing). During processing,
1209  * output buffer is allocated and expanded automatically to hold all output
1210  * data.
1211  *
1212  * Some particular instance methods consume the data in output buffer and
1213  * return them as a String.
1214  *
1215  * Here is an ascii art for describing above:
1216  *
1217  * +================ an instance of Zlib::ZStream ================+
1218  * || ||
1219  * || +--------+ +-------+ +--------+ ||
1220  * || +--| output |<---------|zstream|<---------| input |<--+ ||
1221  * || | | buffer | next_out+-------+next_in | buffer | | ||
1222  * || | +--------+ +--------+ | ||
1223  * || | | ||
1224  * +===|======================================================|===+
1225  * | |
1226  * v |
1227  * "output data" "input data"
1228  *
1229  * If an error occurs during processing input buffer, an exception which is a
1230  * subclass of Zlib::Error is raised. At that time, both input and output
1231  * buffer keep their conditions at the time when the error occurs.
1232  *
1233  * == Method Catalogue
1234  *
1235  * Many of the methods in this class are fairly low-level and unlikely to be
1236  * of interest to users. In fact, users are unlikely to use this class
1237  * directly; rather they will be interested in Zlib::Inflate and
1238  * Zlib::Deflate.
1239  *
1240  * The higher level methods are listed below.
1241  *
1242  * - #total_in
1243  * - #total_out
1244  * - #data_type
1245  * - #adler
1246  * - #reset
1247  * - #finish
1248  * - #finished?
1249  * - #close
1250  * - #closed?
1251  */
1252 
1253 /*
1254  * Closes the stream. All operations on the closed stream will raise an
1255  * exception.
1256  */
1257 static VALUE
1259 {
1260  zstream_end(get_zstream(obj));
1261  return Qnil;
1262 }
1263 
1264 /*
1265  * Resets and initializes the stream. All data in both input and output buffer
1266  * are discarded.
1267  */
1268 static VALUE
1270 {
1271  zstream_reset(get_zstream(obj));
1272  return Qnil;
1273 }
1274 
1275 /*
1276  * call-seq:
1277  * finish -> String
1278  * finish { |chunk| ... } -> nil
1279  *
1280  * Finishes the stream and flushes output buffer. If a block is given each
1281  * chunk is yielded to the block until the input buffer has been flushed to
1282  * the output buffer.
1283  */
1284 static VALUE
1286 {
1287  struct zstream *z = get_zstream(obj);
1288 
1289  zstream_run(z, (Bytef*)"", 0, Z_FINISH);
1290 
1291  return zstream_detach_buffer(z);
1292 }
1293 
1294 /*
1295  * call-seq:
1296  * flush_next_out -> String
1297  * flush_next_out { |chunk| ... } -> nil
1298  *
1299  * Flushes output buffer and returns all data in that buffer. If a block is
1300  * given each chunk is yielded to the block until the current output buffer
1301  * has been flushed.
1302  */
1303 static VALUE
1305 {
1306  struct zstream *z;
1307  VALUE dst;
1308 
1309  Data_Get_Struct(obj, struct zstream, z);
1310  dst = zstream_detach_input(z);
1311  OBJ_INFECT(dst, obj);
1312  return dst;
1313 }
1314 
1315 /*
1316  * Flushes output buffer and returns all data in that buffer.
1317  */
1318 static VALUE
1320 {
1321  struct zstream *z;
1322 
1323  Data_Get_Struct(obj, struct zstream, z);
1324 
1325  return zstream_detach_buffer(z);
1326 }
1327 
1328 /*
1329  * Returns number of bytes of free spaces in output buffer. Because the free
1330  * space is allocated automatically, this method returns 0 normally.
1331  */
1332 static VALUE
1334 {
1335  struct zstream *z;
1336  Data_Get_Struct(obj, struct zstream, z);
1337  return rb_uint2inum(z->stream.avail_out);
1338 }
1339 
1340 /*
1341  * Allocates +size+ bytes of free space in the output buffer. If there are more
1342  * than +size+ bytes already in the buffer, the buffer is truncated. Because
1343  * free space is allocated automatically, you usually don't need to use this
1344  * method.
1345  */
1346 static VALUE
1348 {
1349  struct zstream *z = get_zstream(obj);
1350 
1351  Check_Type(size, T_FIXNUM);
1353  return size;
1354 }
1355 
1356 /*
1357  * Returns bytes of data in the input buffer. Normally, returns 0.
1358  */
1359 static VALUE
1361 {
1362  struct zstream *z;
1363  Data_Get_Struct(obj, struct zstream, z);
1364  return INT2FIX(NIL_P(z->input) ? 0 : (int)(RSTRING_LEN(z->input)));
1365 }
1366 
1367 /*
1368  * Returns the total bytes of the input data to the stream. FIXME
1369  */
1370 static VALUE
1372 {
1373  return rb_uint2inum(get_zstream(obj)->stream.total_in);
1374 }
1375 
1376 /*
1377  * Returns the total bytes of the output data from the stream. FIXME
1378  */
1379 static VALUE
1381 {
1382  return rb_uint2inum(get_zstream(obj)->stream.total_out);
1383 }
1384 
1385 /*
1386  * Guesses the type of the data which have been inputed into the stream. The
1387  * returned value is either <tt>BINARY</tt>, <tt>ASCII</tt>, or
1388  * <tt>UNKNOWN</tt>.
1389  */
1390 static VALUE
1392 {
1393  return INT2FIX(get_zstream(obj)->stream.data_type);
1394 }
1395 
1396 /*
1397  * Returns the adler-32 checksum.
1398  */
1399 static VALUE
1401 {
1402  return rb_uint2inum(get_zstream(obj)->stream.adler);
1403 }
1404 
1405 /*
1406  * Returns true if the stream is finished.
1407  */
1408 static VALUE
1410 {
1411  return ZSTREAM_IS_FINISHED(get_zstream(obj)) ? Qtrue : Qfalse;
1412 }
1413 
1414 /*
1415  * Returns true if the stream is closed.
1416  */
1417 static VALUE
1419 {
1420  struct zstream *z;
1421  Data_Get_Struct(obj, struct zstream, z);
1422  return ZSTREAM_IS_READY(z) ? Qfalse : Qtrue;
1423 }
1424 
1425 
1426 /* ------------------------------------------------------------------------- */
1427 
1428 /*
1429  * Document-class: Zlib::Deflate
1430  *
1431  * Zlib::Deflate is the class for compressing data. See Zlib::ZStream for more
1432  * information.
1433  */
1434 
1435 #define FIXNUMARG(val, ifnil) \
1436  (NIL_P((val)) ? (ifnil) \
1437  : ((void)Check_Type((val), T_FIXNUM), FIX2INT((val))))
1438 
1439 #define ARG_LEVEL(val) FIXNUMARG((val), Z_DEFAULT_COMPRESSION)
1440 #define ARG_WBITS(val) FIXNUMARG((val), MAX_WBITS)
1441 #define ARG_MEMLEVEL(val) FIXNUMARG((val), DEF_MEM_LEVEL)
1442 #define ARG_STRATEGY(val) FIXNUMARG((val), Z_DEFAULT_STRATEGY)
1443 #define ARG_FLUSH(val) FIXNUMARG((val), Z_NO_FLUSH)
1444 
1445 
1446 static VALUE
1448 {
1449  return zstream_deflate_new(klass);
1450 }
1451 
1452 /*
1453  * Document-method: Zlib::Deflate.new
1454  *
1455  * call-seq:
1456  * Zlib::Deflate.new(level=DEFAULT_COMPRESSION, window_bits=MAX_WBITS, mem_level=DEF_MEM_LEVEL, strategy=DEFAULT_STRATEGY)
1457  *
1458  * Creates a new deflate stream for compression. If a given argument is nil,
1459  * the default value of that argument is used.
1460  *
1461  * The +level+ sets the compression level for the deflate stream between 0 (no
1462  * compression) and 9 (best compression. The following constants have been
1463  * defined to make code more readable:
1464  *
1465  * * Zlib::NO_COMPRESSION = 0
1466  * * Zlib::BEST_SPEED = 1
1467  * * Zlib::DEFAULT_COMPRESSION = 6
1468  * * Zlib::BEST_COMPRESSION = 9
1469  *
1470  * The +window_bits+ sets the size of the history buffer and should be between
1471  * 8 and 15. Larger values of this parameter result in better compression at
1472  * the expense of memory usage.
1473  *
1474  * The +mem_level+ specifies how much memory should be allocated for the
1475  * internal compression state. 1 uses minimum memory but is slow and reduces
1476  * compression ratio while 9 uses maximum memory for optimal speed. The
1477  * default value is 8. Two constants are defined:
1478  *
1479  * * Zlib::DEF_MEM_LEVEL
1480  * * Zlib::MAX_MEM_LEVEL
1481  *
1482  * The +strategy+ sets the deflate compression strategy. The following
1483  * strategies are available:
1484  *
1485  * Zlib::DEFAULT_STRATEGY:: For normal data
1486  * Zlib::FILTERED:: For data produced by a filter or predictor
1487  * Zlib::FIXED:: Prevents dynamic Huffman codes
1488  * Zlib::HUFFMAN_ONLY:: Prevents string matching
1489  * Zlib::RLE:: Designed for better compression of PNG image data
1490  *
1491  * See the constants for further description.
1492  *
1493  * == Examples
1494  *
1495  * === Basic
1496  *
1497  * open "compressed.file", "w+" do |io|
1498  * io << Zlib::Deflate.new.deflate(File.read("big.file"))
1499  * end
1500  *
1501  * === Custom compression
1502  *
1503  * open "compressed.file", "w+" do |compressed_io|
1504  * deflate = Zlib::Deflate.new(Zlib::BEST_COMPRESSION,
1505  * Zlib::MAX_WBITS,
1506  * Zlib::MAX_MEM_LEVEL,
1507  * Zlib::HUFFMAN_ONLY)
1508  *
1509  * begin
1510  * open "big.file" do |big_io|
1511  * until big_io.eof? do
1512  * compressed_io << zd.deflate(big_io.read(16384))
1513  * end
1514  * end
1515  * ensure
1516  * deflate.close
1517  * end
1518  * end
1519  *
1520  * While this example will work, for best optimization review the flags for
1521  * your specific time, memory usage and output space requirements.
1522  */
1523 static VALUE
1525 {
1526  struct zstream *z;
1527  VALUE level, wbits, memlevel, strategy;
1528  int err;
1529 
1530  rb_scan_args(argc, argv, "04", &level, &wbits, &memlevel, &strategy);
1531  Data_Get_Struct(obj, struct zstream, z);
1532 
1533  err = deflateInit2(&z->stream, ARG_LEVEL(level), Z_DEFLATED,
1534  ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel),
1535  ARG_STRATEGY(strategy));
1536  if (err != Z_OK) {
1537  raise_zlib_error(err, z->stream.msg);
1538  }
1539  ZSTREAM_READY(z);
1540 
1541  return obj;
1542 }
1543 
1544 /*
1545  * Document-method: Zlib::Deflate#initialize_copy
1546  *
1547  * Duplicates the deflate stream.
1548  */
1549 static VALUE
1551 {
1552  struct zstream *z1, *z2;
1553  int err;
1554 
1555  Data_Get_Struct(self, struct zstream, z1);
1556  z2 = get_zstream(orig);
1557 
1558  err = deflateCopy(&z1->stream, &z2->stream);
1559  if (err != Z_OK) {
1560  raise_zlib_error(err, 0);
1561  }
1562  z1->input = NIL_P(z2->input) ? Qnil : rb_str_dup(z2->input);
1563  z1->buf = NIL_P(z2->buf) ? Qnil : rb_str_dup(z2->buf);
1564  z1->buf_filled = z2->buf_filled;
1565  z1->flags = z2->flags;
1566 
1567  return self;
1568 }
1569 
1570 static VALUE
1572 {
1573  struct zstream *z = (struct zstream*)((VALUE*)args)[0];
1574  VALUE src = ((VALUE*)args)[1];
1575 
1576  zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_FINISH);
1577  return zstream_detach_buffer(z);
1578 }
1579 
1580 /*
1581  * Document-method: Zlib::Deflate.deflate
1582  *
1583  * call-seq:
1584  * Zlib.deflate(string[, level])
1585  * Zlib::Deflate.deflate(string[, level])
1586  *
1587  * Compresses the given +string+. Valid values of level are
1588  * Zlib::NO_COMPRESSION, Zlib::BEST_SPEED, Zlib::BEST_COMPRESSION,
1589  * Zlib::DEFAULT_COMPRESSION, or an integer from 0 to 9 (the default is 6).
1590  *
1591  * This method is almost equivalent to the following code:
1592  *
1593  * def deflate(string, level)
1594  * z = Zlib::Deflate.new(level)
1595  * dst = z.deflate(string, Zlib::FINISH)
1596  * z.close
1597  * dst
1598  * end
1599  *
1600  * See also Zlib.inflate
1601  *
1602  */
1603 static VALUE
1604 rb_deflate_s_deflate(int argc, VALUE *argv, VALUE klass)
1605 {
1606  struct zstream z;
1607  VALUE src, level, dst, args[2];
1608  int err, lev;
1609 
1610  rb_scan_args(argc, argv, "11", &src, &level);
1611 
1612  lev = ARG_LEVEL(level);
1613  StringValue(src);
1615  err = deflateInit(&z.stream, lev);
1616  if (err != Z_OK) {
1617  raise_zlib_error(err, z.stream.msg);
1618  }
1619  ZSTREAM_READY(&z);
1620 
1621  args[0] = (VALUE)&z;
1622  args[1] = src;
1623  dst = rb_ensure(deflate_run, (VALUE)args, zstream_end, (VALUE)&z);
1624 
1625  OBJ_INFECT(dst, src);
1626  return dst;
1627 }
1628 
1629 static void
1630 do_deflate(struct zstream *z, VALUE src, int flush)
1631 {
1632  if (NIL_P(src)) {
1633  zstream_run(z, (Bytef*)"", 0, Z_FINISH);
1634  return;
1635  }
1636  StringValue(src);
1637  if (flush != Z_NO_FLUSH || RSTRING_LEN(src) > 0) { /* prevent BUF_ERROR */
1638  zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), flush);
1639  }
1640 }
1641 
1642 /*
1643  * Document-method: Zlib::Deflate#deflate
1644  *
1645  * call-seq:
1646  * z.deflate(string, flush = Zlib::NO_FLUSH) -> String
1647  * z.deflate(string, flush = Zlib::NO_FLUSH) { |chunk| ... } -> nil
1648  *
1649  * Inputs +string+ into the deflate stream and returns the output from the
1650  * stream. On calling this method, both the input and the output buffers of
1651  * the stream are flushed. If +string+ is nil, this method finishes the
1652  * stream, just like Zlib::ZStream#finish.
1653  *
1654  * If a block is given consecutive deflated chunks from the +string+ are
1655  * yielded to the block and +nil+ is returned.
1656  *
1657  * The +flush+ parameter specifies the flush mode. The following constants
1658  * may be used:
1659  *
1660  * Zlib::NO_FLUSH:: The default
1661  * Zlib::SYNC_FLUSH:: Flushes the output to a byte boundary
1662  * Zlib::FULL_FLUSH:: SYNC_FLUSH + resets the compression state
1663  * Zlib::FINISH:: Pending input is processed, pending output is flushed.
1664  *
1665  * See the constants for further description.
1666  *
1667  */
1668 static VALUE
1670 {
1671  struct zstream *z = get_zstream(obj);
1672  VALUE src, flush;
1673 
1674  rb_scan_args(argc, argv, "11", &src, &flush);
1675  OBJ_INFECT(obj, src);
1676  do_deflate(z, src, ARG_FLUSH(flush));
1677 
1678  return zstream_detach_buffer(z);
1679 }
1680 
1681 /*
1682  * Document-method: Zlib::Deflate#<<
1683  *
1684  * call-seq: << string
1685  *
1686  * Inputs +string+ into the deflate stream just like Zlib::Deflate#deflate, but
1687  * returns the Zlib::Deflate object itself. The output from the stream is
1688  * preserved in output buffer.
1689  */
1690 static VALUE
1692 {
1693  OBJ_INFECT(obj, src);
1694  do_deflate(get_zstream(obj), src, Z_NO_FLUSH);
1695  return obj;
1696 }
1697 
1698 /*
1699  * Document-method: Zlib::Deflate#flush
1700  *
1701  * call-seq:
1702  * flush(flush = Zlib::SYNC_FLUSH) -> String
1703  * flush(flush = Zlib::SYNC_FLUSH) { |chunk| ... } -> nil
1704  *
1705  * This method is equivalent to <tt>deflate('', flush)</tt>. This method is
1706  * just provided to improve the readability of your Ruby program. If a block
1707  * is given chunks of deflate output are yielded to the block until the buffer
1708  * is flushed.
1709  *
1710  * See Zlib::Deflate#deflate for detail on the +flush+ constants NO_FLUSH,
1711  * SYNC_FLUSH, FULL_FLUSH and FINISH.
1712  */
1713 static VALUE
1714 rb_deflate_flush(int argc, VALUE *argv, VALUE obj)
1715 {
1716  struct zstream *z = get_zstream(obj);
1717  VALUE v_flush;
1718  int flush;
1719 
1720  rb_scan_args(argc, argv, "01", &v_flush);
1721  flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
1722  if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
1723  zstream_run(z, (Bytef*)"", 0, flush);
1724  }
1725 
1726  return zstream_detach_buffer(z);
1727 }
1728 
1729 /*
1730  * Document-method: Zlib::Deflate.params
1731  *
1732  * call-seq: params(level, strategy)
1733  *
1734  * Changes the parameters of the deflate stream to allow changes between
1735  * different types of data that require different types of compression. Any
1736  * unprocessed data is flushed before changing the params.
1737  *
1738  * See Zlib::Deflate.new for a description of +level+ and +strategy+.
1739  *
1740  */
1741 static VALUE
1742 rb_deflate_params(VALUE obj, VALUE v_level, VALUE v_strategy)
1743 {
1744  struct zstream *z = get_zstream(obj);
1745  int level, strategy;
1746  int err;
1747  uInt n;
1748 
1749  level = ARG_LEVEL(v_level);
1750  strategy = ARG_STRATEGY(v_strategy);
1751 
1752  n = z->stream.avail_out;
1753  err = deflateParams(&z->stream, level, strategy);
1754  z->buf_filled += n - z->stream.avail_out;
1755  while (err == Z_BUF_ERROR) {
1756  rb_warning("deflateParams() returned Z_BUF_ERROR");
1758  n = z->stream.avail_out;
1759  err = deflateParams(&z->stream, level, strategy);
1760  z->buf_filled += n - z->stream.avail_out;
1761  }
1762  if (err != Z_OK) {
1763  raise_zlib_error(err, z->stream.msg);
1764  }
1765 
1766  return Qnil;
1767 }
1768 
1769 /*
1770  * Document-method: Zlib::Deflate.set_dictionary
1771  *
1772  * call-seq: set_dictionary(string)
1773  *
1774  * Sets the preset dictionary and returns +string+. This method is available
1775  * just only after Zlib::Deflate.new or Zlib::ZStream#reset method was called.
1776  * See zlib.h for details.
1777  *
1778  * Can raise errors of Z_STREAM_ERROR if a parameter is invalid (such as
1779  * NULL dictionary) or the stream state is inconsistent, Z_DATA_ERROR if
1780  * the given dictionary doesn't match the expected one (incorrect adler32 value)
1781  *
1782  */
1783 static VALUE
1785 {
1786  struct zstream *z = get_zstream(obj);
1787  VALUE src = dic;
1788  int err;
1789 
1790  OBJ_INFECT(obj, dic);
1791  StringValue(src);
1792  err = deflateSetDictionary(&z->stream,
1793  (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
1794  if (err != Z_OK) {
1795  raise_zlib_error(err, z->stream.msg);
1796  }
1797 
1798  return dic;
1799 }
1800 
1801 
1802 /* ------------------------------------------------------------------------- */
1803 
1804 /*
1805  * Document-class: Zlib::Inflate
1806  *
1807  * Zlib:Inflate is the class for decompressing compressed data. Unlike
1808  * Zlib::Deflate, an instance of this class is not able to duplicate (clone,
1809  * dup) itself.
1810  */
1811 
1812 static VALUE
1814 {
1815  VALUE inflate = zstream_inflate_new(klass);
1817  return inflate;
1818 }
1819 
1820 /*
1821  * Document-method: Zlib::Inflate.new
1822  *
1823  * call-seq:
1824  * Zlib::Inflate.new(window_bits = Zlib::MAX_WBITS)
1825  *
1826  * Creates a new inflate stream for decompression. +window_bits+ sets the
1827  * size of the history buffer and can have the following values:
1828  *
1829  * 0::
1830  * Have inflate use the window size from the zlib header of the compressed
1831  * stream.
1832  *
1833  * (8..15)
1834  * Overrides the window size of the inflate header in the compressed stream.
1835  * The window size must be greater than or equal to the window size of the
1836  * compressed stream.
1837  *
1838  * Greater than 15::
1839  * Add 32 to window_bits to enable zlib and gzip decoding with automatic
1840  * header detection, or add 16 to decode only the gzip format (a
1841  * Zlib::DataError will be raised for a non-gzip stream).
1842  *
1843  * (-8..-15)::
1844  * Enables raw deflate mode which will not generate a check value, and will
1845  * not look for any check values for comparison at the end of the stream.
1846  *
1847  * This is for use with other formats that use the deflate compressed data
1848  * format such as zip which provide their own check values.
1849  *
1850  * == Example
1851  *
1852  * open "compressed.file" do |compressed_io|
1853  * inflate = Zlib::Inflate.new(Zlib::MAX_WBITS + 32)
1854  *
1855  * begin
1856  * open "uncompressed.file", "w+" do |uncompressed_io|
1857  * uncompressed_io << zi.inflate(compressed_io.read)
1858  * }
1859  * ensure
1860  * zi.close
1861  * end
1862  * end
1863  *
1864  */
1865 static VALUE
1867 {
1868  struct zstream *z;
1869  VALUE wbits;
1870  int err;
1871 
1872  rb_scan_args(argc, argv, "01", &wbits);
1873  Data_Get_Struct(obj, struct zstream, z);
1874 
1875  err = inflateInit2(&z->stream, ARG_WBITS(wbits));
1876  if (err != Z_OK) {
1877  raise_zlib_error(err, z->stream.msg);
1878  }
1879  ZSTREAM_READY(z);
1880 
1881  return obj;
1882 }
1883 
1884 static VALUE
1886 {
1887  struct zstream *z = (struct zstream*)((VALUE*)args)[0];
1888  VALUE src = ((VALUE*)args)[1];
1889 
1890  zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_SYNC_FLUSH);
1891  zstream_run(z, (Bytef*)"", 0, Z_FINISH); /* for checking errors */
1892  return zstream_detach_buffer(z);
1893 }
1894 
1895 /*
1896  * Document-method: Zlib::inflate
1897  *
1898  * call-seq:
1899  * Zlib.inflate(string)
1900  * Zlib::Inflate.inflate(string)
1901  *
1902  * Decompresses +string+. Raises a Zlib::NeedDict exception if a preset
1903  * dictionary is needed for decompression.
1904  *
1905  * This method is almost equivalent to the following code:
1906  *
1907  * def inflate(string)
1908  * zstream = Zlib::Inflate.new
1909  * buf = zstream.inflate(string)
1910  * zstream.finish
1911  * zstream.close
1912  * buf
1913  * end
1914  *
1915  * See also Zlib.deflate
1916  *
1917  */
1918 static VALUE
1920 {
1921  struct zstream z;
1922  VALUE dst, args[2];
1923  int err;
1924 
1925  StringValue(src);
1927  err = inflateInit(&z.stream);
1928  if (err != Z_OK) {
1929  raise_zlib_error(err, z.stream.msg);
1930  }
1931  ZSTREAM_READY(&z);
1932 
1933  args[0] = (VALUE)&z;
1934  args[1] = src;
1935  dst = rb_ensure(inflate_run, (VALUE)args, zstream_end, (VALUE)&z);
1936 
1937  OBJ_INFECT(dst, src);
1938  return dst;
1939 }
1940 
1941 static void
1943 {
1944  if (NIL_P(src)) {
1945  zstream_run(z, (Bytef*)"", 0, Z_FINISH);
1946  return;
1947  }
1948  StringValue(src);
1949  if (RSTRING_LEN(src) > 0 || z->stream.avail_in > 0) { /* prevent Z_BUF_ERROR */
1950  zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_SYNC_FLUSH);
1951  }
1952 }
1953 
1954 /* Document-method: Zlib::Inflate#add_dictionary
1955  *
1956  * call-seq: add_dictionary(string)
1957  *
1958  * Provide the inflate stream with a dictionary that may be required in the
1959  * future. Multiple dictionaries may be provided. The inflate stream will
1960  * automatically choose the correct user-provided dictionary based on the
1961  * stream's required dictionary.
1962  */
1963 static VALUE
1965  VALUE dictionaries = rb_ivar_get(obj, id_dictionaries);
1966  VALUE checksum = do_checksum(1, &dictionary, adler32);
1967 
1968  rb_hash_aset(dictionaries, checksum, dictionary);
1969 
1970  return obj;
1971 }
1972 
1973 /*
1974  * Document-method: Zlib::Inflate#inflate
1975  *
1976  * call-seq:
1977  * inflate(deflate_string) -> String
1978  * inflate(deflate_string) { |chunk| ... } -> nil
1979  *
1980  * Inputs +deflate_string+ into the inflate stream and returns the output from
1981  * the stream. Calling this method, both the input and the output buffer of
1982  * the stream are flushed. If string is +nil+, this method finishes the
1983  * stream, just like Zlib::ZStream#finish.
1984  *
1985  * If a block is given consecutive inflated chunks from the +deflate_string+
1986  * are yielded to the block and +nil+ is returned.
1987  *
1988  * Raises a Zlib::NeedDict exception if a preset dictionary is needed to
1989  * decompress. Set the dictionary by Zlib::Inflate#set_dictionary and then
1990  * call this method again with an empty string to flush the stream:
1991  *
1992  * inflater = Zlib::Inflate.new
1993  *
1994  * begin
1995  * out = inflater.inflate compressed
1996  * rescue Zlib::NeedDict
1997  * # ensure the dictionary matches the stream's required dictionary
1998  * raise unless inflater.adler == Zlib.adler32(dictionary)
1999  *
2000  * inflater.set_dictionary dictionary
2001  * inflater.inflate ''
2002  * end
2003  *
2004  * # ...
2005  *
2006  * inflater.close
2007  *
2008  * See also Zlib::Inflate.new
2009  */
2010 static VALUE
2012 {
2013  struct zstream *z = get_zstream(obj);
2014  VALUE dst;
2015 
2016  OBJ_INFECT(obj, src);
2017 
2018  if (ZSTREAM_IS_FINISHED(z)) {
2019  if (NIL_P(src)) {
2020  dst = zstream_detach_buffer(z);
2021  }
2022  else {
2023  StringValue(src);
2024  zstream_append_buffer2(z, src);
2025  dst = rb_str_new(0, 0);
2026  OBJ_INFECT(dst, obj);
2027  }
2028  }
2029  else {
2030  do_inflate(z, src);
2031  dst = zstream_detach_buffer(z);
2032  if (ZSTREAM_IS_FINISHED(z)) {
2034  }
2035  }
2036 
2037  return dst;
2038 }
2039 
2040 /*
2041  * call-seq: << string
2042  *
2043  * Inputs +string+ into the inflate stream just like Zlib::Inflate#inflate, but
2044  * returns the Zlib::Inflate object itself. The output from the stream is
2045  * preserved in output buffer.
2046  */
2047 static VALUE
2049 {
2050  struct zstream *z = get_zstream(obj);
2051 
2052  OBJ_INFECT(obj, src);
2053 
2054  if (ZSTREAM_IS_FINISHED(z)) {
2055  if (!NIL_P(src)) {
2056  StringValue(src);
2057  zstream_append_buffer2(z, src);
2058  }
2059  }
2060  else {
2061  do_inflate(z, src);
2062  if (ZSTREAM_IS_FINISHED(z)) {
2064  }
2065  }
2066 
2067  return obj;
2068 }
2069 
2070 /*
2071  * call-seq: sync(string)
2072  *
2073  * Inputs +string+ into the end of input buffer and skips data until a full
2074  * flush point can be found. If the point is found in the buffer, this method
2075  * flushes the buffer and returns false. Otherwise it returns +true+ and the
2076  * following data of full flush point is preserved in the buffer.
2077  */
2078 static VALUE
2080 {
2081  struct zstream *z = get_zstream(obj);
2082 
2083  OBJ_INFECT(obj, src);
2084  StringValue(src);
2085  return zstream_sync(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src));
2086 }
2087 
2088 /*
2089  * Quoted verbatim from original documentation:
2090  *
2091  * What is this?
2092  *
2093  * <tt>:)</tt>
2094  */
2095 static VALUE
2097 {
2098  struct zstream *z = get_zstream(obj);
2099  int err;
2100 
2101  err = inflateSyncPoint(&z->stream);
2102  if (err == 1) {
2103  return Qtrue;
2104  }
2105  if (err != Z_OK) {
2106  raise_zlib_error(err, z->stream.msg);
2107  }
2108  return Qfalse;
2109 }
2110 
2111 /*
2112  * Document-method: Zlib::Inflate#set_dictionary
2113  *
2114  * Sets the preset dictionary and returns +string+. This method is available just
2115  * only after a Zlib::NeedDict exception was raised. See zlib.h for details.
2116  *
2117  */
2118 static VALUE
2120 {
2121  struct zstream *z = get_zstream(obj);
2122  VALUE src = dic;
2123  int err;
2124 
2125  OBJ_INFECT(obj, dic);
2126  StringValue(src);
2127  err = inflateSetDictionary(&z->stream,
2128  (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
2129  if (err != Z_OK) {
2130  raise_zlib_error(err, z->stream.msg);
2131  }
2132 
2133  return dic;
2134 }
2135 
2136 
2137 
2138 #if GZIP_SUPPORT
2139 
2140 /* NOTE: Features for gzip files of Ruby/zlib are written from scratch
2141  * and using undocumented feature of zlib, negative wbits.
2142  * I don't think gzFile APIs of zlib are good for Ruby.
2143  */
2144 
2145 /*------- .gz file header --------*/
2146 
2147 #define GZ_MAGIC1 0x1f
2148 #define GZ_MAGIC2 0x8b
2149 #define GZ_METHOD_DEFLATE 8
2150 #define GZ_FLAG_MULTIPART 0x2
2151 #define GZ_FLAG_EXTRA 0x4
2152 #define GZ_FLAG_ORIG_NAME 0x8
2153 #define GZ_FLAG_COMMENT 0x10
2154 #define GZ_FLAG_ENCRYPT 0x20
2155 #define GZ_FLAG_UNKNOWN_MASK 0xc0
2156 
2157 #define GZ_EXTRAFLAG_FAST 0x4
2158 #define GZ_EXTRAFLAG_SLOW 0x2
2159 
2160 /* from zutil.h */
2161 #define OS_MSDOS 0x00
2162 #define OS_AMIGA 0x01
2163 #define OS_VMS 0x02
2164 #define OS_UNIX 0x03
2165 #define OS_ATARI 0x05
2166 #define OS_OS2 0x06
2167 #define OS_MACOS 0x07
2168 #define OS_TOPS20 0x0a
2169 #define OS_WIN32 0x0b
2170 
2171 #define OS_VMCMS 0x04
2172 #define OS_ZSYSTEM 0x08
2173 #define OS_CPM 0x09
2174 #define OS_QDOS 0x0c
2175 #define OS_RISCOS 0x0d
2176 #define OS_UNKNOWN 0xff
2177 
2178 #ifndef OS_CODE
2179 #define OS_CODE OS_UNIX
2180 #endif
2181 
2184 
2185 
2186 
2187 /*-------- gzfile internal APIs --------*/
2188 
2189 struct gzfile {
2190  struct zstream z;
2192  int level;
2193  time_t mtime; /* for header */
2194  int os_code; /* for header */
2195  VALUE orig_name; /* for header; must be a String */
2196  VALUE comment; /* for header; must be a String */
2197  unsigned long crc;
2198  int lineno;
2199  long ungetc;
2200  void (*end)(struct gzfile *);
2204  int ecflags;
2206  char *cbuf;
2208 };
2209 #define GZFILE_CBUF_CAPA 10
2210 
2211 #define GZFILE_FLAG_SYNC ZSTREAM_FLAG_UNUSED
2212 #define GZFILE_FLAG_HEADER_FINISHED (ZSTREAM_FLAG_UNUSED << 1)
2213 #define GZFILE_FLAG_FOOTER_FINISHED (ZSTREAM_FLAG_UNUSED << 2)
2214 
2215 #define GZFILE_IS_FINISHED(gz) \
2216  (ZSTREAM_IS_FINISHED(&(gz)->z) && (gz)->z.buf_filled == 0)
2217 
2218 #define GZFILE_READ_SIZE 2048
2219 
2220 
2221 static void
2223 {
2224  rb_gc_mark(gz->io);
2225  rb_gc_mark(gz->orig_name);
2226  rb_gc_mark(gz->comment);
2227  zstream_mark(&gz->z);
2228  rb_gc_mark(gz->ecopts);
2229  rb_gc_mark(gz->path);
2230 }
2231 
2232 static void
2234 {
2235  struct zstream *z = &gz->z;
2236 
2237  if (ZSTREAM_IS_READY(z)) {
2238  if (z->func == &deflate_funcs) {
2239  finalizer_warn("Zlib::GzipWriter object must be closed explicitly.");
2240  }
2241  zstream_finalize(z);
2242  }
2243  if (gz->cbuf) {
2244  xfree(gz->cbuf);
2245  }
2246  xfree(gz);
2247 }
2248 
2249 static VALUE
2250 gzfile_new(klass, funcs, endfunc)
2251  VALUE klass;
2252  const struct zstream_funcs *funcs;
2253  void (*endfunc)(struct gzfile *);
2254 {
2255  VALUE obj;
2256  struct gzfile *gz;
2257 
2258  obj = Data_Make_Struct(klass, struct gzfile, gzfile_mark, gzfile_free, gz);
2259  zstream_init(&gz->z, funcs);
2261  gz->io = Qnil;
2262  gz->level = 0;
2263  gz->mtime = 0;
2266  gz->comment = Qnil;
2267  gz->crc = crc32(0, Z_NULL, 0);
2268  gz->lineno = 0;
2269  gz->ungetc = 0;
2270  gz->end = endfunc;
2272  gz->enc2 = 0;
2273  gz->ec = NULL;
2274  gz->ecflags = 0;
2275  gz->ecopts = Qnil;
2276  gz->cbuf = 0;
2277  gz->path = Qnil;
2278 
2279  return obj;
2280 }
2281 
2282 #define gzfile_writer_new(gz) gzfile_new((gz),&deflate_funcs,gzfile_writer_end)
2283 #define gzfile_reader_new(gz) gzfile_new((gz),&inflate_funcs,gzfile_reader_end)
2284 
2285 static void
2287 {
2288  zstream_reset(&gz->z);
2289  gz->crc = crc32(0, Z_NULL, 0);
2290  gz->lineno = 0;
2291  gz->ungetc = 0;
2292  if (gz->ec) {
2293  rb_econv_close(gz->ec);
2294  gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
2295  gz->ecflags, gz->ecopts);
2296  }
2297 }
2298 
2299 static void
2300 gzfile_close(struct gzfile *gz, int closeflag)
2301 {
2302  VALUE io = gz->io;
2303 
2304  gz->end(gz);
2305  gz->io = Qnil;
2306  gz->orig_name = Qnil;
2307  gz->comment = Qnil;
2308  if (closeflag && rb_respond_to(io, id_close)) {
2309  rb_funcall(io, id_close, 0);
2310  }
2311 }
2312 
2313 static void
2315 {
2316  VALUE str;
2317 
2318  if (gz->z.buf_filled > 0) {
2319  str = zstream_detach_buffer(&gz->z);
2320  OBJ_TAINT(str); /* for safe */
2321  rb_funcall(gz->io, id_write, 1, str);
2322  if ((gz->z.flags & GZFILE_FLAG_SYNC)
2323  && rb_respond_to(gz->io, id_flush))
2324  rb_funcall(gz->io, id_flush, 0);
2325  }
2326 }
2327 
2328 static VALUE
2330 {
2331  struct gzfile *gz = (struct gzfile*)arg;
2332  VALUE str;
2333 
2334  str = rb_funcall(gz->io, id_readpartial, 1, INT2FIX(GZFILE_READ_SIZE));
2335  Check_Type(str, T_STRING);
2336  return str;
2337 }
2338 
2339 static VALUE
2341 {
2342  struct gzfile *gz = (struct gzfile*)arg;
2343  VALUE str = Qnil;
2345  str = rb_funcall(gz->io, id_read, 1, INT2FIX(GZFILE_READ_SIZE));
2346  if (!NIL_P(str)) {
2347  Check_Type(str, T_STRING);
2348  }
2349  }
2350  return str; /* return nil when EOFError */
2351 }
2352 
2353 static VALUE
2355 {
2359 }
2360 
2361 static int
2363 {
2364  VALUE str;
2365 
2366  while (NIL_P(gz->z.input) || RSTRING_LEN(gz->z.input) < size) {
2367  str = gzfile_read_raw(gz);
2368  if (NIL_P(str)) return 0;
2369  zstream_append_input2(&gz->z, str);
2370  }
2371  return 1;
2372 }
2373 
2374 static char *
2375 gzfile_read_raw_until_zero(struct gzfile *gz, long offset)
2376 {
2377  VALUE str;
2378  char *p;
2379 
2380  for (;;) {
2381  p = memchr(RSTRING_PTR(gz->z.input) + offset, '\0',
2382  RSTRING_LEN(gz->z.input) - offset);
2383  if (p) break;
2384  str = gzfile_read_raw(gz);
2385  if (NIL_P(str)) {
2386  rb_raise(cGzError, "unexpected end of file");
2387  }
2388  offset = RSTRING_LEN(gz->z.input);
2389  zstream_append_input2(&gz->z, str);
2390  }
2391  return p;
2392 }
2393 
2394 static unsigned int
2395 gzfile_get16(const unsigned char *src)
2396 {
2397  unsigned int n;
2398  n = *(src++) & 0xff;
2399  n |= (*(src++) & 0xff) << 8;
2400  return n;
2401 }
2402 
2403 static unsigned long
2404 gzfile_get32(const unsigned char *src)
2405 {
2406  unsigned long n;
2407  n = *(src++) & 0xff;
2408  n |= (*(src++) & 0xff) << 8;
2409  n |= (*(src++) & 0xff) << 16;
2410  n |= (*(src++) & 0xffU) << 24;
2411  return n;
2412 }
2413 
2414 static void
2415 gzfile_set32(unsigned long n, unsigned char *dst)
2416 {
2417  *(dst++) = n & 0xff;
2418  *(dst++) = (n >> 8) & 0xff;
2419  *(dst++) = (n >> 16) & 0xff;
2420  *dst = (n >> 24) & 0xff;
2421 }
2422 
2423 static void
2424 gzfile_raise(struct gzfile *gz, VALUE klass, const char *message)
2425 {
2426  VALUE exc = rb_exc_new2(klass, message);
2427  if (!NIL_P(gz->z.input)) {
2428  rb_ivar_set(exc, id_input, rb_str_resurrect(gz->z.input));
2429  }
2430  rb_exc_raise(exc);
2431 }
2432 
2433 /*
2434  * Document-method: Zlib::GzipFile::Error#inspect
2435  *
2436  * Constructs a String of the GzipFile Error
2437  */
2438 static VALUE
2440 {
2441  VALUE str = rb_call_super(0, 0);
2442  VALUE input = rb_attr_get(error, id_input);
2443 
2444  if (!NIL_P(input)) {
2445  rb_str_resize(str, RSTRING_LEN(str)-1);
2446  rb_str_cat2(str, ", input=");
2447  rb_str_append(str, rb_str_inspect(input));
2448  rb_str_cat2(str, ">");
2449  }
2450  return str;
2451 }
2452 
2453 static void
2455 {
2456  Bytef buf[10]; /* the size of gzip header */
2457  unsigned char flags = 0, extraflags = 0;
2458 
2459  if (!NIL_P(gz->orig_name)) {
2460  flags |= GZ_FLAG_ORIG_NAME;
2461  }
2462  if (!NIL_P(gz->comment)) {
2463  flags |= GZ_FLAG_COMMENT;
2464  }
2465  if (gz->mtime == 0) {
2466  gz->mtime = time(0);
2467  }
2468 
2469  if (gz->level == Z_BEST_SPEED) {
2470  extraflags |= GZ_EXTRAFLAG_FAST;
2471  }
2472  else if (gz->level == Z_BEST_COMPRESSION) {
2473  extraflags |= GZ_EXTRAFLAG_SLOW;
2474  }
2475 
2476  buf[0] = GZ_MAGIC1;
2477  buf[1] = GZ_MAGIC2;
2478  buf[2] = GZ_METHOD_DEFLATE;
2479  buf[3] = flags;
2480  gzfile_set32((unsigned long)gz->mtime, &buf[4]);
2481  buf[8] = extraflags;
2482  buf[9] = gz->os_code;
2483  zstream_append_buffer(&gz->z, buf, sizeof(buf));
2484 
2485  if (!NIL_P(gz->orig_name)) {
2486  zstream_append_buffer2(&gz->z, gz->orig_name);
2487  zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
2488  }
2489  if (!NIL_P(gz->comment)) {
2490  zstream_append_buffer2(&gz->z, gz->comment);
2491  zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
2492  }
2493 
2495 }
2496 
2497 static void
2499 {
2500  Bytef buf[8]; /* 8 is the size of gzip footer */
2501 
2502  gzfile_set32(gz->crc, buf);
2503  gzfile_set32(gz->z.stream.total_in, &buf[4]);
2504  zstream_append_buffer(&gz->z, buf, sizeof(buf));
2506 }
2507 
2508 static void
2510 {
2511  const unsigned char *head;
2512  long len;
2513  char flags, *p;
2514 
2515  if (!gzfile_read_raw_ensure(gz, 10)) { /* 10 is the size of gzip header */
2516  gzfile_raise(gz, cGzError, "not in gzip format");
2517  }
2518 
2519  head = (unsigned char*)RSTRING_PTR(gz->z.input);
2520 
2521  if (head[0] != GZ_MAGIC1 || head[1] != GZ_MAGIC2) {
2522  gzfile_raise(gz, cGzError, "not in gzip format");
2523  }
2524  if (head[2] != GZ_METHOD_DEFLATE) {
2525  rb_raise(cGzError, "unsupported compression method %d", head[2]);
2526  }
2527 
2528  flags = head[3];
2529  if (flags & GZ_FLAG_MULTIPART) {
2530  rb_raise(cGzError, "multi-part gzip file is not supported");
2531  }
2532  else if (flags & GZ_FLAG_ENCRYPT) {
2533  rb_raise(cGzError, "encrypted gzip file is not supported");
2534  }
2535  else if (flags & GZ_FLAG_UNKNOWN_MASK) {
2536  rb_raise(cGzError, "unknown flags 0x%02x", flags);
2537  }
2538 
2539  if (head[8] & GZ_EXTRAFLAG_FAST) {
2540  gz->level = Z_BEST_SPEED;
2541  }
2542  else if (head[8] & GZ_EXTRAFLAG_SLOW) {
2543  gz->level = Z_BEST_COMPRESSION;
2544  }
2545  else {
2546  gz->level = Z_DEFAULT_COMPRESSION;
2547  }
2548 
2549  gz->mtime = gzfile_get32(&head[4]);
2550  gz->os_code = head[9];
2551  zstream_discard_input(&gz->z, 10);
2552 
2553  if (flags & GZ_FLAG_EXTRA) {
2554  if (!gzfile_read_raw_ensure(gz, 2)) {
2555  rb_raise(cGzError, "unexpected end of file");
2556  }
2557  len = gzfile_get16((Bytef*)RSTRING_PTR(gz->z.input));
2558  if (!gzfile_read_raw_ensure(gz, 2 + len)) {
2559  rb_raise(cGzError, "unexpected end of file");
2560  }
2561  zstream_discard_input(&gz->z, 2 + len);
2562  }
2563  if (flags & GZ_FLAG_ORIG_NAME) {
2564  if (!gzfile_read_raw_ensure(gz, 1)) {
2565  rb_raise(cGzError, "unexpected end of file");
2566  }
2567  p = gzfile_read_raw_until_zero(gz, 0);
2568  len = p - RSTRING_PTR(gz->z.input);
2569  gz->orig_name = rb_str_new(RSTRING_PTR(gz->z.input), len);
2570  OBJ_TAINT(gz->orig_name); /* for safe */
2571  zstream_discard_input(&gz->z, len + 1);
2572  }
2573  if (flags & GZ_FLAG_COMMENT) {
2574  if (!gzfile_read_raw_ensure(gz, 1)) {
2575  rb_raise(cGzError, "unexpected end of file");
2576  }
2577  p = gzfile_read_raw_until_zero(gz, 0);
2578  len = p - RSTRING_PTR(gz->z.input);
2579  gz->comment = rb_str_new(RSTRING_PTR(gz->z.input), len);
2580  OBJ_TAINT(gz->comment); /* for safe */
2581  zstream_discard_input(&gz->z, len + 1);
2582  }
2583 
2584  if (gz->z.input != Qnil && RSTRING_LEN(gz->z.input) > 0) {
2585  zstream_run(&gz->z, 0, 0, Z_SYNC_FLUSH);
2586  }
2587 }
2588 
2589 static void
2591 {
2592  unsigned long crc, length;
2593 
2595 
2596  if (!gzfile_read_raw_ensure(gz, 8)) { /* 8 is the size of gzip footer */
2597  gzfile_raise(gz, cNoFooter, "footer is not found");
2598  }
2599 
2600  crc = gzfile_get32((Bytef*)RSTRING_PTR(gz->z.input));
2601  length = gzfile_get32((Bytef*)RSTRING_PTR(gz->z.input) + 4);
2602 
2603  gz->z.stream.total_in += 8; /* to rewind correctly */
2604  zstream_discard_input(&gz->z, 8);
2605 
2606  if (gz->crc != crc) {
2607  rb_raise(cCRCError, "invalid compressed data -- crc error");
2608  }
2609  if ((uint32_t)gz->z.stream.total_out != length) {
2610  rb_raise(cLengthError, "invalid compressed data -- length error");
2611  }
2612 }
2613 
2614 static void
2615 gzfile_write(struct gzfile *gz, Bytef *str, long len)
2616 {
2617  if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
2618  gzfile_make_header(gz);
2619  }
2620 
2621  if (len > 0 || (gz->z.flags & GZFILE_FLAG_SYNC)) {
2622  gz->crc = checksum_long(crc32, gz->crc, str, len);
2623  zstream_run(&gz->z, str, len, (gz->z.flags & GZFILE_FLAG_SYNC)
2624  ? Z_SYNC_FLUSH : Z_NO_FLUSH);
2625  }
2626  gzfile_write_raw(gz);
2627 }
2628 
2629 static long
2631 {
2632  volatile VALUE str;
2633 
2634  while (!ZSTREAM_IS_FINISHED(&gz->z)) {
2635  str = gzfile_read_raw(gz);
2636  if (NIL_P(str)) {
2637  if (!ZSTREAM_IS_FINISHED(&gz->z)) {
2638  rb_raise(cGzError, "unexpected end of file");
2639  }
2640  break;
2641  }
2642  if (RSTRING_LEN(str) > 0) { /* prevent Z_BUF_ERROR */
2643  zstream_run(&gz->z, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str),
2644  Z_SYNC_FLUSH);
2645  }
2646  if (gz->z.buf_filled > 0) break;
2647  }
2648  return gz->z.buf_filled;
2649 }
2650 
2651 static void
2653 {
2654  if (RSTRING_LEN(str) <= gz->ungetc) {
2655  gz->ungetc -= RSTRING_LEN(str);
2656  }
2657  else {
2658  gz->crc = checksum_long(crc32, gz->crc, (Bytef*)RSTRING_PTR(str) + gz->ungetc,
2659  RSTRING_LEN(str) - gz->ungetc);
2660  gz->ungetc = 0;
2661  }
2662 }
2663 
2664 static VALUE
2666 {
2667  if (!gz->enc2) {
2668  rb_enc_associate(str, gz->enc);
2669  OBJ_TAINT(str); /* for safe */
2670  return str;
2671  }
2672  if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
2673  str = rb_econv_str_convert(gz->ec, str, ECONV_PARTIAL_INPUT);
2674  rb_enc_associate(str, gz->enc);
2675  OBJ_TAINT(str);
2676  return str;
2677  }
2678  return rb_str_conv_enc_opts(str, gz->enc2, gz->enc,
2679  gz->ecflags, gz->ecopts);
2680 }
2681 
2682 static long
2683 gzfile_fill(struct gzfile *gz, long len)
2684 {
2685  if (len < 0)
2686  rb_raise(rb_eArgError, "negative length %ld given", len);
2687  if (len == 0)
2688  return 0;
2689  while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled < len) {
2690  gzfile_read_more(gz);
2691  }
2692  if (GZFILE_IS_FINISHED(gz)) {
2693  if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2694  gzfile_check_footer(gz);
2695  }
2696  return -1;
2697  }
2698  return len < gz->z.buf_filled ? len : gz->z.buf_filled;
2699 }
2700 
2701 static VALUE
2702 gzfile_read(struct gzfile *gz, long len)
2703 {
2704  VALUE dst;
2705 
2706  len = gzfile_fill(gz, len);
2707  if (len == 0) return rb_str_new(0, 0);
2708  if (len < 0) return Qnil;
2709  dst = zstream_shift_buffer(&gz->z, len);
2710  if (!NIL_P(dst)) gzfile_calc_crc(gz, dst);
2711  return dst;
2712 }
2713 
2714 static VALUE
2715 gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
2716 {
2717  VALUE dst;
2718 
2719  if (len < 0)
2720  rb_raise(rb_eArgError, "negative length %ld given", len);
2721 
2722  if (!NIL_P(outbuf))
2723  OBJ_TAINT(outbuf);
2724 
2725  if (len == 0) {
2726  if (NIL_P(outbuf))
2727  return rb_str_new(0, 0);
2728  else {
2729  rb_str_resize(outbuf, 0);
2730  return outbuf;
2731  }
2732  }
2733  while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled == 0) {
2734  gzfile_read_more(gz);
2735  }
2736  if (GZFILE_IS_FINISHED(gz)) {
2737  if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2738  gzfile_check_footer(gz);
2739  }
2740  if (!NIL_P(outbuf))
2741  rb_str_resize(outbuf, 0);
2742  rb_raise(rb_eEOFError, "end of file reached");
2743  }
2744 
2745  dst = zstream_shift_buffer(&gz->z, len);
2746  gzfile_calc_crc(gz, dst);
2747 
2748  if (!NIL_P(outbuf)) {
2749  rb_str_resize(outbuf, RSTRING_LEN(dst));
2750  memcpy(RSTRING_PTR(outbuf), RSTRING_PTR(dst), RSTRING_LEN(dst));
2751  dst = outbuf;
2752  }
2753  OBJ_TAINT(dst); /* for safe */
2754  return dst;
2755 }
2756 
2757 static VALUE
2759 {
2760  VALUE dst;
2761 
2762  while (!ZSTREAM_IS_FINISHED(&gz->z)) {
2763  gzfile_read_more(gz);
2764  }
2765  if (GZFILE_IS_FINISHED(gz)) {
2766  if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2767  gzfile_check_footer(gz);
2768  }
2769  return rb_str_new(0, 0);
2770  }
2771 
2772  dst = zstream_detach_buffer(&gz->z);
2773  if (NIL_P(dst)) return dst;
2774  gzfile_calc_crc(gz, dst);
2775  OBJ_TAINT(dst);
2776  return gzfile_newstr(gz, dst);
2777 }
2778 
2779 static VALUE
2781 {
2782  VALUE buf, dst = 0;
2783  int len;
2784 
2785  len = rb_enc_mbmaxlen(gz->enc);
2786  while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled < len) {
2787  gzfile_read_more(gz);
2788  }
2789  if (GZFILE_IS_FINISHED(gz)) {
2790  if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2791  gzfile_check_footer(gz);
2792  }
2793  return Qnil;
2794  }
2795 
2796  if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
2797  const unsigned char *ss, *sp, *se;
2798  unsigned char *ds, *dp, *de;
2799 
2800  if (!gz->cbuf) {
2801  gz->cbuf = ALLOC_N(char, GZFILE_CBUF_CAPA);
2802  }
2803  ss = sp = (const unsigned char*)RSTRING_PTR(gz->z.buf);
2804  se = sp + gz->z.buf_filled;
2805  ds = dp = (unsigned char *)gz->cbuf;
2806  de = (unsigned char *)ds + GZFILE_CBUF_CAPA;
2808  rb_econv_check_error(gz->ec);
2809  dst = zstream_shift_buffer(&gz->z, sp - ss);
2810  gzfile_calc_crc(gz, dst);
2811  dst = rb_str_new(gz->cbuf, dp - ds);
2812  rb_enc_associate(dst, gz->enc);
2813  OBJ_TAINT(dst);
2814  return dst;
2815  }
2816  else {
2817  buf = gz->z.buf;
2818  len = rb_enc_mbclen(RSTRING_PTR(buf), RSTRING_END(buf), gz->enc);
2819  dst = gzfile_read(gz, len);
2820  if (NIL_P(dst)) return dst;
2821  return gzfile_newstr(gz, dst);
2822  }
2823 }
2824 
2825 static void
2826 gzfile_ungets(struct gzfile *gz, const Bytef *b, long len)
2827 {
2828  zstream_buffer_ungets(&gz->z, b, len);
2829  gz->ungetc+=len;
2830 }
2831 
2832 static void
2834 {
2835  zstream_buffer_ungetbyte(&gz->z, c);
2836  gz->ungetc++;
2837 }
2838 
2839 static VALUE
2841 {
2842  struct gzfile *gz = (struct gzfile *)arg;
2843 
2844  if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
2845  gzfile_make_header(gz);
2846  }
2847 
2848  zstream_run(&gz->z, (Bytef*)"", 0, Z_FINISH);
2849  gzfile_make_footer(gz);
2850  gzfile_write_raw(gz);
2851 
2852  return Qnil;
2853 }
2854 
2855 static void
2857 {
2858  if (ZSTREAM_IS_CLOSING(&gz->z)) return;
2859  gz->z.flags |= ZSTREAM_FLAG_CLOSING;
2860 
2862 }
2863 
2864 static VALUE
2866 {
2867  struct gzfile *gz = (struct gzfile *)arg;
2868 
2869  if (GZFILE_IS_FINISHED(gz)
2870  && !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2871  gzfile_check_footer(gz);
2872  }
2873 
2874  return Qnil;
2875 }
2876 
2877 static void
2879 {
2880  if (ZSTREAM_IS_CLOSING(&gz->z)) return;
2881  gz->z.flags |= ZSTREAM_FLAG_CLOSING;
2882 
2884 }
2885 
2886 static void
2888 {
2889  long n;
2890 
2891  n = gz->z.stream.total_in;
2892  if (!NIL_P(gz->z.input)) {
2893  n += RSTRING_LEN(gz->z.input);
2894  }
2895 
2896  rb_funcall(gz->io, id_seek, 2, rb_int2inum(-n), INT2FIX(1));
2897  gzfile_reset(gz);
2898 }
2899 
2900 static VALUE
2902 {
2903  VALUE str;
2904 
2905  if (!ZSTREAM_IS_READY(&gz->z)) return Qnil;
2906  if (!GZFILE_IS_FINISHED(gz)) return Qnil;
2907  if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
2908  gzfile_check_footer(gz);
2909  }
2910  if (NIL_P(gz->z.input)) return Qnil;
2911 
2912  str = rb_str_resurrect(gz->z.input);
2913  OBJ_TAINT(str); /* for safe */
2914  return str;
2915 }
2916 
2917 static struct gzfile *
2919 {
2920  struct gzfile *gz;
2921 
2922  Data_Get_Struct(obj, struct gzfile, gz);
2923  if (!ZSTREAM_IS_READY(&gz->z)) {
2924  rb_raise(cGzError, "closed gzip stream");
2925  }
2926  return gz;
2927 }
2928 
2929 
2930 /* ------------------------------------------------------------------------- */
2931 
2932 /*
2933  * Document-class: Zlib::GzipFile
2934  *
2935  * Zlib::GzipFile is an abstract class for handling a gzip formatted
2936  * compressed file. The operations are defined in the subclasses,
2937  * Zlib::GzipReader for reading, and Zlib::GzipWriter for writing.
2938  *
2939  * GzipReader should be used by associating an IO, or IO-like, object.
2940  *
2941  * == Method Catalogue
2942  *
2943  * - ::wrap
2944  * - ::open (Zlib::GzipReader::open and Zlib::GzipWriter::open)
2945  * - #close
2946  * - #closed?
2947  * - #comment
2948  * - comment= (Zlib::GzipWriter#comment=)
2949  * - #crc
2950  * - eof? (Zlib::GzipReader#eof?)
2951  * - #finish
2952  * - #level
2953  * - lineno (Zlib::GzipReader#lineno)
2954  * - lineno= (Zlib::GzipReader#lineno=)
2955  * - #mtime
2956  * - mtime= (Zlib::GzipWriter#mtime=)
2957  * - #orig_name
2958  * - orig_name (Zlib::GzipWriter#orig_name=)
2959  * - #os_code
2960  * - path (when the underlying IO supports #path)
2961  * - #sync
2962  * - #sync=
2963  * - #to_io
2964  *
2965  * (due to internal structure, documentation may appear under Zlib::GzipReader
2966  * or Zlib::GzipWriter)
2967  */
2968 
2969 
2970 typedef struct {
2971  int argc;
2974 } new_wrap_arg_t;
2975 
2976 static VALUE
2978 {
2979  new_wrap_arg_t *arg = (new_wrap_arg_t *)tmp;
2980  return rb_class_new_instance(arg->argc, arg->argv, arg->klass);
2981 }
2982 
2983 static VALUE
2985 {
2986  struct gzfile *gz;
2987 
2988  Data_Get_Struct(obj, struct gzfile, gz);
2989  if (ZSTREAM_IS_READY(&gz->z)) {
2990  gzfile_close(gz, 1);
2991  }
2992  return Qnil;
2993 }
2994 
2995 static VALUE
2996 gzfile_wrap(int argc, VALUE *argv, VALUE klass, int close_io_on_error)
2997 {
2998  VALUE obj;
2999 
3000  if (close_io_on_error) {
3001  int state = 0;
3003  arg.argc = argc;
3004  arg.argv = argv;
3005  arg.klass = klass;
3006  obj = rb_protect(new_wrap, (VALUE)&arg, &state);
3007  if (state) {
3008  rb_io_close(argv[0]);
3009  rb_jump_tag(state);
3010  }
3011  }
3012  else {
3013  obj = rb_class_new_instance(argc, argv, klass);
3014  }
3015 
3016  if (rb_block_given_p()) {
3017  return rb_ensure(rb_yield, obj, gzfile_ensure_close, obj);
3018  }
3019  else {
3020  return obj;
3021  }
3022 }
3023 
3024 /*
3025  * Document-method: Zlib::GzipFile.wrap
3026  *
3027  * call-seq:
3028  * Zlib::GzipReader.wrap(io, ...) { |gz| ... }
3029  * Zlib::GzipWriter.wrap(io, ...) { |gz| ... }
3030  *
3031  * Creates a GzipReader or GzipWriter associated with +io+, passing in any
3032  * necessary extra options, and executes the block with the newly created
3033  * object just like File.open.
3034  *
3035  * The GzipFile object will be closed automatically after executing the block.
3036  * If you want to keep the associated IO object open, you may call
3037  * Zlib::GzipFile#finish method in the block.
3038  */
3039 static VALUE
3040 rb_gzfile_s_wrap(int argc, VALUE *argv, VALUE klass)
3041 {
3042  return gzfile_wrap(argc, argv, klass, 0);
3043 }
3044 
3045 /*
3046  * Document-method: Zlib::GzipFile.open
3047  *
3048  * See Zlib::GzipReader#open and Zlib::GzipWriter#open.
3049  */
3050 static VALUE
3051 gzfile_s_open(int argc, VALUE *argv, VALUE klass, const char *mode)
3052 {
3053  VALUE io, filename;
3054 
3055  if (argc < 1) {
3056  rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
3057  }
3058  filename = argv[0];
3059  io = rb_file_open_str(filename, mode);
3060  argv[0] = io;
3061  return gzfile_wrap(argc, argv, klass, 1);
3062 }
3063 
3064 /*
3065  * Document-method: Zlib::GzipFile#to_io
3066  *
3067  * Same as IO.
3068  */
3069 static VALUE
3071 {
3072  return get_gzfile(obj)->io;
3073 }
3074 
3075 /*
3076  * Document-method: Zlib::GzipFile#crc
3077  *
3078  * Returns CRC value of the uncompressed data.
3079  */
3080 static VALUE
3082 {
3083  return rb_uint2inum(get_gzfile(obj)->crc);
3084 }
3085 
3086 /*
3087  * Document-method: Zlib::GzipFile#mtime
3088  *
3089  * Returns last modification time recorded in the gzip file header.
3090  */
3091 static VALUE
3093 {
3094  return rb_time_new(get_gzfile(obj)->mtime, (time_t)0);
3095 }
3096 
3097 /*
3098  * Document-method: Zlib::GzipFile#level
3099  *
3100  * Returns compression level.
3101  */
3102 static VALUE
3104 {
3105  return INT2FIX(get_gzfile(obj)->level);
3106 }
3107 
3108 /*
3109  * Document-method: Zlib::GzipFile#os_code
3110  *
3111  * Returns OS code number recorded in the gzip file header.
3112  */
3113 static VALUE
3115 {
3116  return INT2FIX(get_gzfile(obj)->os_code);
3117 }
3118 
3119 /*
3120  * Document-method: Zlib::GzipFile#orig_name
3121  *
3122  * Returns original filename recorded in the gzip file header, or +nil+ if
3123  * original filename is not present.
3124  */
3125 static VALUE
3127 {
3128  VALUE str = get_gzfile(obj)->orig_name;
3129  if (!NIL_P(str)) {
3130  str = rb_str_dup(str);
3131  }
3132  OBJ_TAINT(str); /* for safe */
3133  return str;
3134 }
3135 
3136 /*
3137  * Document-method: Zlib::GzipFile#comment
3138  *
3139  * Returns comments recorded in the gzip file header, or nil if the comments
3140  * is not present.
3141  */
3142 static VALUE
3144 {
3145  VALUE str = get_gzfile(obj)->comment;
3146  if (!NIL_P(str)) {
3147  str = rb_str_dup(str);
3148  }
3149  OBJ_TAINT(str); /* for safe */
3150  return str;
3151 }
3152 
3153 /*
3154  * Document-method: Zlib::GzipFile#lineno
3155  *
3156  * The line number of the last row read from this file.
3157  */
3158 static VALUE
3160 {
3161  return INT2NUM(get_gzfile(obj)->lineno);
3162 }
3163 
3164 /*
3165  * Document-method: Zlib::GzipReader#lineno=
3166  *
3167  * Specify line number of the last row read from this file.
3168  */
3169 static VALUE
3171 {
3172  struct gzfile *gz = get_gzfile(obj);
3173  gz->lineno = NUM2INT(lineno);
3174  return lineno;
3175 }
3176 
3177 /*
3178  * Document-method: Zlib::GzipWriter#mtime=
3179  *
3180  * Specify the modification time (+mtime+) in the gzip header.
3181  * Using a Fixnum or Integer
3182  */
3183 static VALUE
3185 {
3186  struct gzfile *gz = get_gzfile(obj);
3187  VALUE val;
3188 
3189  if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
3190  rb_raise(cGzError, "header is already written");
3191  }
3192 
3193  if (FIXNUM_P(mtime)) {
3194  gz->mtime = FIX2INT(mtime);
3195  }
3196  else {
3197  val = rb_Integer(mtime);
3198  gz->mtime = FIXNUM_P(val) ? FIX2UINT(val) : rb_big2ulong(val);
3199  }
3200  return mtime;
3201 }
3202 
3203 /*
3204  * Document-method: Zlib::GzipFile#orig_name=
3205  *
3206  * Specify the original name (+str+) in the gzip header.
3207  */
3208 static VALUE
3210 {
3211  struct gzfile *gz = get_gzfile(obj);
3212  VALUE s;
3213  char *p;
3214 
3215  if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
3216  rb_raise(cGzError, "header is already written");
3217  }
3218  s = rb_str_dup(rb_str_to_str(str));
3219  p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
3220  if (p) {
3221  rb_str_resize(s, p - RSTRING_PTR(s));
3222  }
3223  gz->orig_name = s;
3224  return str;
3225 }
3226 
3227 /*
3228  * Document-method: Zlib::GzipFile#comment=
3229  *
3230  * Specify the comment (+str+) in the gzip header.
3231  */
3232 static VALUE
3234 {
3235  struct gzfile *gz = get_gzfile(obj);
3236  VALUE s;
3237  char *p;
3238 
3239  if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
3240  rb_raise(cGzError, "header is already written");
3241  }
3242  s = rb_str_dup(rb_str_to_str(str));
3243  p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
3244  if (p) {
3245  rb_str_resize(s, p - RSTRING_PTR(s));
3246  }
3247  gz->comment = s;
3248  return str;
3249 }
3250 
3251 /*
3252  * Document-method: Zlib::GzipFile#close
3253  *
3254  * Closes the GzipFile object. This method calls close method of the
3255  * associated IO object. Returns the associated IO object.
3256  */
3257 static VALUE
3259 {
3260  struct gzfile *gz = get_gzfile(obj);
3261  VALUE io;
3262 
3263  io = gz->io;
3264  gzfile_close(gz, 1);
3265  return io;
3266 }
3267 
3268 /*
3269  * Document-method: Zlib::GzipFile#finish
3270  *
3271  * Closes the GzipFile object. Unlike Zlib::GzipFile#close, this method never
3272  * calls the close method of the associated IO object. Returns the associated IO
3273  * object.
3274  */
3275 static VALUE
3277 {
3278  struct gzfile *gz = get_gzfile(obj);
3279  VALUE io;
3280 
3281  io = gz->io;
3282  gzfile_close(gz, 0);
3283  return io;
3284 }
3285 
3286 /*
3287  * Document-method: Zlib::GzipFile#closed?
3288  *
3289  * Same as IO#closed?
3290  *
3291  */
3292 static VALUE
3294 {
3295  struct gzfile *gz;
3296  Data_Get_Struct(obj, struct gzfile, gz);
3297  return NIL_P(gz->io) ? Qtrue : Qfalse;
3298 }
3299 
3300 /*
3301  * Document-method: Zlib::GzipFile#eof?
3302  *
3303  * Returns +true+ or +false+ whether the stream has reached the end.
3304  */
3305 static VALUE
3307 {
3308  struct gzfile *gz = get_gzfile(obj);
3309  return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
3310 }
3311 
3312 /*
3313  * Document-method: Zlib::GzipFile#sync
3314  *
3315  * Same as IO#sync
3316  *
3317  */
3318 static VALUE
3320 {
3321  return (get_gzfile(obj)->z.flags & GZFILE_FLAG_SYNC) ? Qtrue : Qfalse;
3322 }
3323 
3324 /*
3325  * Document-method: Zlib::GzipFile#sync=
3326  *
3327  * call-seq: sync = flag
3328  *
3329  * Same as IO. If flag is +true+, the associated IO object must respond to the
3330  * +flush+ method. While +sync+ mode is +true+, the compression ratio
3331  * decreases sharply.
3332  */
3333 static VALUE
3335 {
3336  struct gzfile *gz = get_gzfile(obj);
3337 
3338  if (RTEST(mode)) {
3339  gz->z.flags |= GZFILE_FLAG_SYNC;
3340  }
3341  else {
3342  gz->z.flags &= ~GZFILE_FLAG_SYNC;
3343  }
3344  return mode;
3345 }
3346 
3347 /*
3348  * Document-method: Zlib::GzipFile#total_in
3349  *
3350  * Total number of input bytes read so far.
3351  */
3352 static VALUE
3354 {
3355  return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
3356 }
3357 
3358 /*
3359  * Document-method: Zlib::GzipFile#total_out
3360  *
3361  * Total number of output bytes output so far.
3362  */
3363 static VALUE
3365 {
3366  struct gzfile *gz = get_gzfile(obj);
3367  return rb_uint2inum(gz->z.stream.total_out - gz->z.buf_filled);
3368 }
3369 
3370 /*
3371  * Document-method: Zlib::GzipFile#path
3372  *
3373  * call-seq: path
3374  *
3375  * Returns the path string of the associated IO-like object. This
3376  * method is only defined when the IO-like object responds to #path().
3377  */
3378 static VALUE
3380 {
3381  struct gzfile *gz;
3382  Data_Get_Struct(obj, struct gzfile, gz);
3383  return gz->path;
3384 }
3385 
3386 static void
3388 {
3389  if (!NIL_P(opts)) {
3390  rb_io_extract_encoding_option(opts, &gz->enc, &gz->enc2, NULL);
3391  }
3392  if (gz->enc2) {
3393  gz->ecflags = rb_econv_prepare_opts(opts, &opts);
3394  gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
3395  gz->ecflags, opts);
3396  gz->ecopts = opts;
3397  }
3398 }
3399 
3400 /* ------------------------------------------------------------------------- */
3401 
3402 /*
3403  * Document-class: Zlib::GzipWriter
3404  *
3405  * Zlib::GzipWriter is a class for writing gzipped files. GzipWriter should
3406  * be used with an instance of IO, or IO-like, object.
3407  *
3408  * Following two example generate the same result.
3409  *
3410  * Zlib::GzipWriter.open('hoge.gz') do |gz|
3411  * gz.write 'jugemu jugemu gokou no surikire...'
3412  * end
3413  *
3414  * File.open('hoge.gz', 'w') do |f|
3415  * gz = Zlib::GzipWriter.new(f)
3416  * gz.write 'jugemu jugemu gokou no surikire...'
3417  * gz.close
3418  * end
3419  *
3420  * To make like gzip(1) does, run following:
3421  *
3422  * orig = 'hoge.txt'
3423  * Zlib::GzipWriter.open('hoge.gz') do |gz|
3424  * gz.mtime = File.mtime(orig)
3425  * gz.orig_name = orig
3426  * gz.write IO.binread(orig)
3427  * end
3428  *
3429  * NOTE: Due to the limitation of Ruby's finalizer, you must explicitly close
3430  * GzipWriter objects by Zlib::GzipWriter#close etc. Otherwise, GzipWriter
3431  * will be not able to write the gzip footer and will generate a broken gzip
3432  * file.
3433  */
3434 
3435 static VALUE
3437 {
3438  return gzfile_writer_new(klass);
3439 }
3440 
3441 /*
3442  * call-seq: Zlib::GzipWriter.open(filename, level=nil, strategy=nil) { |gz| ... }
3443  *
3444  * Opens a file specified by +filename+ for writing gzip compressed data, and
3445  * returns a GzipWriter object associated with that file. Further details of
3446  * this method are found in Zlib::GzipWriter.new and Zlib::GzipFile.wrap.
3447  */
3448 static VALUE
3449 rb_gzwriter_s_open(int argc, VALUE *argv, VALUE klass)
3450 {
3451  return gzfile_s_open(argc, argv, klass, "wb");
3452 }
3453 
3454 /*
3455  * call-seq:
3456  * Zlib::GzipWriter.new(io, level = nil, strategy = nil, options = {})
3457  *
3458  * Creates a GzipWriter object associated with +io+. +level+ and +strategy+
3459  * should be the same as the arguments of Zlib::Deflate.new. The GzipWriter
3460  * object writes gzipped data to +io+. +io+ must respond to the
3461  * +write+ method that behaves the same as IO#write.
3462  *
3463  * The +options+ hash may be used to set the encoding of the data.
3464  * +:external_encoding+, +:internal_encoding+ and +:encoding+ may be set as in
3465  * IO::new.
3466  */
3467 static VALUE
3469 {
3470  struct gzfile *gz;
3471  VALUE io, level, strategy, opt = Qnil;
3472  int err;
3473 
3474  if (argc > 1) {
3475  opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash");
3476  if (!NIL_P(opt)) argc--;
3477  }
3478 
3479  rb_scan_args(argc, argv, "12", &io, &level, &strategy);
3480  Data_Get_Struct(obj, struct gzfile, gz);
3481 
3482  /* this is undocumented feature of zlib */
3483  gz->level = ARG_LEVEL(level);
3484  err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED,
3485  -MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));
3486  if (err != Z_OK) {
3487  raise_zlib_error(err, gz->z.stream.msg);
3488  }
3489  gz->io = io;
3490  ZSTREAM_READY(&gz->z);
3491  rb_gzfile_ecopts(gz, opt);
3492 
3493  if (rb_respond_to(io, id_path)) {
3494  gz->path = rb_funcall(gz->io, id_path, 0);
3495  rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
3496  }
3497 
3498  return obj;
3499 }
3500 
3501 /*
3502  * call-seq: flush(flush=nil)
3503  *
3504  * Flushes all the internal buffers of the GzipWriter object. The meaning of
3505  * +flush+ is same as in Zlib::Deflate#deflate. <tt>Zlib::SYNC_FLUSH</tt> is used if
3506  * +flush+ is omitted. It is no use giving flush <tt>Zlib::NO_FLUSH</tt>.
3507  */
3508 static VALUE
3510 {
3511  struct gzfile *gz = get_gzfile(obj);
3512  VALUE v_flush;
3513  int flush;
3514 
3515  rb_scan_args(argc, argv, "01", &v_flush);
3516 
3517  flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
3518  if (flush != Z_NO_FLUSH) { /* prevent Z_BUF_ERROR */
3519  zstream_run(&gz->z, (Bytef*)"", 0, flush);
3520  }
3521 
3522  gzfile_write_raw(gz);
3523  if (rb_respond_to(gz->io, id_flush)) {
3524  rb_funcall(gz->io, id_flush, 0);
3525  }
3526  return obj;
3527 }
3528 
3529 /*
3530  * Same as IO.
3531  */
3532 static VALUE
3534 {
3535  struct gzfile *gz = get_gzfile(obj);
3536 
3537  if (!RB_TYPE_P(str, T_STRING))
3538  str = rb_obj_as_string(str);
3539  if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
3540  str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2);
3541  }
3542  gzfile_write(gz, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
3543  return INT2FIX(RSTRING_LEN(str));
3544 }
3545 
3546 /*
3547  * Same as IO.
3548  */
3549 static VALUE
3551 {
3552  struct gzfile *gz = get_gzfile(obj);
3553  char c = NUM2CHR(ch);
3554 
3555  gzfile_write(gz, (Bytef*)&c, 1);
3556  return ch;
3557 }
3558 
3559 
3560 
3561 /*
3562  * Document-method: <<
3563  * Same as IO.
3564  */
3565 #define rb_gzwriter_addstr rb_io_addstr
3566 /*
3567  * Document-method: printf
3568  * Same as IO.
3569  */
3570 #define rb_gzwriter_printf rb_io_printf
3571 /*
3572  * Document-method: print
3573  * Same as IO.
3574  */
3575 #define rb_gzwriter_print rb_io_print
3576 /*
3577  * Document-method: puts
3578  * Same as IO.
3579  */
3580 #define rb_gzwriter_puts rb_io_puts
3581 
3582 
3583 /* ------------------------------------------------------------------------- */
3584 
3585 /*
3586  * Document-class: Zlib::GzipReader
3587  *
3588  * Zlib::GzipReader is the class for reading a gzipped file. GzipReader should
3589  * be used an IO, or -IO-like, object.
3590  *
3591  * Zlib::GzipReader.open('hoge.gz') {|gz|
3592  * print gz.read
3593  * }
3594  *
3595  * File.open('hoge.gz') do |f|
3596  * gz = Zlib::GzipReader.new(f)
3597  * print gz.read
3598  * gz.close
3599  * end
3600  *
3601  * == Method Catalogue
3602  *
3603  * The following methods in Zlib::GzipReader are just like their counterparts
3604  * in IO, but they raise Zlib::Error or Zlib::GzipFile::Error exception if an
3605  * error was found in the gzip file.
3606  * - #each
3607  * - #each_line
3608  * - #each_byte
3609  * - #gets
3610  * - #getc
3611  * - #lineno
3612  * - #lineno=
3613  * - #read
3614  * - #readchar
3615  * - #readline
3616  * - #readlines
3617  * - #ungetc
3618  *
3619  * Be careful of the footer of the gzip file. A gzip file has the checksum of
3620  * pre-compressed data in its footer. GzipReader checks all uncompressed data
3621  * against that checksum at the following cases, and if it fails, raises
3622  * <tt>Zlib::GzipFile::NoFooter</tt>, <tt>Zlib::GzipFile::CRCError</tt>, or
3623  * <tt>Zlib::GzipFile::LengthError</tt> exception.
3624  *
3625  * - When an reading request is received beyond the end of file (the end of
3626  * compressed data). That is, when Zlib::GzipReader#read,
3627  * Zlib::GzipReader#gets, or some other methods for reading returns nil.
3628  * - When Zlib::GzipFile#close method is called after the object reaches the
3629  * end of file.
3630  * - When Zlib::GzipReader#unused method is called after the object reaches
3631  * the end of file.
3632  *
3633  * The rest of the methods are adequately described in their own
3634  * documentation.
3635  */
3636 
3637 static VALUE
3639 {
3640  return gzfile_reader_new(klass);
3641 }
3642 
3643 /*
3644  * Document-method: Zlib::GzipReader.open
3645  *
3646  * call-seq: Zlib::GzipReader.open(filename) {|gz| ... }
3647  *
3648  * Opens a file specified by +filename+ as a gzipped file, and returns a
3649  * GzipReader object associated with that file. Further details of this method
3650  * are in Zlib::GzipReader.new and ZLib::GzipFile.wrap.
3651  */
3652 static VALUE
3653 rb_gzreader_s_open(int argc, VALUE *argv, VALUE klass)
3654 {
3655  return gzfile_s_open(argc, argv, klass, "rb");
3656 }
3657 
3658 /*
3659  * Document-method: Zlib::GzipReader.new
3660  *
3661  * call-seq:
3662  * Zlib::GzipReader.new(io, options = {})
3663  *
3664  * Creates a GzipReader object associated with +io+. The GzipReader object reads
3665  * gzipped data from +io+, and parses/decompresses it. The +io+ must
3666  * have a +read+ method that behaves same as the IO#read.
3667  *
3668  * The +options+ hash may be used to set the encoding of the data.
3669  * +:external_encoding+, +:internal_encoding+ and +:encoding+ may be set as in
3670  * IO::new.
3671  *
3672  * If the gzip file header is incorrect, raises an Zlib::GzipFile::Error
3673  * exception.
3674  */
3675 static VALUE
3677 {
3678  VALUE io, opt = Qnil;
3679  struct gzfile *gz;
3680  int err;
3681 
3682  Data_Get_Struct(obj, struct gzfile, gz);
3683  rb_scan_args(argc, argv, "1:", &io, &opt);
3684 
3685  /* this is undocumented feature of zlib */
3686  err = inflateInit2(&gz->z.stream, -MAX_WBITS);
3687  if (err != Z_OK) {
3688  raise_zlib_error(err, gz->z.stream.msg);
3689  }
3690  gz->io = io;
3691  ZSTREAM_READY(&gz->z);
3692  gzfile_read_header(gz);
3693  rb_gzfile_ecopts(gz, opt);
3694 
3695  if (rb_respond_to(io, id_path)) {
3696  gz->path = rb_funcall(gz->io, id_path, 0);
3697  rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
3698  }
3699 
3700  return obj;
3701 }
3702 
3703 /*
3704  * Document-method: Zlib::GzipReader#rewind
3705  *
3706  * Resets the position of the file pointer to the point created the GzipReader
3707  * object. The associated IO object needs to respond to the +seek+ method.
3708  */
3709 static VALUE
3711 {
3712  struct gzfile *gz = get_gzfile(obj);
3714  return INT2FIX(0);
3715 }
3716 
3717 /*
3718  * Document-method: Zlib::GzipReader#unused
3719  *
3720  * Returns the rest of the data which had read for parsing gzip format, or
3721  * +nil+ if the whole gzip file is not parsed yet.
3722  */
3723 static VALUE
3725 {
3726  struct gzfile *gz;
3727  Data_Get_Struct(obj, struct gzfile, gz);
3728  return gzfile_reader_get_unused(gz);
3729 }
3730 
3731 /*
3732  * Document-method: Zlib::GzipReader#read
3733  *
3734  * See Zlib::GzipReader documentation for a description.
3735  */
3736 static VALUE
3737 rb_gzreader_read(int argc, VALUE *argv, VALUE obj)
3738 {
3739  struct gzfile *gz = get_gzfile(obj);
3740  VALUE vlen;
3741  long len;
3742 
3743  rb_scan_args(argc, argv, "01", &vlen);
3744  if (NIL_P(vlen)) {
3745  return gzfile_read_all(gz);
3746  }
3747 
3748  len = NUM2INT(vlen);
3749  if (len < 0) {
3750  rb_raise(rb_eArgError, "negative length %ld given", len);
3751  }
3752  return gzfile_read(gz, len);
3753 }
3754 
3755 /*
3756  * Document-method: Zlib::GzipReader#readpartial
3757  *
3758  * call-seq:
3759  * gzipreader.readpartial(maxlen [, outbuf]) => string, outbuf
3760  *
3761  * Reads at most <i>maxlen</i> bytes from the gziped stream but
3762  * it blocks only if <em>gzipreader</em> has no data immediately available.
3763  * If the optional <i>outbuf</i> argument is present,
3764  * it must reference a String, which will receive the data.
3765  * It raises <code>EOFError</code> on end of file.
3766  */
3767 static VALUE
3769 {
3770  struct gzfile *gz = get_gzfile(obj);
3771  VALUE vlen, outbuf;
3772  long len;
3773 
3774  rb_scan_args(argc, argv, "11", &vlen, &outbuf);
3775 
3776  len = NUM2INT(vlen);
3777  if (len < 0) {
3778  rb_raise(rb_eArgError, "negative length %ld given", len);
3779  }
3780  if (!NIL_P(outbuf))
3781  Check_Type(outbuf, T_STRING);
3782  return gzfile_readpartial(gz, len, outbuf);
3783 }
3784 
3785 /*
3786  * Document-method: Zlib::GzipReader#getc
3787  *
3788  * See Zlib::GzipReader documentation for a description.
3789  */
3790 static VALUE
3792 {
3793  struct gzfile *gz = get_gzfile(obj);
3794 
3795  return gzfile_getc(gz);
3796 }
3797 
3798 /*
3799  * Document-method: Zlib::GzipReader#readchar
3800  *
3801  * See Zlib::GzipReader documentation for a description.
3802  */
3803 static VALUE
3805 {
3806  VALUE dst;
3807  dst = rb_gzreader_getc(obj);
3808  if (NIL_P(dst)) {
3809  rb_raise(rb_eEOFError, "end of file reached");
3810  }
3811  return dst;
3812 }
3813 
3814 /*
3815  * Document-method: Zlib::GzipReader#getbyte
3816  *
3817  * See Zlib::GzipReader documentation for a description.
3818  */
3819 static VALUE
3821 {
3822  struct gzfile *gz = get_gzfile(obj);
3823  VALUE dst;
3824 
3825  dst = gzfile_read(gz, 1);
3826  if (!NIL_P(dst)) {
3827  dst = INT2FIX((unsigned int)(RSTRING_PTR(dst)[0]) & 0xff);
3828  }
3829  return dst;
3830 }
3831 
3832 /*
3833  * Document-method: Zlib::GzipReader#readbyte
3834  *
3835  * See Zlib::GzipReader documentation for a description.
3836  */
3837 static VALUE
3839 {
3840  VALUE dst;
3841  dst = rb_gzreader_getbyte(obj);
3842  if (NIL_P(dst)) {
3843  rb_raise(rb_eEOFError, "end of file reached");
3844  }
3845  return dst;
3846 }
3847 
3848 /*
3849  * Document-method: Zlib::GzipReader#each_char
3850  *
3851  * See Zlib::GzipReader documentation for a description.
3852  */
3853 static VALUE
3855 {
3856  VALUE c;
3857 
3858  RETURN_ENUMERATOR(obj, 0, 0);
3859 
3860  while (!NIL_P(c = rb_gzreader_getc(obj))) {
3861  rb_yield(c);
3862  }
3863  return Qnil;
3864 }
3865 
3866 /*
3867  * Document-method: Zlib::GzipReader#each_byte
3868  *
3869  * See Zlib::GzipReader documentation for a description.
3870  */
3871 static VALUE
3873 {
3874  VALUE c;
3875 
3876  RETURN_ENUMERATOR(obj, 0, 0);
3877 
3878  while (!NIL_P(c = rb_gzreader_getbyte(obj))) {
3879  rb_yield(c);
3880  }
3881  return Qnil;
3882 }
3883 
3884 /*
3885  * Document-method: Zlib::GzipReader#bytes
3886  *
3887  * This is a deprecated alias for <code>each_byte</code>.
3888  */
3889 static VALUE
3891 {
3892  rb_warn("Zlib::GzipReader#bytes is deprecated; use #each_byte instead");
3893  if (!rb_block_given_p())
3894  return rb_enumeratorize(obj, ID2SYM(rb_intern("each_byte")), 0, 0);
3895  return rb_gzreader_each_byte(obj);
3896 }
3897 
3898 /*
3899  * Document-method: Zlib::GzipReader#ungetc
3900  *
3901  * See Zlib::GzipReader documentation for a description.
3902  */
3903 static VALUE
3905 {
3906  struct gzfile *gz;
3907 
3908  if (FIXNUM_P(s))
3909  return rb_gzreader_ungetbyte(obj, s);
3910  gz = get_gzfile(obj);
3911  StringValue(s);
3912  if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
3913  s = rb_str_conv_enc(s, rb_enc_get(s), gz->enc2);
3914  }
3915  gzfile_ungets(gz, (const Bytef*)RSTRING_PTR(s), RSTRING_LEN(s));
3916  return Qnil;
3917 }
3918 
3919 /*
3920  * Document-method: Zlib::GzipReader#ungetbyte
3921  *
3922  * See Zlib::GzipReader documentation for a description.
3923  */
3924 static VALUE
3926 {
3927  struct gzfile *gz = get_gzfile(obj);
3928  gzfile_ungetbyte(gz, NUM2CHR(ch));
3929  return Qnil;
3930 }
3931 
3932 static void
3934 {
3935  VALUE str;
3936  char *p;
3937  int n;
3938 
3939  while (gz->z.buf_filled == 0) {
3940  if (GZFILE_IS_FINISHED(gz)) return;
3941  gzfile_read_more(gz);
3942  }
3943  n = 0;
3944  p = RSTRING_PTR(gz->z.buf);
3945 
3946  while (n++, *(p++) == '\n') {
3947  if (n >= gz->z.buf_filled) {
3948  str = zstream_detach_buffer(&gz->z);
3949  gzfile_calc_crc(gz, str);
3950  while (gz->z.buf_filled == 0) {
3951  if (GZFILE_IS_FINISHED(gz)) return;
3952  gzfile_read_more(gz);
3953  }
3954  n = 0;
3955  p = RSTRING_PTR(gz->z.buf);
3956  }
3957  }
3958 
3959  str = zstream_shift_buffer(&gz->z, n - 1);
3960  gzfile_calc_crc(gz, str);
3961 }
3962 
3963 static void
3964 rscheck(const char *rsptr, long rslen, VALUE rs)
3965 {
3966  if (RSTRING_PTR(rs) != rsptr && RSTRING_LEN(rs) != rslen)
3967  rb_raise(rb_eRuntimeError, "rs modified");
3968 }
3969 
3970 static long
3972 {
3973  char *s = RSTRING_PTR(gz->z.buf);
3974  char *e = s + gz->z.buf_filled;
3975  char *p = rb_enc_left_char_head(s, s + n, e, gz->enc);
3976  long l = p - s;
3977  if (l < n) {
3978  n = rb_enc_precise_mbclen(p, e, gz->enc);
3979  if (MBCLEN_NEEDMORE_P(n)) {
3980  if ((l = gzfile_fill(gz, l + MBCLEN_NEEDMORE_LEN(n))) > 0) {
3981  return l;
3982  }
3983  }
3984  else if (MBCLEN_CHARFOUND_P(n)) {
3985  return l + MBCLEN_CHARFOUND_LEN(n);
3986  }
3987  }
3988  return n;
3989 }
3990 
3991 static VALUE
3992 gzreader_gets(int argc, VALUE *argv, VALUE obj)
3993 {
3994  struct gzfile *gz = get_gzfile(obj);
3995  volatile VALUE rs;
3996  VALUE dst;
3997  const char *rsptr;
3998  char *p, *res;
3999  long rslen, n, limit = -1;
4000  int rspara;
4001  rb_encoding *enc = gz->enc;
4002  int maxlen = rb_enc_mbmaxlen(enc);
4003 
4004  if (argc == 0) {
4005  rs = rb_rs;
4006  }
4007  else {
4008  VALUE lim, tmp;
4009 
4010  rb_scan_args(argc, argv, "11", &rs, &lim);
4011  if (!NIL_P(lim)) {
4012  if (!NIL_P(rs)) StringValue(rs);
4013  }
4014  else if (!NIL_P(rs)) {
4015  tmp = rb_check_string_type(rs);
4016  if (NIL_P(tmp)) {
4017  lim = rs;
4018  rs = rb_rs;
4019  }
4020  else {
4021  rs = tmp;
4022  }
4023  }
4024  if (!NIL_P(lim)) {
4025  limit = NUM2LONG(lim);
4026  if (limit == 0) return rb_str_new(0,0);
4027  }
4028  }
4029 
4030  if (NIL_P(rs)) {
4031  if (limit < 0) {
4032  dst = gzfile_read_all(gz);
4033  if (RSTRING_LEN(dst) == 0) return Qnil;
4034  }
4035  else if ((n = gzfile_fill(gz, limit)) <= 0) {
4036  return Qnil;
4037  }
4038  else {
4039  if (maxlen > 1 && n >= limit && !GZFILE_IS_FINISHED(gz)) {
4040  n = gzreader_charboundary(gz, n);
4041  }
4042  else {
4043  n = limit;
4044  }
4045  dst = zstream_shift_buffer(&gz->z, n);
4046  if (NIL_P(dst)) return dst;
4047  gzfile_calc_crc(gz, dst);
4048  dst = gzfile_newstr(gz, dst);
4049  }
4050  gz->lineno++;
4051  return dst;
4052  }
4053 
4054  if (RSTRING_LEN(rs) == 0) {
4055  rsptr = "\n\n";
4056  rslen = 2;
4057  rspara = 1;
4058  } else {
4059  rsptr = RSTRING_PTR(rs);
4060  rslen = RSTRING_LEN(rs);
4061  rspara = 0;
4062  }
4063 
4064  if (rspara) {
4066  }
4067 
4068  while (gz->z.buf_filled < rslen) {
4069  if (ZSTREAM_IS_FINISHED(&gz->z)) {
4070  if (gz->z.buf_filled > 0) gz->lineno++;
4071  return gzfile_read(gz, rslen);
4072  }
4073  gzfile_read_more(gz);
4074  }
4075 
4076  p = RSTRING_PTR(gz->z.buf);
4077  n = rslen;
4078  for (;;) {
4079  long filled;
4080  if (n > gz->z.buf_filled) {
4081  if (ZSTREAM_IS_FINISHED(&gz->z)) break;
4082  gzfile_read_more(gz);
4083  p = RSTRING_PTR(gz->z.buf) + n - rslen;
4084  }
4085  if (!rspara) rscheck(rsptr, rslen, rs);
4086  filled = gz->z.buf_filled;
4087  if (limit > 0 && filled >= limit) {
4088  filled = limit;
4089  }
4090  res = memchr(p, rsptr[0], (filled - n + 1));
4091  if (!res) {
4092  n = filled;
4093  if (limit > 0 && filled >= limit) break;
4094  n++;
4095  } else {
4096  n += (long)(res - p);
4097  p = res;
4098  if (rslen == 1 || memcmp(p, rsptr, rslen) == 0) break;
4099  p++, n++;
4100  }
4101  }
4102  if (maxlen > 1 && n == limit && (gz->z.buf_filled > n || !ZSTREAM_IS_FINISHED(&gz->z))) {
4103  n = gzreader_charboundary(gz, n);
4104  }
4105 
4106  gz->lineno++;
4107  dst = gzfile_read(gz, n);
4108  if (NIL_P(dst)) return dst;
4109  if (rspara) {
4111  }
4112 
4113  return gzfile_newstr(gz, dst);
4114 }
4115 
4116 /*
4117  * Document-method: Zlib::GzipReader#gets
4118  *
4119  * See Zlib::GzipReader documentation for a description.
4120  */
4121 static VALUE
4122 rb_gzreader_gets(int argc, VALUE *argv, VALUE obj)
4123 {
4124  VALUE dst;
4125  dst = gzreader_gets(argc, argv, obj);
4126  if (!NIL_P(dst)) {
4127  rb_lastline_set(dst);
4128  }
4129  return dst;
4130 }
4131 
4132 /*
4133  * Document-method: Zlib::GzipReader#readline
4134  *
4135  * See Zlib::GzipReader documentation for a description.
4136  */
4137 static VALUE
4139 {
4140  VALUE dst;
4141  dst = rb_gzreader_gets(argc, argv, obj);
4142  if (NIL_P(dst)) {
4143  rb_raise(rb_eEOFError, "end of file reached");
4144  }
4145  return dst;
4146 }
4147 
4148 /*
4149  * Document-method: Zlib::GzipReader#each
4150  *
4151  * See Zlib::GzipReader documentation for a description.
4152  */
4153 static VALUE
4154 rb_gzreader_each(int argc, VALUE *argv, VALUE obj)
4155 {
4156  VALUE str;
4157 
4158  RETURN_ENUMERATOR(obj, 0, 0);
4159 
4160  while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
4161  rb_yield(str);
4162  }
4163  return obj;
4164 }
4165 
4166 /*
4167  * Document-method: Zlib::GzipReader#lines
4168  *
4169  * This is a deprecated alias for <code>each_line</code>.
4170  */
4171 static VALUE
4173 {
4174  rb_warn("Zlib::GzipReader#lines is deprecated; use #each_line instead");
4175  if (!rb_block_given_p())
4176  return rb_enumeratorize(obj, ID2SYM(rb_intern("each_line")), argc, argv);
4177  return rb_gzreader_each(argc, argv, obj);
4178 }
4179 
4180 /*
4181  * Document-method: Zlib::GzipReader#readlines
4182  *
4183  * See Zlib::GzipReader documentation for a description.
4184  */
4185 static VALUE
4187 {
4188  VALUE str, dst;
4189  dst = rb_ary_new();
4190  while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
4191  rb_ary_push(dst, str);
4192  }
4193  return dst;
4194 }
4195 
4196 #endif /* GZIP_SUPPORT */
4197 
4198 void
4200 {
4201  VALUE mZlib, cZStream, cDeflate, cInflate;
4202 #if GZIP_SUPPORT
4203  VALUE cGzipFile, cGzipWriter, cGzipReader;
4204 #endif
4205 
4206  mZlib = rb_define_module("Zlib");
4207 
4208  id_dictionaries = rb_intern("@dictionaries");
4209 
4210  cZError = rb_define_class_under(mZlib, "Error", rb_eStandardError);
4211  cStreamEnd = rb_define_class_under(mZlib, "StreamEnd", cZError);
4212  cNeedDict = rb_define_class_under(mZlib, "NeedDict", cZError);
4213  cDataError = rb_define_class_under(mZlib, "DataError", cZError);
4214  cStreamError = rb_define_class_under(mZlib, "StreamError", cZError);
4215  cMemError = rb_define_class_under(mZlib, "MemError", cZError);
4216  cBufError = rb_define_class_under(mZlib, "BufError", cZError);
4217  cVersionError = rb_define_class_under(mZlib, "VersionError", cZError);
4218 
4219  rb_define_module_function(mZlib, "zlib_version", rb_zlib_version, 0);
4220  rb_define_module_function(mZlib, "adler32", rb_zlib_adler32, -1);
4221  rb_define_module_function(mZlib, "adler32_combine", rb_zlib_adler32_combine, 3);
4222  rb_define_module_function(mZlib, "crc32", rb_zlib_crc32, -1);
4223  rb_define_module_function(mZlib, "crc32_combine", rb_zlib_crc32_combine, 3);
4224  rb_define_module_function(mZlib, "crc_table", rb_zlib_crc_table, 0);
4225 
4226  /* The Ruby/zlib version string. */
4227  rb_define_const(mZlib, "VERSION", rb_str_new2(RUBY_ZLIB_VERSION));
4228  /* The string which represents the version of zlib.h */
4229  rb_define_const(mZlib, "ZLIB_VERSION", rb_str_new2(ZLIB_VERSION));
4230 
4231  cZStream = rb_define_class_under(mZlib, "ZStream", rb_cObject);
4232  rb_undef_alloc_func(cZStream);
4233  rb_define_method(cZStream, "avail_out", rb_zstream_avail_out, 0);
4234  rb_define_method(cZStream, "avail_out=", rb_zstream_set_avail_out, 1);
4235  rb_define_method(cZStream, "avail_in", rb_zstream_avail_in, 0);
4236  rb_define_method(cZStream, "total_in", rb_zstream_total_in, 0);
4237  rb_define_method(cZStream, "total_out", rb_zstream_total_out, 0);
4238  rb_define_method(cZStream, "data_type", rb_zstream_data_type, 0);
4239  rb_define_method(cZStream, "adler", rb_zstream_adler, 0);
4240  rb_define_method(cZStream, "finished?", rb_zstream_finished_p, 0);
4241  rb_define_method(cZStream, "stream_end?", rb_zstream_finished_p, 0);
4242  rb_define_method(cZStream, "closed?", rb_zstream_closed_p, 0);
4243  rb_define_method(cZStream, "ended?", rb_zstream_closed_p, 0);
4244  rb_define_method(cZStream, "close", rb_zstream_end, 0);
4245  rb_define_method(cZStream, "end", rb_zstream_end, 0);
4246  rb_define_method(cZStream, "reset", rb_zstream_reset, 0);
4247  rb_define_method(cZStream, "finish", rb_zstream_finish, 0);
4248  rb_define_method(cZStream, "flush_next_in", rb_zstream_flush_next_in, 0);
4249  rb_define_method(cZStream, "flush_next_out", rb_zstream_flush_next_out, 0);
4250 
4251  /* Represents binary data as guessed by deflate.
4252  *
4253  * See Zlib::Deflate#data_type. */
4254  rb_define_const(mZlib, "BINARY", INT2FIX(Z_BINARY));
4255 
4256  /* Represents text data as guessed by deflate.
4257  *
4258  * NOTE: The underlying constant Z_ASCII was deprecated in favor of Z_TEXT
4259  * in zlib 1.2.2. New applications should not use this constant.
4260  *
4261  * See Zlib::Deflate#data_type. */
4262  rb_define_const(mZlib, "ASCII", INT2FIX(Z_ASCII));
4263 
4264 #ifdef Z_TEXT
4265  /* Represents text data as guessed by deflate.
4266  *
4267  * See Zlib::Deflate#data_type. */
4268  rb_define_const(mZlib, "TEXT", INT2FIX(Z_TEXT));
4269 #endif
4270 
4271  /* Represents an unknown data type as guessed by deflate.
4272  *
4273  * See Zlib::Deflate#data_type. */
4274  rb_define_const(mZlib, "UNKNOWN", INT2FIX(Z_UNKNOWN));
4275 
4276  cDeflate = rb_define_class_under(mZlib, "Deflate", cZStream);
4277  rb_define_singleton_method(cDeflate, "deflate", rb_deflate_s_deflate, -1);
4278  rb_define_singleton_method(mZlib, "deflate", rb_deflate_s_deflate, -1);
4280  rb_define_method(cDeflate, "initialize", rb_deflate_initialize, -1);
4281  rb_define_method(cDeflate, "initialize_copy", rb_deflate_init_copy, 1);
4282  rb_define_method(cDeflate, "deflate", rb_deflate_deflate, -1);
4283  rb_define_method(cDeflate, "<<", rb_deflate_addstr, 1);
4284  rb_define_method(cDeflate, "flush", rb_deflate_flush, -1);
4285  rb_define_method(cDeflate, "params", rb_deflate_params, 2);
4286  rb_define_method(cDeflate, "set_dictionary", rb_deflate_set_dictionary, 1);
4287 
4288  cInflate = rb_define_class_under(mZlib, "Inflate", cZStream);
4289  rb_define_singleton_method(cInflate, "inflate", rb_inflate_s_inflate, 1);
4290  rb_define_singleton_method(mZlib, "inflate", rb_inflate_s_inflate, 1);
4292  rb_define_method(cInflate, "initialize", rb_inflate_initialize, -1);
4293  rb_define_method(cInflate, "add_dictionary", rb_inflate_add_dictionary, 1);
4294  rb_define_method(cInflate, "inflate", rb_inflate_inflate, 1);
4295  rb_define_method(cInflate, "<<", rb_inflate_addstr, 1);
4296  rb_define_method(cInflate, "sync", rb_inflate_sync, 1);
4297  rb_define_method(cInflate, "sync_point?", rb_inflate_sync_point_p, 0);
4298  rb_define_method(cInflate, "set_dictionary", rb_inflate_set_dictionary, 1);
4299 
4300  /* No compression, passes through data untouched. Use this for appending
4301  * pre-compressed data to a deflate stream.
4302  */
4303  rb_define_const(mZlib, "NO_COMPRESSION", INT2FIX(Z_NO_COMPRESSION));
4304  /* Fastest compression level, but with with lowest space savings. */
4305  rb_define_const(mZlib, "BEST_SPEED", INT2FIX(Z_BEST_SPEED));
4306  /* Slowest compression level, but with the best space savings. */
4307  rb_define_const(mZlib, "BEST_COMPRESSION", INT2FIX(Z_BEST_COMPRESSION));
4308  /* Default compression level which is a good trade-off between space and
4309  * time
4310  */
4311  rb_define_const(mZlib, "DEFAULT_COMPRESSION",
4312  INT2FIX(Z_DEFAULT_COMPRESSION));
4313 
4314  /* Deflate strategy for data produced by a filter (or predictor). The
4315  * effect of FILTERED is to force more Huffman codes and less string
4316  * matching; it is somewhat intermediate between DEFAULT_STRATEGY and
4317  * HUFFMAN_ONLY. Filtered data consists mostly of small values with a
4318  * somewhat random distribution.
4319  */
4320  rb_define_const(mZlib, "FILTERED", INT2FIX(Z_FILTERED));
4321 
4322  /* Deflate strategy which uses Huffman codes only (no string matching). */
4323  rb_define_const(mZlib, "HUFFMAN_ONLY", INT2FIX(Z_HUFFMAN_ONLY));
4324 
4325 #ifdef Z_RLE
4326  /* Deflate compression strategy designed to be almost as fast as
4327  * HUFFMAN_ONLY, but give better compression for PNG image data.
4328  */
4329  rb_define_const(mZlib, "RLE", INT2FIX(Z_RLE));
4330 #endif
4331 
4332 #ifdef Z_FIXED
4333  /* Deflate strategy which prevents the use of dynamic Huffman codes,
4334  * allowing for a simpler decoder for specialized applications.
4335  */
4336  rb_define_const(mZlib, "FIXED", INT2FIX(Z_FIXED));
4337 #endif
4338 
4339  /* Default deflate strategy which is used for normal data. */
4340  rb_define_const(mZlib, "DEFAULT_STRATEGY", INT2FIX(Z_DEFAULT_STRATEGY));
4341 
4342  /* The maximum size of the zlib history buffer. Note that zlib allows
4343  * larger values to enable different inflate modes. See Zlib::Inflate.new
4344  * for details.
4345  */
4346  rb_define_const(mZlib, "MAX_WBITS", INT2FIX(MAX_WBITS));
4347 
4348  /* The default memory level for allocating zlib deflate compression state.
4349  */
4350  rb_define_const(mZlib, "DEF_MEM_LEVEL", INT2FIX(DEF_MEM_LEVEL));
4351 
4352  /* The maximum memory level for allocating zlib deflate compression state.
4353  */
4354  rb_define_const(mZlib, "MAX_MEM_LEVEL", INT2FIX(MAX_MEM_LEVEL));
4355 
4356  /* NO_FLUSH is the default flush method and allows deflate to decide how
4357  * much data to accumulate before producing output in order to maximize
4358  * compression.
4359  */
4360  rb_define_const(mZlib, "NO_FLUSH", INT2FIX(Z_NO_FLUSH));
4361 
4362  /* The SYNC_FLUSH method flushes all pending output to the output buffer
4363  * and the output is aligned on a byte boundary. Flushing may degrade
4364  * compression so it should be used only when necessary, such as at a
4365  * request or response boundary for a network stream.
4366  */
4367  rb_define_const(mZlib, "SYNC_FLUSH", INT2FIX(Z_SYNC_FLUSH));
4368 
4369  /* Flushes all output as with SYNC_FLUSH, and the compression state is
4370  * reset so that decompression can restart from this point if previous
4371  * compressed data has been damaged or if random access is desired. Like
4372  * SYNC_FLUSH, using FULL_FLUSH too often can seriously degrade
4373  * compression.
4374  */
4375  rb_define_const(mZlib, "FULL_FLUSH", INT2FIX(Z_FULL_FLUSH));
4376 
4377  /* Processes all pending input and flushes pending output. */
4378  rb_define_const(mZlib, "FINISH", INT2FIX(Z_FINISH));
4379 
4380 #if GZIP_SUPPORT
4381  id_write = rb_intern("write");
4382  id_read = rb_intern("read");
4383  id_readpartial = rb_intern("readpartial");
4384  id_flush = rb_intern("flush");
4385  id_seek = rb_intern("seek");
4386  id_close = rb_intern("close");
4387  id_path = rb_intern("path");
4388  id_input = rb_intern("@input");
4389 
4390  cGzipFile = rb_define_class_under(mZlib, "GzipFile", rb_cObject);
4391  cGzError = rb_define_class_under(cGzipFile, "Error", cZError);
4392 
4393  /* input gzipped string */
4394  rb_define_attr(cGzError, "input", 1, 0);
4395  rb_define_method(cGzError, "inspect", gzfile_error_inspect, 0);
4396 
4397  cNoFooter = rb_define_class_under(cGzipFile, "NoFooter", cGzError);
4398  cCRCError = rb_define_class_under(cGzipFile, "CRCError", cGzError);
4399  cLengthError = rb_define_class_under(cGzipFile,"LengthError",cGzError);
4400 
4401  cGzipWriter = rb_define_class_under(mZlib, "GzipWriter", cGzipFile);
4402  cGzipReader = rb_define_class_under(mZlib, "GzipReader", cGzipFile);
4403  rb_include_module(cGzipReader, rb_mEnumerable);
4404 
4405  rb_define_singleton_method(cGzipFile, "wrap", rb_gzfile_s_wrap, -1);
4406  rb_undef_alloc_func(cGzipFile);
4407  rb_define_method(cGzipFile, "to_io", rb_gzfile_to_io, 0);
4408  rb_define_method(cGzipFile, "crc", rb_gzfile_crc, 0);
4409  rb_define_method(cGzipFile, "mtime", rb_gzfile_mtime, 0);
4410  rb_define_method(cGzipFile, "level", rb_gzfile_level, 0);
4411  rb_define_method(cGzipFile, "os_code", rb_gzfile_os_code, 0);
4412  rb_define_method(cGzipFile, "orig_name", rb_gzfile_orig_name, 0);
4413  rb_define_method(cGzipFile, "comment", rb_gzfile_comment, 0);
4414  rb_define_method(cGzipReader, "lineno", rb_gzfile_lineno, 0);
4415  rb_define_method(cGzipReader, "lineno=", rb_gzfile_set_lineno, 1);
4416  rb_define_method(cGzipWriter, "mtime=", rb_gzfile_set_mtime, 1);
4417  rb_define_method(cGzipWriter, "orig_name=", rb_gzfile_set_orig_name,1);
4418  rb_define_method(cGzipWriter, "comment=", rb_gzfile_set_comment, 1);
4419  rb_define_method(cGzipFile, "close", rb_gzfile_close, 0);
4420  rb_define_method(cGzipFile, "finish", rb_gzfile_finish, 0);
4421  rb_define_method(cGzipFile, "closed?", rb_gzfile_closed_p, 0);
4422  rb_define_method(cGzipReader, "eof", rb_gzfile_eof_p, 0);
4423  rb_define_method(cGzipReader, "eof?", rb_gzfile_eof_p, 0);
4424  rb_define_method(cGzipFile, "sync", rb_gzfile_sync, 0);
4425  rb_define_method(cGzipFile, "sync=", rb_gzfile_set_sync, 1);
4426  rb_define_method(cGzipReader, "pos", rb_gzfile_total_out, 0);
4427  rb_define_method(cGzipWriter, "pos", rb_gzfile_total_in, 0);
4428  rb_define_method(cGzipReader, "tell", rb_gzfile_total_out, 0);
4429  rb_define_method(cGzipWriter, "tell", rb_gzfile_total_in, 0);
4430 
4431  rb_define_singleton_method(cGzipWriter, "open", rb_gzwriter_s_open,-1);
4433  rb_define_method(cGzipWriter, "initialize", rb_gzwriter_initialize,-1);
4434  rb_define_method(cGzipWriter, "flush", rb_gzwriter_flush, -1);
4435  rb_define_method(cGzipWriter, "write", rb_gzwriter_write, 1);
4436  rb_define_method(cGzipWriter, "putc", rb_gzwriter_putc, 1);
4437  rb_define_method(cGzipWriter, "<<", rb_gzwriter_addstr, 1);
4438  rb_define_method(cGzipWriter, "printf", rb_gzwriter_printf, -1);
4439  rb_define_method(cGzipWriter, "print", rb_gzwriter_print, -1);
4440  rb_define_method(cGzipWriter, "puts", rb_gzwriter_puts, -1);
4441 
4442  rb_define_singleton_method(cGzipReader, "open", rb_gzreader_s_open,-1);
4444  rb_define_method(cGzipReader, "initialize", rb_gzreader_initialize, -1);
4445  rb_define_method(cGzipReader, "rewind", rb_gzreader_rewind, 0);
4446  rb_define_method(cGzipReader, "unused", rb_gzreader_unused, 0);
4447  rb_define_method(cGzipReader, "read", rb_gzreader_read, -1);
4448  rb_define_method(cGzipReader, "readpartial", rb_gzreader_readpartial, -1);
4449  rb_define_method(cGzipReader, "getc", rb_gzreader_getc, 0);
4450  rb_define_method(cGzipReader, "getbyte", rb_gzreader_getbyte, 0);
4451  rb_define_method(cGzipReader, "readchar", rb_gzreader_readchar, 0);
4452  rb_define_method(cGzipReader, "readbyte", rb_gzreader_readbyte, 0);
4453  rb_define_method(cGzipReader, "each_byte", rb_gzreader_each_byte, 0);
4454  rb_define_method(cGzipReader, "each_char", rb_gzreader_each_char, 0);
4455  rb_define_method(cGzipReader, "bytes", rb_gzreader_bytes, 0);
4456  rb_define_method(cGzipReader, "ungetc", rb_gzreader_ungetc, 1);
4457  rb_define_method(cGzipReader, "ungetbyte", rb_gzreader_ungetbyte, 1);
4458  rb_define_method(cGzipReader, "gets", rb_gzreader_gets, -1);
4459  rb_define_method(cGzipReader, "readline", rb_gzreader_readline, -1);
4460  rb_define_method(cGzipReader, "each", rb_gzreader_each, -1);
4461  rb_define_method(cGzipReader, "each_line", rb_gzreader_each, -1);
4462  rb_define_method(cGzipReader, "lines", rb_gzreader_lines, -1);
4463  rb_define_method(cGzipReader, "readlines", rb_gzreader_readlines, -1);
4464 
4465  /* The OS code of current host */
4466  rb_define_const(mZlib, "OS_CODE", INT2FIX(OS_CODE));
4467  /* OS code for MSDOS hosts */
4468  rb_define_const(mZlib, "OS_MSDOS", INT2FIX(OS_MSDOS));
4469  /* OS code for Amiga hosts */
4470  rb_define_const(mZlib, "OS_AMIGA", INT2FIX(OS_AMIGA));
4471  /* OS code for VMS hosts */
4472  rb_define_const(mZlib, "OS_VMS", INT2FIX(OS_VMS));
4473  /* OS code for UNIX hosts */
4474  rb_define_const(mZlib, "OS_UNIX", INT2FIX(OS_UNIX));
4475  /* OS code for Atari hosts */
4476  rb_define_const(mZlib, "OS_ATARI", INT2FIX(OS_ATARI));
4477  /* OS code for OS2 hosts */
4478  rb_define_const(mZlib, "OS_OS2", INT2FIX(OS_OS2));
4479  /* OS code for Mac OS hosts */
4480  rb_define_const(mZlib, "OS_MACOS", INT2FIX(OS_MACOS));
4481  /* OS code for TOPS-20 hosts */
4482  rb_define_const(mZlib, "OS_TOPS20", INT2FIX(OS_TOPS20));
4483  /* OS code for Win32 hosts */
4484  rb_define_const(mZlib, "OS_WIN32", INT2FIX(OS_WIN32));
4485  /* OS code for VM OS hosts */
4486  rb_define_const(mZlib, "OS_VMCMS", INT2FIX(OS_VMCMS));
4487  /* OS code for Z-System hosts */
4488  rb_define_const(mZlib, "OS_ZSYSTEM", INT2FIX(OS_ZSYSTEM));
4489  /* OS code for CP/M hosts */
4490  rb_define_const(mZlib, "OS_CPM", INT2FIX(OS_CPM));
4491  /* OS code for QDOS hosts */
4492  rb_define_const(mZlib, "OS_QDOS", INT2FIX(OS_QDOS));
4493  /* OS code for RISC OS hosts */
4494  rb_define_const(mZlib, "OS_RISCOS", INT2FIX(OS_RISCOS));
4495  /* OS code for unknown hosts */
4496  rb_define_const(mZlib, "OS_UNKNOWN", INT2FIX(OS_UNKNOWN));
4497 
4498 #endif /* GZIP_SUPPORT */
4499 }
4500 
4501 /* Document error classes. */
4502 
4503 /*
4504  * Document-class: Zlib::Error
4505  *
4506  * The superclass for all exceptions raised by Ruby/zlib.
4507  *
4508  * The following exceptions are defined as subclasses of Zlib::Error. These
4509  * exceptions are raised when zlib library functions return with an error
4510  * status.
4511  *
4512  * - Zlib::StreamEnd
4513  * - Zlib::NeedDict
4514  * - Zlib::DataError
4515  * - Zlib::StreamError
4516  * - Zlib::MemError
4517  * - Zlib::BufError
4518  * - Zlib::VersionError
4519  *
4520  */
4521 
4522 /*
4523  * Document-class: Zlib::StreamEnd
4524  *
4525  * Subclass of Zlib::Error
4526  *
4527  * When zlib returns a Z_STREAM_END
4528  * is return if the end of the compressed data has been reached
4529  * and all uncompressed out put has been produced.
4530  *
4531  */
4532 
4533 /*
4534  * Document-class: Zlib::NeedDict
4535  *
4536  * Subclass of Zlib::Error
4537  *
4538  * When zlib returns a Z_NEED_DICT
4539  * if a preset dictionary is needed at this point.
4540  *
4541  * Used by Zlib::Inflate.inflate and <tt>Zlib.inflate</tt>
4542  */
4543 
4544 /*
4545  * Document-class: Zlib::VersionError
4546  *
4547  * Subclass of Zlib::Error
4548  *
4549  * When zlib returns a Z_VERSION_ERROR,
4550  * usually if the zlib library version is incompatible with the
4551  * version assumed by the caller.
4552  *
4553  */
4554 
4555 /*
4556  * Document-class: Zlib::MemError
4557  *
4558  * Subclass of Zlib::Error
4559  *
4560  * When zlib returns a Z_MEM_ERROR,
4561  * usually if there was not enough memory.
4562  *
4563  */
4564 
4565 /*
4566  * Document-class: Zlib::StreamError
4567  *
4568  * Subclass of Zlib::Error
4569  *
4570  * When zlib returns a Z_STREAM_ERROR,
4571  * usually if the stream state was inconsistent.
4572  *
4573  */
4574 
4575 /*
4576  * Document-class: Zlib::BufError
4577  *
4578  * Subclass of Zlib::Error when zlib returns a Z_BUF_ERROR.
4579  *
4580  * Usually if no progress is possible.
4581  *
4582  */
4583 
4584 /*
4585  * Document-class: Zlib::DataError
4586  *
4587  * Subclass of Zlib::Error when zlib returns a Z_DATA_ERROR.
4588  *
4589  * Usually if a stream was prematurely freed.
4590  *
4591  */
4592 
4593 /*
4594  * Document-class: Zlib::GzipFile::Error
4595  *
4596  * Base class of errors that occur when processing GZIP files.
4597  */
4598 
4599 /*
4600  * Document-class: Zlib::GzipFile::NoFooter
4601  *
4602  * Raised when gzip file footer is not found.
4603  */
4604 
4605 /*
4606  * Document-class: Zlib::GzipFile::CRCError
4607  *
4608  * Raised when the CRC checksum recorded in gzip file footer is not equivalent
4609  * to the CRC checksum of the actual uncompressed data.
4610  */
4611 
4612 /*
4613  * Document-class: Zlib::GzipFile::LengthError
4614  *
4615  * Raised when the data length recorded in the gzip file footer is not equivalent
4616  * to the length of the actual uncompressed data.
4617  */
4618 
4619 
#define RB_TYPE_P(obj, type)
static VALUE rb_gzreader_ungetbyte(VALUE, VALUE)
Definition: zlib.c:3925
static VALUE rb_zstream_closed_p(VALUE)
Definition: zlib.c:1418
#define ZSTREAM_IS_CLOSING(z)
Definition: zlib.c:555
static VALUE rb_zstream_avail_out(VALUE)
Definition: zlib.c:1333
#define OS_RISCOS
Definition: zlib.c:2175
static VALUE rb_inflate_s_allocate(VALUE)
Definition: zlib.c:1813
volatile VALUE tmp
Definition: tcltklib.c:10209
static VALUE rb_gzreader_unused(VALUE)
Definition: zlib.c:3724
VALUE rb_eStandardError
Definition: error.c:509
static VALUE rb_gzfile_os_code(VALUE)
Definition: zlib.c:3114
struct zstream_funcs * funcs
Definition: zlib.c:2252
static VALUE rb_gzfile_set_comment(VALUE, VALUE)
Definition: zlib.c:3233
static void gzfile_set32(unsigned long n, unsigned char *)
Definition: zlib.c:2415
ssize_t n
Definition: bigdecimal.c:5655
static VALUE rb_deflate_params(VALUE, VALUE, VALUE)
Definition: zlib.c:1742
#define RSTRING(obj)
static VALUE rb_gzfile_comment(VALUE)
Definition: zlib.c:3143
rb_econv_t * ec
Definition: zlib.c:2203
static VALUE rb_gzfile_to_io(VALUE)
Definition: zlib.c:3070
static VALUE new_wrap(VALUE tmp)
Definition: zlib.c:2977
VP_EXPORT int
Definition: bigdecimal.c:5050
VALUE rb_str_resurrect(VALUE str)
Definition: string.c:952
static VALUE rb_gzfile_level(VALUE)
Definition: zlib.c:3103
static void finalizer_warn(const char *)
Definition: zlib.c:354
#define GZFILE_FLAG_SYNC
Definition: zlib.c:2211
#define MBCLEN_NEEDMORE_LEN(ret)
#define OBJ_INFECT(x, s)
static void zstream_mark(struct zstream *)
Definition: zlib.c:1136
static VALUE rb_zstream_set_avail_out(VALUE, VALUE)
Definition: zlib.c:1347
VALUE rb_class_new_instance(int, VALUE *, VALUE)
Definition: object.c:1756
#define FIX2UINT(x)
void(* end)(struct gzfile *)
Definition: zlib.c:2200
Win32OLEIDispatch * p
Definition: win32ole.c:786
#define RSTRING_END(str)
static VALUE rb_gzwriter_putc(VALUE, VALUE)
Definition: zlib.c:3550
static VALUE rb_zstream_end(VALUE)
Definition: zlib.c:1258
static void gzfile_check_footer(struct gzfile *)
Definition: zlib.c:2590
#define ECONV_AFTER_OUTPUT
#define OS_UNKNOWN
Definition: zlib.c:2176
VALUE rb_big2ulong(VALUE x)
Definition: bignum.c:1225
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1493
static VALUE rb_gzreader_readbyte(VALUE obj)
Definition: zlib.c:3838
#define zstream_init_inflate(z)
Definition: zlib.c:620
#define ZSTREAM_AVAIL_OUT_STEP_MAX
Definition: zlib.c:564
static void zstream_expand_buffer_into(struct zstream *, unsigned long)
Definition: zlib.c:672
VALUE comment
Definition: zlib.c:2196
#define Data_Make_Struct(klass, type, mark, free, sval)
static VALUE rb_gzfile_mtime(VALUE)
Definition: zlib.c:3092
void(* endfunc)(struct gzfile *)
Definition: zlib.c:2253
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:108
#define rb_zlib_adler32_combine
Definition: zlib.c:461
static VALUE rb_gzfile_set_mtime(VALUE, VALUE)
Definition: zlib.c:3184
static VALUE rb_gzwriter_initialize(int, VALUE *, VALUE)
Definition: zlib.c:3468
static VALUE cNoFooter
Definition: zlib.c:2183
static VALUE cMemError
Definition: zlib.c:303
ssize_t i
Definition: bigdecimal.c:5655
static ID id_readpartial
Definition: zlib.c:2182
RUBY_EXTERN void * memmove(void *, const void *, size_t)
Definition: memmove.c:7
#define OS_AMIGA
Definition: zlib.c:2162
static void zstream_unblock_func(void *ptr)
Definition: zlib.c:1022
#define GZ_FLAG_ORIG_NAME
Definition: zlib.c:2152
static void gzfile_read_header(struct gzfile *)
Definition: zlib.c:2509
VALUE rb_str_subseq(VALUE, long, long)
Definition: string.c:1668
static void zstream_buffer_ungetbyte(struct zstream *, int)
Definition: zlib.c:846
static void gzfile_ungets(struct gzfile *, const Bytef *, long)
Definition: zlib.c:2826
static void do_inflate(struct zstream *, VALUE)
Definition: zlib.c:1942
static void do_deflate(struct zstream *, VALUE, int)
Definition: zlib.c:1630
static VALUE gzfile_reader_get_unused(struct gzfile *)
Definition: zlib.c:2901
static void zstream_reset_input(struct zstream *)
Definition: zlib.c:894
#define OS_OS2
Definition: zlib.c:2166
static char * gzfile_read_raw_until_zero(struct gzfile *, long)
Definition: zlib.c:2375
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE exc
Definition: tcltklib.c:3096
static VALUE rb_gzreader_getc(VALUE)
Definition: zlib.c:3791
VALUE enc
Definition: tcltklib.c:10311
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
VALUE io
Definition: zlib.c:2191
static VALUE rb_zstream_finished_p(VALUE)
Definition: zlib.c:1409
int os_code
Definition: zlib.c:2194
#define NUM2ULONG(x)
VALUE path
Definition: zlib.c:2207
#define RSTRING_PTR(str)
NIL_P(eventloop_thread)
Definition: tcltklib.c:4068
void rb_lastline_set(VALUE)
Definition: vm.c:780
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
Definition: eval.c:771
#define xfree
#define MBCLEN_NEEDMORE_P(ret)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
static VALUE rb_inflate_set_dictionary(VALUE, VALUE)
Definition: zlib.c:2119
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:545
static VALUE rb_deflate_s_allocate(VALUE)
Definition: zlib.c:1447
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
static VALUE zstream_detach_input(struct zstream *)
Definition: zlib.c:909
gz os_code
Definition: zlib.c:2264
#define T_HASH
return Qtrue
Definition: tcltklib.c:9610
static void zstream_append_input(struct zstream *, const Bytef *, long)
Definition: zlib.c:862
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
Definition: encoding.c:764
#define ARG_FLUSH(val)
Definition: zlib.c:1443
static void gzfile_reader_end(struct gzfile *)
Definition: zlib.c:2878
#define RETURN_ENUMERATOR(obj, argc, argv)
#define GZFILE_FLAG_FOOTER_FINISHED
Definition: zlib.c:2213
#define rb_enc_left_char_head(s, p, e, enc)
static void * zstream_run_func(void *ptr)
Definition: zlib.c:966
static void zstream_discard_input(struct zstream *, long)
Definition: zlib.c:881
int rb_enc_mbclen(const char *p, const char *e, rb_encoding *enc)
Definition: encoding.c:884
static struct zstream_funcs deflate_funcs
Definition: zlib.c:567
#define MAX_UINT(n)
Definition: zlib.c:55
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:695
#define GZFILE_IS_FINISHED(gz)
Definition: zlib.c:2215
#define GZFILE_FLAG_HEADER_FINISHED
Definition: zlib.c:2212
static VALUE cBufError
Definition: zlib.c:303
static VALUE rb_zlib_version(VALUE)
Definition: zlib.c:368
static ID id_input
Definition: zlib.c:2182
static VALUE rb_gzreader_each_char(VALUE obj)
Definition: zlib.c:3854
#define ZSTREAM_IS_READY(z)
Definition: zlib.c:553
static VALUE gzfile_read_all(struct gzfile *)
Definition: zlib.c:2758
#define rb_str_new2
static VALUE cStreamEnd
Definition: zlib.c:302
static VALUE rb_inflate_s_inflate(VALUE, VALUE)
Definition: zlib.c:1919
#define ZSTREAM_FLAG_FINISHED
Definition: zlib.c:546
static void gzreader_skip_linebreaks(struct gzfile *)
Definition: zlib.c:3933
int state
Definition: tcltklib.c:1462
static VALUE rb_deflate_addstr(VALUE, VALUE)
Definition: zlib.c:1691
static VALUE cGzError
Definition: zlib.c:2183
#define ARG_WBITS(val)
Definition: zlib.c:1440
#define ZSTREAM_FLAG_IN_STREAM
Definition: zlib.c:545
#define ZSTREAM_IS_GZFILE(z)
Definition: zlib.c:556
static VALUE gzfile_new(VALUE, const struct zstream_funcs *, void(*) _((struct gzfile *)))
static void zstream_init(struct zstream *, const struct zstream_funcs *)
Definition: zlib.c:602
#define ZSTREAM_FLAG_CLOSING
Definition: zlib.c:547
static void gzfile_mark(struct gzfile *)
Definition: zlib.c:2222
#define ID2SYM(x)
static VALUE rb_gzwriter_flush(int, VALUE *, VALUE)
Definition: zlib.c:3509
VALUE VALUE args
Definition: tcltklib.c:2561
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2114
int jump_state
Definition: zlib.c:579
static VALUE rb_gzreader_rewind(VALUE)
Definition: zlib.c:3710
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1111
static VALUE rb_gzreader_readchar(VALUE)
Definition: zlib.c:3804
VALUE rb_str_to_str(VALUE)
Definition: string.c:849
static VALUE rb_gzfile_finish(VALUE)
Definition: zlib.c:3276
gz lineno
Definition: zlib.c:2268
static void zstream_buffer_ungets(struct zstream *, const Bytef *, unsigned long)
Definition: zlib.c:829
#define head
Definition: st.c:107
const char * name
Definition: ripper.y:163
VALUE input
Definition: zlib.c:535
static void gzfile_writer_end(struct gzfile *)
Definition: zlib.c:2856
static ID id_close
Definition: zlib.c:2182
#define rb_gzwriter_printf
Definition: zlib.c:3570
static VALUE rb_zstream_total_in(VALUE)
Definition: zlib.c:1371
#define ZSTREAM_FLAG_GZFILE
Definition: zlib.c:548
static VALUE cCRCError
Definition: zlib.c:2183
int level
Definition: zlib.c:2192
#define NORETURN(x)
Definition: ruby.h:31
VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, VALUE *argv)
Definition: enumerator.c:398
int rb_econv_prepare_opts(VALUE opthash, VALUE *ecopts)
Definition: transcode.c:2564
void rb_exc_raise(VALUE mesg)
Definition: eval.c:527
static ID id_seek
Definition: zlib.c:2182
int lineno
Definition: zlib.c:2198
static VALUE cLengthError
Definition: zlib.c:2183
#define gzfile_writer_new(gz)
Definition: zlib.c:2282
rb_encoding * rb_default_external_encoding(void)
Definition: encoding.c:1286
int(* end)(z_streamp)
Definition: zlib.c:539
static void gzfile_close(struct gzfile *, int)
Definition: zlib.c:2300
#define OS_ZSYSTEM
Definition: zlib.c:2172
static ID id_flush
Definition: zlib.c:2182
static VALUE rb_gzfile_path(VALUE)
Definition: zlib.c:3379
static long gzfile_fill(struct gzfile *gz, long len)
Definition: zlib.c:2683
unsigned int input
Definition: nkf.c:4311
#define FIXNUM_P(f)
return Qfalse
Definition: tcltklib.c:6779
static unsigned long gzfile_get32(const unsigned char *)
Definition: zlib.c:2404
static void gzfile_calc_crc(struct gzfile *, VALUE)
Definition: zlib.c:2652
static VALUE rb_zstream_adler(VALUE)
Definition: zlib.c:1400
static VALUE rb_deflate_s_deflate(int, VALUE *, VALUE)
Definition: zlib.c:1604
int rb_block_given_p(void)
Definition: eval.c:672
#define ZSTREAM_FLAG_READY
Definition: zlib.c:544
rb_econv_result_t rb_econv_convert(rb_econv_t *ec, const unsigned char **source_buffer_ptr, const unsigned char *source_buffer_end, unsigned char **destination_buffer_ptr, unsigned char *destination_buffer_end, int flags)
Definition: transcode.c:1446
static VALUE cVersionError
Definition: zlib.c:303
#define Qnil
Definition: tcltklib.c:1896
#define val
Definition: tcltklib.c:1949
VALUE rb_eRuntimeError
Definition: error.c:510
static VALUE rb_gzwriter_s_allocate(VALUE)
Definition: zlib.c:3436
static struct gzfile * get_gzfile(VALUE)
Definition: zlib.c:2918
#define checksum_long(func, sum, ptr, len)
Definition: zlib.c:392
#define VALGRIND_MAKE_MEM_DEFINED(p, n)
Definition: zlib.c:24
#define GZ_MAGIC1
Definition: zlib.c:2147
gz crc
Definition: zlib.c:2267
static VALUE rb_gzreader_gets(int, VALUE *, VALUE)
Definition: zlib.c:4122
#define GZ_MAGIC2
Definition: zlib.c:2148
static VALUE char * str
Definition: tcltklib.c:3547
static void gzfile_free(struct gzfile *)
Definition: zlib.c:2233
static VALUE gzfile_getc(struct gzfile *gz)
Definition: zlib.c:2780
static void * zstream_expand_buffer_protect(void *ptr)
Definition: zlib.c:691
static VALUE rb_gzreader_read(int, VALUE *, VALUE)
Definition: zlib.c:3737
VALUE rb_ary_new(void)
Definition: array.c:424
static void gzfile_make_footer(struct gzfile *)
Definition: zlib.c:2498
#define Check_Type(v, t)
#define dp(v)
Definition: vm_debug.h:23
int flags
Definition: tcltklib.c:3023
unsigned long ID
Definition: ripper.y:105
VALUE klass
Definition: zlib.c:2973
void rb_gc_mark(VALUE)
Definition: gc.c:2598
static int gzfile_read_raw_ensure(struct gzfile *, long)
Definition: zlib.c:2362
static void zstream_passthrough_input(struct zstream *)
Definition: zlib.c:900
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2197
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:1975
static void raise_zlib_error(int err, const char *msg)
Definition: zlib.c:306
static void zstream_expand_buffer(struct zstream *)
Definition: zlib.c:623
#define OS_VMS
Definition: zlib.c:2163
VALUE rb_eNoMethodError
Definition: error.c:519
static VALUE VALUE obj
Definition: tcltklib.c:3158
#define RSTRING_LEN(str)
#define FIX2INT(x)
#define INT2FIX(i)
static VALUE rb_inflate_addstr(VALUE, VALUE)
Definition: zlib.c:2048
#define ARG_LEVEL(val)
Definition: zlib.c:1439
#define GZ_EXTRAFLAG_FAST
Definition: zlib.c:2157
#define zstream_deflate_new(klass)
Definition: zlib.c:1174
static int rb_enc_dummy_p(rb_encoding *enc)
Definition: ripper.y:235
#define T_STRING
static VALUE gzfile_read_raw(struct gzfile *)
Definition: zlib.c:2354
#define MBCLEN_CHARFOUND_P(ret)
static VALUE rb_gzfile_crc(VALUE)
Definition: zlib.c:3081
static VALUE rb_gzreader_initialize(int, VALUE *, VALUE)
Definition: zlib.c:3676
#define OS_WIN32
Definition: zlib.c:2169
#define xmalloc
int(* run)(z_streamp, int)
Definition: zlib.c:540
static VALUE rb_zstream_reset(VALUE)
Definition: zlib.c:1269
#define DEF_MEM_LEVEL
Definition: zlib.c:42
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:273
static ID id_write
Definition: zlib.c:2182
#define OS_MACOS
Definition: zlib.c:2167
static VALUE gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
Definition: zlib.c:2715
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
int interrupt
Definition: zlib.c:578
int err
Definition: win32.c:87
static void gzfile_write_raw(struct gzfile *)
Definition: zlib.c:2314
static VALUE rb_gzfile_lineno(VALUE)
Definition: zlib.c:3159
static VALUE rb_zstream_flush_next_out(VALUE)
Definition: zlib.c:1319
#define GZ_FLAG_ENCRYPT
Definition: zlib.c:2154
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
static VALUE rb_zlib_crc_table(VALUE)
Definition: zlib.c:508
#define OS_CODE
Definition: zlib.c:2179
#define ZSTREAM_IS_FINISHED(z)
Definition: zlib.c:554
VALUE rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, VALUE ecopts)
#define ARG_STRATEGY(val)
Definition: zlib.c:1442
static ID id_read
Definition: zlib.c:2182
static VALUE rb_gzreader_bytes(VALUE obj)
Definition: zlib.c:3890
#define OS_ATARI
Definition: zlib.c:2165
#define ZSTREAM_READY(z)
Definition: zlib.c:552
VALUE rb_str_buf_cat(VALUE, const char *, long)
Definition: string.c:1940
VALUE rb_str_dup(VALUE)
Definition: string.c:946
gz level
Definition: zlib.c:2262
VALUE rb_obj_as_string(VALUE)
Definition: string.c:895
VALUE * argv
Definition: tcltklib.c:1971
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
#define rb_zlib_crc32_combine
Definition: zlib.c:499
VALUE rb_yield(VALUE)
Definition: vm_eval.c:934
static VALUE gzfile_writer_end_run(VALUE)
Definition: zlib.c:2840
static VALUE gzfile_error_inspect(VALUE)
Definition: zlib.c:2439
VALUE rb_str_resize(VALUE, long)
Definition: string.c:1846
memcpy(buf+1, str, len)
#define RTEST(v)
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1508
static VALUE rb_deflate_deflate(int, VALUE *, VALUE)
Definition: zlib.c:1669
int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **enc2_p, int *fmode_p)
Definition: io.c:4943
struct zstream z
Definition: zlib.c:2190
long ungetc
Definition: zlib.c:2199
#define OS_CPM
Definition: zlib.c:2173
VALUE rb_mEnumerable
Definition: enum.c:20
static VALUE rb_gzfile_sync(VALUE)
Definition: zlib.c:3319
#define StringValue(v)
void rb_econv_close(rb_econv_t *ec)
Definition: transcode.c:1702
static VALUE rb_gzfile_closed_p(VALUE)
Definition: zlib.c:3293
#define MBCLEN_CHARFOUND_LEN(ret)
int rb_enc_precise_mbclen(const char *p, const char *e, rb_encoding *enc)
Definition: encoding.c:896
#define const
Definition: strftime.c:102
register char * s
Definition: os2.c:56
static long gzreader_charboundary(struct gzfile *gz, long n)
Definition: zlib.c:3971
static VALUE gzreader_gets(int, VALUE *, VALUE)
Definition: zlib.c:3992
#define ZSTREAM_INITIAL_BUFSIZE
Definition: zlib.c:562
VP_EXPORT void
Definition: bigdecimal.c:5083
VALUE mode
Definition: tcltklib.c:1664
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1566
static VALUE gzfile_wrap(int argc, VALUE *argv, VALUE klass, int close_io_on_error)
Definition: zlib.c:2996
size_t length
Definition: tcltklib.c:4559
static VALUE gzfile_newstr(struct gzfile *gz, VALUE str)
Definition: zlib.c:2665
static VALUE rb_zstream_avail_in(VALUE)
Definition: zlib.c:1360
static VALUE gzfile_read(struct gzfile *, long)
Definition: zlib.c:2702
VALUE rb_exc_new2(VALUE etype, const char *s)
Definition: error.c:542
VALUE rb_str_inspect(VALUE)
Definition: string.c:4500
static VALUE rb_gzfile_set_orig_name(VALUE, VALUE)
Definition: zlib.c:3209
static void zlib_mem_free(voidpf, voidpf)
Definition: zlib.c:596
#define RB_GC_GUARD(v)
VALUE rb_file_open_str(VALUE, const char *)
Definition: io.c:5417
#define zstream_append_input2(z, v)
Definition: zlib.c:876
static VALUE rb_gzreader_s_open(int, VALUE *, VALUE)
Definition: zlib.c:3653
static VALUE zstream_new(VALUE, const struct zstream_funcs *)
Definition: zlib.c:1162
#define T_FIXNUM
int argc
Definition: tcltklib.c:1970
VALUE rb_str_buf_new(long)
Definition: string.c:777
struct gzfile * gz
Definition: zlib.c:2256
static struct zstream * get_zstream(VALUE)
Definition: zlib.c:1178
void rb_undef_alloc_func(VALUE)
Definition: vm_method.c:482
#define GZ_FLAG_MULTIPART
Definition: zlib.c:2150
#define rb_gzwriter_print
Definition: zlib.c:3575
static VALUE rb_gzfile_eof_p(VALUE)
Definition: zlib.c:3306
int(* reset)(z_streamp)
Definition: zlib.c:538
Definition: zlib.c:531
static VALUE rb_gzreader_each_byte(VALUE)
Definition: zlib.c:3872
VALUE rb_rescue2(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*r_proc)(ANYARGS), VALUE data2,...)
Definition: eval.c:701
struct zstream::zstream_funcs * func
static VALUE zstream_shift_buffer(struct zstream *, long)
Definition: zlib.c:804
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1117
#define RUBY_ZLIB_VERSION
Definition: zlib.c:28
rb_econv_t * rb_econv_open_opts(const char *source_encoding, const char *destination_encoding, int ecflags, VALUE ecopts)
Definition: transcode.c:2570
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
Definition: eval.c:804
int memcmp(const void *s1, const void *s2, size_t len)
Definition: memcmp.c:7
static voidpf zlib_mem_alloc(voidpf, uInt, uInt)
Definition: zlib.c:584
static VALUE rb_gzreader_readlines(int, VALUE *, VALUE)
Definition: zlib.c:4186
static VALUE rb_deflate_initialize(int, VALUE *, VALUE)
Definition: zlib.c:1524
VALUE rb_time_new(time_t, long)
Definition: time.c:2363
#define GZ_FLAG_EXTRA
Definition: zlib.c:2151
VALUE orig_name
Definition: zlib.c:2195
void rb_sys_fail(const char *mesg)
Definition: error.c:1899
static VALUE zstream_end(struct zstream *)
Definition: zlib.c:943
static struct zstream_funcs inflate_funcs
Definition: zlib.c:571
RUBY_EXTERN VALUE rb_cString
Definition: ripper.y:1456
Real * b
Definition: bigdecimal.c:1182
void rb_jump_tag(int tag)
Definition: eval.c:666
#define GZFILE_READ_SIZE
Definition: zlib.c:2218
return ptr
Definition: tcltklib.c:784
#define FIXNUMARG(val, ifnil)
Definition: zlib.c:1435
VpDivd * c
Definition: bigdecimal.c:1205
static void gzfile_reset(struct gzfile *)
Definition: zlib.c:2286
static VALUE rb_gzfile_total_in(VALUE)
Definition: zlib.c:3353
static VALUE rb_deflate_flush(int, VALUE *, VALUE)
Definition: zlib.c:1714
#define _(args)
Definition: dln.h:28
volatile VALUE msg
Definition: tcltklib.c:3100
#define rb_gzwriter_puts
Definition: zlib.c:3580
unsigned int uint32_t
Definition: sha2.h:101
static VALUE rb_gzwriter_write(VALUE, VALUE)
Definition: zlib.c:3533
static unsigned int gzfile_get16(const unsigned char *)
Definition: zlib.c:2395
#define OS_MSDOS
Definition: zlib.c:2161
#define OS_TOPS20
Definition: zlib.c:2168
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1123
void * ruby_xrealloc(void *ptr, size_t size)
Definition: gc.c:3633
static ID id_dictionaries
Definition: zlib.c:60
void rb_econv_check_error(rb_econv_t *ec)
Definition: transcode.c:4194
arg
Definition: ripper.y:1312
Definition: zlib.c:2189
VALUE rb_Integer(VALUE)
Definition: object.c:2469
int stream_output
Definition: zlib.c:580
VALUE src
Definition: tcltklib.c:7953
static VALUE rb_zlib_crc32(int, VALUE *, VALUE)
Definition: zlib.c:476
#define OS_QDOS
Definition: zlib.c:2174
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:770
static VALUE inflate_run(VALUE)
Definition: zlib.c:1885
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
Definition: string.c:563
static VALUE rb_gzfile_total_out(VALUE)
Definition: zlib.c:3364
int size
Definition: encoding.c:52
static VALUE cZError
Definition: zlib.c:302
#define NUM2LONG(x)
static VALUE do_checksum(int, VALUE *, uLong(*)(uLong, const Bytef *, uInt))
static void gzfile_make_header(struct gzfile *)
Definition: zlib.c:2454
static void gzfile_ungetbyte(struct gzfile *, int)
Definition: zlib.c:2833
#define ZSTREAM_AVAIL_OUT_STEP_MIN
Definition: zlib.c:565
static VALUE rb_inflate_initialize(int, VALUE *, VALUE)
Definition: zlib.c:1866
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:582
static VALUE cDataError
Definition: zlib.c:303
if(RB_TYPE_P(r, T_FLOAT))
Definition: bigdecimal.c:1186
void Init_zlib(void)
Definition: zlib.c:4199
static VALUE gzfile_ensure_close(VALUE)
Definition: zlib.c:2984
void rb_define_attr(VALUE klass, const char *name, int read, int write)
Defines (a) public accessor method(s) for an attribute.
Definition: class.c:1548
static VALUE rb_gzfile_set_lineno(VALUE, VALUE)
Definition: zlib.c:3170
static VALUE rb_zstream_flush_next_in(VALUE)
Definition: zlib.c:1304
static VALUE zstream_detach_buffer(struct zstream *)
Definition: zlib.c:768
struct zstream * z
Definition: zlib.c:576
static VALUE rb_gzreader_ungetc(VALUE, VALUE)
Definition: zlib.c:3904
static VALUE cStreamError
Definition: zlib.c:303
static VALUE rb_inflate_sync_point_p(VALUE)
Definition: zlib.c:2096
static void gzfile_raise(struct gzfile *gz, VALUE klass, const char *message)
Definition: zlib.c:2424
#define OS_VMCMS
Definition: zlib.c:2171
void * rb_thread_call_with_gvl(void *(*func)(void *), void *data1)
Definition: thread.c:1401
#define ARG_MEMLEVEL(val)
Definition: zlib.c:1441
#define ECONV_PARTIAL_INPUT
static VALUE zstream_sync(struct zstream *, Bytef *, long)
Definition: zlib.c:1097
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1426
#define ALLOC_N(type, n)
static VALUE gzfile_read_raw_rescue(VALUE)
Definition: zlib.c:2340
#define RBASIC(obj)
static void zstream_run(struct zstream *, Bytef *, long, int)
Definition: zlib.c:1030
static VALUE rb_gzwriter_s_open(int, VALUE *, VALUE)
Definition: zlib.c:3449
static void zstream_append_buffer(struct zstream *, const Bytef *, long)
Definition: zlib.c:735
klass
Definition: tcltklib.c:3504
#define gzfile_reader_new(gz)
Definition: zlib.c:2283
#define INT2NUM(x)
VALUE ecopts
Definition: zlib.c:2205
static void zstream_free(struct zstream *)
Definition: zlib.c:1153
VALUE * argv
Definition: zlib.c:2972
unsigned long flags
Definition: zlib.c:532
VALUE rb_uint2inum(VALUE n)
Definition: bignum.c:330
static VALUE rb_gzfile_orig_name(VALUE)
Definition: zlib.c:3126
#define Data_Get_Struct(obj, type, sval)
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1557
static ID id_path
Definition: zlib.c:2182
RUBY_EXTERN VALUE rb_rs
Definition: ripper.y:487
static void zstream_finalize(struct zstream *)
Definition: zlib.c:1143
static VALUE rb_inflate_add_dictionary(VALUE obj, VALUE dictionary)
Definition: zlib.c:1964
static VALUE rb_inflate_inflate(VALUE, VALUE)
Definition: zlib.c:2011
static VALUE rb_gzreader_lines(int argc, VALUE *argv, VALUE obj)
Definition: zlib.c:4172
gz io
Definition: zlib.c:2261
static VALUE rb_gzreader_s_allocate(VALUE)
Definition: zlib.c:3638
static VALUE rb_gzfile_set_sync(VALUE, VALUE)
Definition: zlib.c:3334
#define RSTRING_LENINT(str)
VALUE rb_ary_new2(long capa)
Definition: array.c:417
#define rb_gzwriter_addstr
Definition: zlib.c:3565
VALUE rb_str_new(const char *, long)
Definition: string.c:425
static VALUE cNeedDict
Definition: zlib.c:302
Real * res
Definition: bigdecimal.c:1233
static VALUE rb_gzreader_readpartial(int argc, VALUE *argv, VALUE obj)
Definition: zlib.c:3768
static VALUE rb_gzreader_readline(int, VALUE *, VALUE)
Definition: zlib.c:4138
#define GZ_EXTRAFLAG_SLOW
Definition: zlib.c:2158
static VALUE rb_gzfile_close(VALUE)
Definition: zlib.c:3258
#define NUM2INT(x)
VALUE rb_hash_new(void)
Definition: hash.c:234
char * cbuf
Definition: zlib.c:2206
int ecflags
Definition: zlib.c:2204
#define rb_errinfo()
Definition: tcltklib.c:89
static VALUE gzfile_s_open(int, VALUE *, VALUE, const char *)
Definition: zlib.c:3051
unsigned long sum
Definition: zlib.c:400
static VALUE rb_gzreader_each(int, VALUE *, VALUE)
Definition: zlib.c:4154
VALUE rb_io_close(VALUE)
Definition: io.c:4187
#define GZFILE_CBUF_CAPA
Definition: zlib.c:2209
static VALUE rb_zstream_data_type(VALUE)
Definition: zlib.c:1391
static VALUE rb_deflate_init_copy(VALUE, VALUE)
Definition: zlib.c:1550
VALUE rb_int2inum(SIGNED_VALUE n)
Definition: bignum.c:337
static void gzfile_write(struct gzfile *, Bytef *, long)
Definition: zlib.c:2615
BDIGIT e
Definition: bigdecimal.c:5085
#define ZSTREAM_EXPAND_BUFFER_OK
Definition: zlib.c:558
static VALUE rb_zstream_total_out(VALUE)
Definition: zlib.c:1380
VALUE rb_hash_aref(VALUE, VALUE)
Definition: hash.c:560
VALUE opts
Definition: tcltklib.c:6146
#define NUM2CHR(x)
unsigned long VALUE
Definition: ripper.y:104
rb_encoding * rb_ascii8bit_encoding(void)
Definition: encoding.c:1151
RUBY_EXTERN VALUE rb_eEOFError
Definition: ripper.y:1471
void rb_warning(const char *fmt,...)
Definition: error.c:229
#define GZ_METHOD_DEFLATE
Definition: zlib.c:2149
z_stream stream
Definition: zlib.c:536
#define GZ_FLAG_COMMENT
Definition: zlib.c:2153
rb_encoding * enc
Definition: zlib.c:2201
time_t mtime
Definition: zlib.c:2193
#define snprintf
#define zstream_init_deflate(z)
Definition: zlib.c:619
#define OBJ_TAINT(x)
VALUE rb_define_module(const char *name)
Definition: class.c:617
static void zstream_reset(struct zstream *)
Definition: zlib.c:926
static long gzfile_read_more(struct gzfile *)
Definition: zlib.c:2630
static VALUE rb_inflate_sync(VALUE, VALUE)
Definition: zlib.c:2079
#define GZ_FLAG_UNKNOWN_MASK
Definition: zlib.c:2155
#define rb_intern(str)
long buf_filled
Definition: zlib.c:534
static void rb_gzfile_ecopts(struct gzfile *gz, VALUE opts)
Definition: zlib.c:3387
static int zstream_expand_buffer_without_gvl(struct zstream *z)
Definition: zlib.c:702
static void gzfile_reader_rewind(struct gzfile *)
Definition: zlib.c:2887
VALUE buf
Definition: zlib.c:533
static VALUE rb_zstream_finish(VALUE)
Definition: zlib.c:1285
#define OS_UNIX
Definition: zlib.c:2164
#define zstream_append_buffer2(z, v)
Definition: zlib.c:764
#define NULL
Definition: _sdbm.c:103
VALUE time
Definition: tcltklib.c:1866
static void rscheck(const char *rsptr, long rslen, VALUE rs)
Definition: zlib.c:3964
VALUE rb_check_string_type(VALUE)
Definition: string.c:1508
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1340
#define rb_enc_mbmaxlen(enc)
#define ULONG2NUM(x)
static VALUE gzfile_reader_end_run(VALUE)
Definition: zlib.c:2865
char * dst
Definition: tcltklib.c:9868
static VALUE rb_gzfile_s_wrap(int, VALUE *, VALUE)
Definition: zlib.c:3040
void rb_warn(const char *fmt,...)
Definition: error.c:216
static VALUE deflate_run(VALUE)
Definition: zlib.c:1571
unsigned long crc
Definition: zlib.c:2197
VALUE rb_econv_str_convert(rb_econv_t *ec, VALUE src, int flags)
Definition: transcode.c:1869
static VALUE rb_deflate_set_dictionary(VALUE, VALUE)
Definition: zlib.c:1784
VALUE rb_eArgError
Definition: error.c:512
VALUE rb_check_convert_type(VALUE, int, const char *, const char *)
Definition: object.c:2364
#define zstream_inflate_new(klass)
Definition: zlib.c:1175
static VALUE rb_gzreader_getbyte(VALUE obj)
Definition: zlib.c:3820
static VALUE gzfile_read_raw_partial(VALUE)
Definition: zlib.c:2329
rb_encoding * enc2
Definition: zlib.c:2202
gz mtime
Definition: zlib.c:2263
static VALUE rb_zlib_adler32(int, VALUE *, VALUE)
Definition: zlib.c:438
size_t len
Definition: tcltklib.c:3568