Ruby 2.0.0p353(2013-11-22revision43784)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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