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