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