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