00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <ruby.h>
00010 #include <zlib.h>
00011 #include <time.h>
00012 #include <ruby/io.h>
00013
00014 #ifdef HAVE_VALGRIND_MEMCHECK_H
00015 # include <valgrind/memcheck.h>
00016 # ifndef VALGRIND_MAKE_MEM_DEFINED
00017 # define VALGRIND_MAKE_MEM_DEFINED(p, n) VALGRIND_MAKE_READABLE((p), (n))
00018 # endif
00019 # ifndef VALGRIND_MAKE_MEM_UNDEFINED
00020 # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) VALGRIND_MAKE_WRITABLE((p), (n))
00021 # endif
00022 #else
00023 # define VALGRIND_MAKE_MEM_DEFINED(p, n)
00024 # define VALGRIND_MAKE_MEM_UNDEFINED(p, n)
00025 #endif
00026
00027 #define RUBY_ZLIB_VERSION "0.6.0"
00028
00029
00030 #define OBJ_IS_FREED(val) (RBASIC(val)->flags == 0)
00031
00032 #ifndef GZIP_SUPPORT
00033 #define GZIP_SUPPORT 1
00034 #endif
00035
00036
00037 #ifndef DEF_MEM_LEVEL
00038 #if MAX_MEM_LEVEL >= 8
00039 #define DEF_MEM_LEVEL 8
00040 #else
00041 #define DEF_MEM_LEVEL MAX_MEM_LEVEL
00042 #endif
00043 #endif
00044
00045 #if SIZEOF_LONG > SIZEOF_INT
00046 static inline uInt
00047 max_uint(long n)
00048 {
00049 if (n > UINT_MAX) n = UINT_MAX;
00050 return (uInt)n;
00051 }
00052 #define MAX_UINT(n) max_uint(n)
00053 #else
00054 #define MAX_UINT(n) (uInt)(n)
00055 #endif
00056
00057 #define sizeof(x) ((int)sizeof(x))
00058
00059
00060
00061 static NORETURN(void raise_zlib_error(int, const char*));
00062 static VALUE rb_zlib_version(VALUE);
00063 static VALUE do_checksum(int, VALUE*, uLong (*)(uLong, const Bytef*, uInt));
00064 static VALUE rb_zlib_adler32(int, VALUE*, VALUE);
00065 static VALUE rb_zlib_crc32(int, VALUE*, VALUE);
00066 static VALUE rb_zlib_crc_table(VALUE);
00067 static voidpf zlib_mem_alloc(voidpf, uInt, uInt);
00068 static void zlib_mem_free(voidpf, voidpf);
00069 static void finalizer_warn(const char*);
00070
00071 struct zstream;
00072 struct zstream_funcs;
00073 static void zstream_init(struct zstream*, const struct zstream_funcs*);
00074 static void zstream_expand_buffer(struct zstream*);
00075 static void zstream_expand_buffer_into(struct zstream*, unsigned long);
00076 static void zstream_append_buffer(struct zstream*, const Bytef*, long);
00077 static VALUE zstream_detach_buffer(struct zstream*);
00078 static VALUE zstream_shift_buffer(struct zstream*, long);
00079 static void zstream_buffer_ungets(struct zstream*, const Bytef*, unsigned long);
00080 static void zstream_buffer_ungetbyte(struct zstream*, int);
00081 static void zstream_append_input(struct zstream*, const Bytef*, long);
00082 static void zstream_discard_input(struct zstream*, long);
00083 static void zstream_reset_input(struct zstream*);
00084 static void zstream_passthrough_input(struct zstream*);
00085 static VALUE zstream_detach_input(struct zstream*);
00086 static void zstream_reset(struct zstream*);
00087 static VALUE zstream_end(struct zstream*);
00088 static void zstream_run(struct zstream*, Bytef*, long, int);
00089 static VALUE zstream_sync(struct zstream*, Bytef*, long);
00090 static void zstream_mark(struct zstream*);
00091 static void zstream_free(struct zstream*);
00092 static VALUE zstream_new(VALUE, const struct zstream_funcs*);
00093 static struct zstream *get_zstream(VALUE);
00094 static void zstream_finalize(struct zstream*);
00095
00096 static VALUE rb_zstream_end(VALUE);
00097 static VALUE rb_zstream_reset(VALUE);
00098 static VALUE rb_zstream_finish(VALUE);
00099 static VALUE rb_zstream_flush_next_in(VALUE);
00100 static VALUE rb_zstream_flush_next_out(VALUE);
00101 static VALUE rb_zstream_avail_out(VALUE);
00102 static VALUE rb_zstream_set_avail_out(VALUE, VALUE);
00103 static VALUE rb_zstream_avail_in(VALUE);
00104 static VALUE rb_zstream_total_in(VALUE);
00105 static VALUE rb_zstream_total_out(VALUE);
00106 static VALUE rb_zstream_data_type(VALUE);
00107 static VALUE rb_zstream_adler(VALUE);
00108 static VALUE rb_zstream_finished_p(VALUE);
00109 static VALUE rb_zstream_closed_p(VALUE);
00110
00111 static VALUE rb_deflate_s_allocate(VALUE);
00112 static VALUE rb_deflate_initialize(int, VALUE*, VALUE);
00113 static VALUE rb_deflate_init_copy(VALUE, VALUE);
00114 static VALUE deflate_run(VALUE);
00115 static VALUE rb_deflate_s_deflate(int, VALUE*, VALUE);
00116 static void do_deflate(struct zstream*, VALUE, int);
00117 static VALUE rb_deflate_deflate(int, VALUE*, VALUE);
00118 static VALUE rb_deflate_addstr(VALUE, VALUE);
00119 static VALUE rb_deflate_flush(int, VALUE*, VALUE);
00120 static VALUE rb_deflate_params(VALUE, VALUE, VALUE);
00121 static VALUE rb_deflate_set_dictionary(VALUE, VALUE);
00122
00123 static VALUE inflate_run(VALUE);
00124 static VALUE rb_inflate_s_allocate(VALUE);
00125 static VALUE rb_inflate_initialize(int, VALUE*, VALUE);
00126 static VALUE rb_inflate_s_inflate(VALUE, VALUE);
00127 static void do_inflate(struct zstream*, VALUE);
00128 static VALUE rb_inflate_inflate(VALUE, VALUE);
00129 static VALUE rb_inflate_addstr(VALUE, VALUE);
00130 static VALUE rb_inflate_sync(VALUE, VALUE);
00131 static VALUE rb_inflate_sync_point_p(VALUE);
00132 static VALUE rb_inflate_set_dictionary(VALUE, VALUE);
00133
00134 #if GZIP_SUPPORT
00135 struct gzfile;
00136 static void gzfile_mark(struct gzfile*);
00137 static void gzfile_free(struct gzfile*);
00138 static VALUE gzfile_new(VALUE, const struct zstream_funcs*, void (*) _((struct gzfile*)));
00139 static void gzfile_reset(struct gzfile*);
00140 static void gzfile_close(struct gzfile*, int);
00141 static void gzfile_write_raw(struct gzfile*);
00142 static VALUE gzfile_read_raw_partial(VALUE);
00143 static VALUE gzfile_read_raw_rescue(VALUE);
00144 static VALUE gzfile_read_raw(struct gzfile*);
00145 static int gzfile_read_raw_ensure(struct gzfile*, long);
00146 static char *gzfile_read_raw_until_zero(struct gzfile*, long);
00147 static unsigned int gzfile_get16(const unsigned char*);
00148 static unsigned long gzfile_get32(const unsigned char*);
00149 static void gzfile_set32(unsigned long n, unsigned char*);
00150 static void gzfile_make_header(struct gzfile*);
00151 static void gzfile_make_footer(struct gzfile*);
00152 static void gzfile_read_header(struct gzfile*);
00153 static void gzfile_check_footer(struct gzfile*);
00154 static void gzfile_write(struct gzfile*, Bytef*, long);
00155 static long gzfile_read_more(struct gzfile*);
00156 static void gzfile_calc_crc(struct gzfile*, VALUE);
00157 static VALUE gzfile_read(struct gzfile*, long);
00158 static VALUE gzfile_read_all(struct gzfile*);
00159 static void gzfile_ungets(struct gzfile*, const Bytef*, long);
00160 static void gzfile_ungetbyte(struct gzfile*, int);
00161 static VALUE gzfile_writer_end_run(VALUE);
00162 static void gzfile_writer_end(struct gzfile*);
00163 static VALUE gzfile_reader_end_run(VALUE);
00164 static void gzfile_reader_end(struct gzfile*);
00165 static void gzfile_reader_rewind(struct gzfile*);
00166 static VALUE gzfile_reader_get_unused(struct gzfile*);
00167 static struct gzfile *get_gzfile(VALUE);
00168 static VALUE gzfile_ensure_close(VALUE);
00169 static VALUE rb_gzfile_s_wrap(int, VALUE*, VALUE);
00170 static VALUE gzfile_s_open(int, VALUE*, VALUE, const char*);
00171 NORETURN(static void gzfile_raise(struct gzfile *, VALUE, const char *));
00172 static VALUE gzfile_error_inspect(VALUE);
00173
00174 static VALUE rb_gzfile_to_io(VALUE);
00175 static VALUE rb_gzfile_crc(VALUE);
00176 static VALUE rb_gzfile_mtime(VALUE);
00177 static VALUE rb_gzfile_level(VALUE);
00178 static VALUE rb_gzfile_os_code(VALUE);
00179 static VALUE rb_gzfile_orig_name(VALUE);
00180 static VALUE rb_gzfile_comment(VALUE);
00181 static VALUE rb_gzfile_lineno(VALUE);
00182 static VALUE rb_gzfile_set_lineno(VALUE, VALUE);
00183 static VALUE rb_gzfile_set_mtime(VALUE, VALUE);
00184 static VALUE rb_gzfile_set_orig_name(VALUE, VALUE);
00185 static VALUE rb_gzfile_set_comment(VALUE, VALUE);
00186 static VALUE rb_gzfile_close(VALUE);
00187 static VALUE rb_gzfile_finish(VALUE);
00188 static VALUE rb_gzfile_closed_p(VALUE);
00189 static VALUE rb_gzfile_eof_p(VALUE);
00190 static VALUE rb_gzfile_sync(VALUE);
00191 static VALUE rb_gzfile_set_sync(VALUE, VALUE);
00192 static VALUE rb_gzfile_total_in(VALUE);
00193 static VALUE rb_gzfile_total_out(VALUE);
00194 static VALUE rb_gzfile_path(VALUE);
00195
00196 static VALUE rb_gzwriter_s_allocate(VALUE);
00197 static VALUE rb_gzwriter_s_open(int, VALUE*, VALUE);
00198 static VALUE rb_gzwriter_initialize(int, VALUE*, VALUE);
00199 static VALUE rb_gzwriter_flush(int, VALUE*, VALUE);
00200 static VALUE rb_gzwriter_write(VALUE, VALUE);
00201 static VALUE rb_gzwriter_putc(VALUE, VALUE);
00202
00203 static VALUE rb_gzreader_s_allocate(VALUE);
00204 static VALUE rb_gzreader_s_open(int, VALUE*, VALUE);
00205 static VALUE rb_gzreader_initialize(int, VALUE*, VALUE);
00206 static VALUE rb_gzreader_rewind(VALUE);
00207 static VALUE rb_gzreader_unused(VALUE);
00208 static VALUE rb_gzreader_read(int, VALUE*, VALUE);
00209 static VALUE rb_gzreader_getc(VALUE);
00210 static VALUE rb_gzreader_readchar(VALUE);
00211 static VALUE rb_gzreader_each_byte(VALUE);
00212 static VALUE rb_gzreader_ungetc(VALUE, VALUE);
00213 static VALUE rb_gzreader_ungetbyte(VALUE, VALUE);
00214 static void gzreader_skip_linebreaks(struct gzfile*);
00215 static VALUE gzreader_gets(int, VALUE*, VALUE);
00216 static VALUE rb_gzreader_gets(int, VALUE*, VALUE);
00217 static VALUE rb_gzreader_readline(int, VALUE*, VALUE);
00218 static VALUE rb_gzreader_each(int, VALUE*, VALUE);
00219 static VALUE rb_gzreader_readlines(int, VALUE*, VALUE);
00220 #endif
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 void Init_zlib(void);
00256
00257
00258
00259 static VALUE cZError, cStreamEnd, cNeedDict;
00260 static VALUE cStreamError, cDataError, cMemError, cBufError, cVersionError;
00261
00262 static void
00263 raise_zlib_error(int err, const char *msg)
00264 {
00265 VALUE exc;
00266
00267 if (!msg) {
00268 msg = zError(err);
00269 }
00270
00271 switch(err) {
00272 case Z_STREAM_END:
00273 exc = rb_exc_new2(cStreamEnd, msg);
00274 break;
00275 case Z_NEED_DICT:
00276 exc = rb_exc_new2(cNeedDict, msg);
00277 break;
00278 case Z_STREAM_ERROR:
00279 exc = rb_exc_new2(cStreamError, msg);
00280 break;
00281 case Z_DATA_ERROR:
00282 exc = rb_exc_new2(cDataError, msg);
00283 break;
00284 case Z_BUF_ERROR:
00285 exc = rb_exc_new2(cBufError, msg);
00286 break;
00287 case Z_VERSION_ERROR:
00288 exc = rb_exc_new2(cVersionError, msg);
00289 break;
00290 case Z_MEM_ERROR:
00291 exc = rb_exc_new2(cMemError, msg);
00292 break;
00293 case Z_ERRNO:
00294 rb_sys_fail(msg);
00295
00296 default:
00297 {
00298 char buf[BUFSIZ];
00299 snprintf(buf, BUFSIZ, "unknown zlib error %d: %s", err, msg);
00300 exc = rb_exc_new2(cZError, buf);
00301 }
00302 }
00303
00304 rb_exc_raise(exc);
00305 }
00306
00307
00308
00309
00310 static void
00311 finalizer_warn(const char *msg)
00312 {
00313 fprintf(stderr, "zlib(finalizer): %s\n", msg);
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 static VALUE
00325 rb_zlib_version(VALUE klass)
00326 {
00327 VALUE str;
00328
00329 str = rb_str_new2(zlibVersion());
00330 OBJ_TAINT(str);
00331 return str;
00332 }
00333
00334 #if SIZEOF_LONG > SIZEOF_INT
00335 static uLong
00336 checksum_long(uLong (*func)(uLong, const Bytef*, uInt), uLong sum, const Bytef *ptr, long len)
00337 {
00338 if (len > UINT_MAX) {
00339 do {
00340 sum = func(sum, ptr, UINT_MAX);
00341 ptr += UINT_MAX;
00342 len -= UINT_MAX;
00343 } while (len >= UINT_MAX);
00344 }
00345 if (len > 0) sum = func(sum, ptr, (uInt)len);
00346 return sum;
00347 }
00348 #else
00349 #define checksum_long(func, sum, ptr, len) (func)((sum), (ptr), (len))
00350 #endif
00351
00352 static VALUE
00353 do_checksum(argc, argv, func)
00354 int argc;
00355 VALUE *argv;
00356 uLong (*func)(uLong, const Bytef*, uInt);
00357 {
00358 VALUE str, vsum;
00359 unsigned long sum;
00360
00361 rb_scan_args(argc, argv, "02", &str, &vsum);
00362
00363 if (!NIL_P(vsum)) {
00364 sum = NUM2ULONG(vsum);
00365 }
00366 else if (NIL_P(str)) {
00367 sum = 0;
00368 }
00369 else {
00370 sum = func(0, Z_NULL, 0);
00371 }
00372
00373 if (NIL_P(str)) {
00374 sum = func(sum, Z_NULL, 0);
00375 }
00376 else {
00377 StringValue(str);
00378 sum = checksum_long(func, sum, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
00379 }
00380 return rb_uint2inum(sum);
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 static VALUE
00395 rb_zlib_adler32(int argc, VALUE *argv, VALUE klass)
00396 {
00397 return do_checksum(argc, argv, adler32);
00398 }
00399
00400 #ifdef HAVE_ADLER32_COMBINE
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 static VALUE
00412 rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2)
00413 {
00414 return ULONG2NUM(
00415 adler32_combine(NUM2ULONG(adler1), NUM2ULONG(adler2), NUM2LONG(len2)));
00416 }
00417 #else
00418 #define rb_zlib_adler32_combine rb_f_notimplement
00419 #endif
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 static VALUE
00433 rb_zlib_crc32(int argc, VALUE *argv, VALUE klass)
00434 {
00435 return do_checksum(argc, argv, crc32);
00436 }
00437
00438 #ifdef HAVE_CRC32_COMBINE
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 static VALUE
00450 rb_zlib_crc32_combine(VALUE klass, VALUE crc1, VALUE crc2, VALUE len2)
00451 {
00452 return ULONG2NUM(
00453 crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2)));
00454 }
00455 #else
00456 #define rb_zlib_crc32_combine rb_f_notimplement
00457 #endif
00458
00459
00460
00461
00462
00463
00464 static VALUE
00465 rb_zlib_crc_table(VALUE obj)
00466 {
00467 #if !defined(HAVE_TYPE_Z_CRC_T)
00468
00469 typedef unsigned long z_crc_t;
00470 #endif
00471 const z_crc_t *crctbl;
00472 VALUE dst;
00473 int i;
00474
00475 crctbl = get_crc_table();
00476 dst = rb_ary_new2(256);
00477
00478 for (i = 0; i < 256; i++) {
00479 rb_ary_push(dst, rb_uint2inum(crctbl[i]));
00480 }
00481 return dst;
00482 }
00483
00484
00485
00486
00487
00488 struct zstream {
00489 unsigned long flags;
00490 VALUE buf;
00491 long buf_filled;
00492 VALUE input;
00493 z_stream stream;
00494 const struct zstream_funcs {
00495 int (*reset)(z_streamp);
00496 int (*end)(z_streamp);
00497 int (*run)(z_streamp, int);
00498 } *func;
00499 };
00500
00501 #define ZSTREAM_FLAG_READY 0x1
00502 #define ZSTREAM_FLAG_IN_STREAM 0x2
00503 #define ZSTREAM_FLAG_FINISHED 0x4
00504 #define ZSTREAM_FLAG_CLOSING 0x8
00505 #define ZSTREAM_FLAG_UNUSED 0x10
00506
00507 #define ZSTREAM_READY(z) ((z)->flags |= ZSTREAM_FLAG_READY)
00508 #define ZSTREAM_IS_READY(z) ((z)->flags & ZSTREAM_FLAG_READY)
00509 #define ZSTREAM_IS_FINISHED(z) ((z)->flags & ZSTREAM_FLAG_FINISHED)
00510 #define ZSTREAM_IS_CLOSING(z) ((z)->flags & ZSTREAM_FLAG_CLOSING)
00511
00512
00513
00514 #define ZSTREAM_INITIAL_BUFSIZE 1024
00515 #define ZSTREAM_AVAIL_OUT_STEP_MAX 16384
00516 #define ZSTREAM_AVAIL_OUT_STEP_MIN 2048
00517
00518 static const struct zstream_funcs deflate_funcs = {
00519 deflateReset, deflateEnd, deflate,
00520 };
00521
00522 static const struct zstream_funcs inflate_funcs = {
00523 inflateReset, inflateEnd, inflate,
00524 };
00525
00526
00527 static voidpf
00528 zlib_mem_alloc(voidpf opaque, uInt items, uInt size)
00529 {
00530 voidpf p = xmalloc(items * size);
00531
00532
00533
00534
00535 VALGRIND_MAKE_MEM_DEFINED(p, items * size);
00536 return p;
00537 }
00538
00539 static void
00540 zlib_mem_free(voidpf opaque, voidpf address)
00541 {
00542 xfree(address);
00543 }
00544
00545 static void
00546 zstream_init(struct zstream *z, const struct zstream_funcs *func)
00547 {
00548 z->flags = 0;
00549 z->buf = Qnil;
00550 z->buf_filled = 0;
00551 z->input = Qnil;
00552 z->stream.zalloc = zlib_mem_alloc;
00553 z->stream.zfree = zlib_mem_free;
00554 z->stream.opaque = Z_NULL;
00555 z->stream.msg = Z_NULL;
00556 z->stream.next_in = Z_NULL;
00557 z->stream.avail_in = 0;
00558 z->stream.next_out = Z_NULL;
00559 z->stream.avail_out = 0;
00560 z->func = func;
00561 }
00562
00563 #define zstream_init_deflate(z) zstream_init((z), &deflate_funcs)
00564 #define zstream_init_inflate(z) zstream_init((z), &inflate_funcs)
00565
00566 static void
00567 zstream_expand_buffer(struct zstream *z)
00568 {
00569 long inc;
00570
00571 if (NIL_P(z->buf)) {
00572
00573
00574 z->buf = rb_str_new(0, ZSTREAM_INITIAL_BUFSIZE);
00575 z->buf_filled = 0;
00576 z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
00577 z->stream.avail_out = ZSTREAM_INITIAL_BUFSIZE;
00578 RBASIC(z->buf)->klass = 0;
00579 return;
00580 }
00581
00582 if (RSTRING_LEN(z->buf) - z->buf_filled >= ZSTREAM_AVAIL_OUT_STEP_MAX) {
00583
00584 z->stream.avail_out = ZSTREAM_AVAIL_OUT_STEP_MAX;
00585 }
00586 else {
00587 inc = z->buf_filled / 2;
00588 if (inc < ZSTREAM_AVAIL_OUT_STEP_MIN) {
00589 inc = ZSTREAM_AVAIL_OUT_STEP_MIN;
00590 }
00591 rb_str_resize(z->buf, z->buf_filled + inc);
00592 z->stream.avail_out = (inc < ZSTREAM_AVAIL_OUT_STEP_MAX) ?
00593 (int)inc : ZSTREAM_AVAIL_OUT_STEP_MAX;
00594 }
00595 z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
00596 }
00597
00598 static void
00599 zstream_expand_buffer_into(struct zstream *z, unsigned long size)
00600 {
00601 if (NIL_P(z->buf)) {
00602
00603
00604 z->buf = rb_str_new(0, size);
00605 z->buf_filled = 0;
00606 z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
00607 z->stream.avail_out = MAX_UINT(size);
00608 RBASIC(z->buf)->klass = 0;
00609 }
00610 else if (z->stream.avail_out != size) {
00611 rb_str_resize(z->buf, z->buf_filled + size);
00612 z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
00613 z->stream.avail_out = MAX_UINT(size);
00614 }
00615 }
00616
00617 static void
00618 zstream_append_buffer(struct zstream *z, const Bytef *src, long len)
00619 {
00620 if (NIL_P(z->buf)) {
00621 z->buf = rb_str_buf_new(len);
00622 rb_str_buf_cat(z->buf, (const char*)src, len);
00623 z->buf_filled = len;
00624 z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
00625 z->stream.avail_out = 0;
00626 RBASIC(z->buf)->klass = 0;
00627 return;
00628 }
00629
00630 if (RSTRING_LEN(z->buf) < z->buf_filled + len) {
00631 rb_str_resize(z->buf, z->buf_filled + len);
00632 z->stream.avail_out = 0;
00633 }
00634 else {
00635 if (z->stream.avail_out >= (uInt)len) {
00636 z->stream.avail_out -= (uInt)len;
00637 }
00638 else {
00639 z->stream.avail_out = 0;
00640 }
00641 }
00642 memcpy(RSTRING_PTR(z->buf) + z->buf_filled, src, len);
00643 z->buf_filled += len;
00644 z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
00645 }
00646
00647 #define zstream_append_buffer2(z,v) \
00648 zstream_append_buffer((z),(Bytef*)RSTRING_PTR(v),RSTRING_LEN(v))
00649
00650 static VALUE
00651 zstream_detach_buffer(struct zstream *z)
00652 {
00653 VALUE dst;
00654
00655 if (NIL_P(z->buf)) {
00656 dst = rb_str_new(0, 0);
00657 }
00658 else {
00659 dst = z->buf;
00660 rb_str_resize(dst, z->buf_filled);
00661 RBASIC(dst)->klass = rb_cString;
00662 }
00663
00664 z->buf = Qnil;
00665 z->buf_filled = 0;
00666 z->stream.next_out = 0;
00667 z->stream.avail_out = 0;
00668 return dst;
00669 }
00670
00671 static VALUE
00672 zstream_shift_buffer(struct zstream *z, long len)
00673 {
00674 VALUE dst;
00675 long buflen;
00676
00677 if (z->buf_filled <= len) {
00678 return zstream_detach_buffer(z);
00679 }
00680
00681 dst = rb_str_subseq(z->buf, 0, len);
00682 RBASIC(dst)->klass = rb_cString;
00683 z->buf_filled -= len;
00684 memmove(RSTRING_PTR(z->buf), RSTRING_PTR(z->buf) + len,
00685 z->buf_filled);
00686 z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf) + z->buf_filled;
00687 buflen = RSTRING_LEN(z->buf) - z->buf_filled;
00688 if (buflen > ZSTREAM_AVAIL_OUT_STEP_MAX) {
00689 buflen = ZSTREAM_AVAIL_OUT_STEP_MAX;
00690 }
00691 z->stream.avail_out = (uInt)buflen;
00692
00693 return dst;
00694 }
00695
00696 static void
00697 zstream_buffer_ungets(struct zstream *z, const Bytef *b, unsigned long len)
00698 {
00699 if (NIL_P(z->buf) || RSTRING_LEN(z->buf) - z->buf_filled == 0) {
00700 zstream_expand_buffer_into(z, len);
00701 }
00702
00703 memmove(RSTRING_PTR(z->buf) + len, RSTRING_PTR(z->buf), z->buf_filled);
00704 memmove(RSTRING_PTR(z->buf), b, len);
00705 z->buf_filled+=len;
00706 if (z->stream.avail_out > 0) {
00707 if (len > z->stream.avail_out) len = z->stream.avail_out;
00708 z->stream.next_out+=len;
00709 z->stream.avail_out-=(uInt)len;
00710 }
00711 }
00712
00713 static void
00714 zstream_buffer_ungetbyte(struct zstream *z, int c)
00715 {
00716 if (NIL_P(z->buf) || RSTRING_LEN(z->buf) - z->buf_filled == 0) {
00717 zstream_expand_buffer(z);
00718 }
00719
00720 memmove(RSTRING_PTR(z->buf) + 1, RSTRING_PTR(z->buf), z->buf_filled);
00721 RSTRING_PTR(z->buf)[0] = (char)c;
00722 z->buf_filled++;
00723 if (z->stream.avail_out > 0) {
00724 z->stream.next_out++;
00725 z->stream.avail_out--;
00726 }
00727 }
00728
00729 static void
00730 zstream_append_input(struct zstream *z, const Bytef *src, long len)
00731 {
00732 if (len <= 0) return;
00733
00734 if (NIL_P(z->input)) {
00735 z->input = rb_str_buf_new(len);
00736 rb_str_buf_cat(z->input, (const char*)src, len);
00737 RBASIC(z->input)->klass = 0;
00738 }
00739 else {
00740 rb_str_buf_cat(z->input, (const char*)src, len);
00741 }
00742 }
00743
00744 #define zstream_append_input2(z,v)\
00745 RB_GC_GUARD(v),\
00746 zstream_append_input((z), (Bytef*)RSTRING_PTR(v), RSTRING_LEN(v))
00747
00748 static void
00749 zstream_discard_input(struct zstream *z, long len)
00750 {
00751 if (NIL_P(z->input) || RSTRING_LEN(z->input) <= len) {
00752 z->input = Qnil;
00753 }
00754 else {
00755 memmove(RSTRING_PTR(z->input), RSTRING_PTR(z->input) + len,
00756 RSTRING_LEN(z->input) - len);
00757 rb_str_resize(z->input, RSTRING_LEN(z->input) - len);
00758 }
00759 }
00760
00761 static void
00762 zstream_reset_input(struct zstream *z)
00763 {
00764 z->input = Qnil;
00765 }
00766
00767 static void
00768 zstream_passthrough_input(struct zstream *z)
00769 {
00770 if (!NIL_P(z->input)) {
00771 zstream_append_buffer2(z, z->input);
00772 z->input = Qnil;
00773 }
00774 }
00775
00776 static VALUE
00777 zstream_detach_input(struct zstream *z)
00778 {
00779 VALUE dst;
00780
00781 if (NIL_P(z->input)) {
00782 dst = rb_str_new(0, 0);
00783 }
00784 else {
00785 dst = z->input;
00786 RBASIC(dst)->klass = rb_cString;
00787 }
00788 z->input = Qnil;
00789 RBASIC(dst)->klass = rb_cString;
00790 return dst;
00791 }
00792
00793 static void
00794 zstream_reset(struct zstream *z)
00795 {
00796 int err;
00797
00798 err = z->func->reset(&z->stream);
00799 if (err != Z_OK) {
00800 raise_zlib_error(err, z->stream.msg);
00801 }
00802 z->flags = ZSTREAM_FLAG_READY;
00803 z->buf = Qnil;
00804 z->buf_filled = 0;
00805 z->stream.next_out = 0;
00806 z->stream.avail_out = 0;
00807 zstream_reset_input(z);
00808 }
00809
00810 static VALUE
00811 zstream_end(struct zstream *z)
00812 {
00813 int err;
00814
00815 if (!ZSTREAM_IS_READY(z)) {
00816 rb_warning("attempt to close uninitialized zstream; ignored.");
00817 return Qnil;
00818 }
00819 if (z->flags & ZSTREAM_FLAG_IN_STREAM) {
00820 rb_warning("attempt to close unfinished zstream; reset forced.");
00821 zstream_reset(z);
00822 }
00823
00824 zstream_reset_input(z);
00825 err = z->func->end(&z->stream);
00826 if (err != Z_OK) {
00827 raise_zlib_error(err, z->stream.msg);
00828 }
00829 z->flags = 0;
00830 return Qnil;
00831 }
00832
00833 static void
00834 zstream_run(struct zstream *z, Bytef *src, long len, int flush)
00835 {
00836 uInt n;
00837 int err;
00838 volatile VALUE guard = Qnil;
00839
00840 if (NIL_P(z->input) && len == 0) {
00841 z->stream.next_in = (Bytef*)"";
00842 z->stream.avail_in = 0;
00843 }
00844 else {
00845 zstream_append_input(z, src, len);
00846 z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
00847 z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input));
00848
00849
00850
00851 guard = z->input;
00852 }
00853
00854 if (z->stream.avail_out == 0) {
00855 zstream_expand_buffer(z);
00856 }
00857
00858 for (;;) {
00859
00860
00861 RB_GC_GUARD(guard);
00862 n = z->stream.avail_out;
00863 err = z->func->run(&z->stream, flush);
00864 z->buf_filled += n - z->stream.avail_out;
00865 rb_thread_schedule();
00866
00867 if (err == Z_STREAM_END) {
00868 z->flags &= ~ZSTREAM_FLAG_IN_STREAM;
00869 z->flags |= ZSTREAM_FLAG_FINISHED;
00870 break;
00871 }
00872 if (err != Z_OK) {
00873 if (flush != Z_FINISH && err == Z_BUF_ERROR
00874 && z->stream.avail_out > 0) {
00875 z->flags |= ZSTREAM_FLAG_IN_STREAM;
00876 break;
00877 }
00878 zstream_reset_input(z);
00879 if (z->stream.avail_in > 0) {
00880 zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
00881 }
00882 raise_zlib_error(err, z->stream.msg);
00883 }
00884 if (z->stream.avail_out > 0) {
00885 z->flags |= ZSTREAM_FLAG_IN_STREAM;
00886 break;
00887 }
00888 zstream_expand_buffer(z);
00889 }
00890
00891 zstream_reset_input(z);
00892 if (z->stream.avail_in > 0) {
00893 zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
00894 guard = Qnil;
00895 }
00896 }
00897
00898 static VALUE
00899 zstream_sync(struct zstream *z, Bytef *src, long len)
00900 {
00901 VALUE rest;
00902 int err;
00903
00904 if (!NIL_P(z->input)) {
00905 z->stream.next_in = (Bytef*)RSTRING_PTR(z->input);
00906 z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input));
00907 err = inflateSync(&z->stream);
00908 if (err == Z_OK) {
00909 zstream_discard_input(z,
00910 RSTRING_LEN(z->input) - z->stream.avail_in);
00911 zstream_append_input(z, src, len);
00912 return Qtrue;
00913 }
00914 zstream_reset_input(z);
00915 if (err != Z_DATA_ERROR) {
00916 rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in);
00917 raise_zlib_error(err, z->stream.msg);
00918 }
00919 }
00920
00921 if (len <= 0) return Qfalse;
00922
00923 z->stream.next_in = src;
00924 z->stream.avail_in = MAX_UINT(len);
00925 err = inflateSync(&z->stream);
00926 if (err == Z_OK) {
00927 zstream_append_input(z, z->stream.next_in, z->stream.avail_in);
00928 return Qtrue;
00929 }
00930 if (err != Z_DATA_ERROR) {
00931 rest = rb_str_new((char*)z->stream.next_in, z->stream.avail_in);
00932 raise_zlib_error(err, z->stream.msg);
00933 }
00934 return Qfalse;
00935 }
00936
00937 static void
00938 zstream_mark(struct zstream *z)
00939 {
00940 rb_gc_mark(z->buf);
00941 rb_gc_mark(z->input);
00942 }
00943
00944 static void
00945 zstream_finalize(struct zstream *z)
00946 {
00947 int err = z->func->end(&z->stream);
00948 if (err == Z_STREAM_ERROR)
00949 finalizer_warn("the stream state was inconsistent.");
00950 if (err == Z_DATA_ERROR)
00951 finalizer_warn("the stream was freed prematurely.");
00952 }
00953
00954 static void
00955 zstream_free(struct zstream *z)
00956 {
00957 if (ZSTREAM_IS_READY(z)) {
00958 zstream_finalize(z);
00959 }
00960 xfree(z);
00961 }
00962
00963 static VALUE
00964 zstream_new(VALUE klass, const struct zstream_funcs *funcs)
00965 {
00966 VALUE obj;
00967 struct zstream *z;
00968
00969 obj = Data_Make_Struct(klass, struct zstream,
00970 zstream_mark, zstream_free, z);
00971 zstream_init(z, funcs);
00972 return obj;
00973 }
00974
00975 #define zstream_deflate_new(klass) zstream_new((klass), &deflate_funcs)
00976 #define zstream_inflate_new(klass) zstream_new((klass), &inflate_funcs)
00977
00978 static struct zstream *
00979 get_zstream(VALUE obj)
00980 {
00981 struct zstream *z;
00982
00983 Data_Get_Struct(obj, struct zstream, z);
00984 if (!ZSTREAM_IS_READY(z)) {
00985 rb_raise(cZError, "stream is not ready");
00986 }
00987 return z;
00988 }
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058 static VALUE
01059 rb_zstream_end(VALUE obj)
01060 {
01061 zstream_end(get_zstream(obj));
01062 return Qnil;
01063 }
01064
01065
01066
01067
01068
01069 static VALUE
01070 rb_zstream_reset(VALUE obj)
01071 {
01072 zstream_reset(get_zstream(obj));
01073 return Qnil;
01074 }
01075
01076
01077
01078
01079
01080 static VALUE
01081 rb_zstream_finish(VALUE obj)
01082 {
01083 struct zstream *z = get_zstream(obj);
01084 VALUE dst;
01085
01086 zstream_run(z, (Bytef*)"", 0, Z_FINISH);
01087 dst = zstream_detach_buffer(z);
01088
01089 OBJ_INFECT(dst, obj);
01090 return dst;
01091 }
01092
01093
01094
01095
01096 static VALUE
01097 rb_zstream_flush_next_in(VALUE obj)
01098 {
01099 struct zstream *z;
01100 VALUE dst;
01101
01102 Data_Get_Struct(obj, struct zstream, z);
01103 dst = zstream_detach_input(z);
01104 OBJ_INFECT(dst, obj);
01105 return dst;
01106 }
01107
01108
01109
01110
01111 static VALUE
01112 rb_zstream_flush_next_out(VALUE obj)
01113 {
01114 struct zstream *z;
01115 VALUE dst;
01116
01117 Data_Get_Struct(obj, struct zstream, z);
01118 dst = zstream_detach_buffer(z);
01119 OBJ_INFECT(dst, obj);
01120 return dst;
01121 }
01122
01123
01124
01125
01126
01127 static VALUE
01128 rb_zstream_avail_out(VALUE obj)
01129 {
01130 struct zstream *z;
01131 Data_Get_Struct(obj, struct zstream, z);
01132 return rb_uint2inum(z->stream.avail_out);
01133 }
01134
01135
01136
01137
01138
01139
01140
01141 static VALUE
01142 rb_zstream_set_avail_out(VALUE obj, VALUE size)
01143 {
01144 struct zstream *z = get_zstream(obj);
01145
01146 Check_Type(size, T_FIXNUM);
01147 zstream_expand_buffer_into(z, FIX2INT(size));
01148 return size;
01149 }
01150
01151
01152
01153
01154 static VALUE
01155 rb_zstream_avail_in(VALUE obj)
01156 {
01157 struct zstream *z;
01158 Data_Get_Struct(obj, struct zstream, z);
01159 return INT2FIX(NIL_P(z->input) ? 0 : (int)(RSTRING_LEN(z->input)));
01160 }
01161
01162
01163
01164
01165 static VALUE
01166 rb_zstream_total_in(VALUE obj)
01167 {
01168 return rb_uint2inum(get_zstream(obj)->stream.total_in);
01169 }
01170
01171
01172
01173
01174 static VALUE
01175 rb_zstream_total_out(VALUE obj)
01176 {
01177 return rb_uint2inum(get_zstream(obj)->stream.total_out);
01178 }
01179
01180
01181
01182
01183
01184
01185 static VALUE
01186 rb_zstream_data_type(VALUE obj)
01187 {
01188 return INT2FIX(get_zstream(obj)->stream.data_type);
01189 }
01190
01191
01192
01193
01194 static VALUE
01195 rb_zstream_adler(VALUE obj)
01196 {
01197 return rb_uint2inum(get_zstream(obj)->stream.adler);
01198 }
01199
01200
01201
01202
01203 static VALUE
01204 rb_zstream_finished_p(VALUE obj)
01205 {
01206 return ZSTREAM_IS_FINISHED(get_zstream(obj)) ? Qtrue : Qfalse;
01207 }
01208
01209
01210
01211
01212 static VALUE
01213 rb_zstream_closed_p(VALUE obj)
01214 {
01215 struct zstream *z;
01216 Data_Get_Struct(obj, struct zstream, z);
01217 return ZSTREAM_IS_READY(z) ? Qfalse : Qtrue;
01218 }
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230 #define FIXNUMARG(val, ifnil) \
01231 (NIL_P((val)) ? (ifnil) \
01232 : ((void)Check_Type((val), T_FIXNUM), FIX2INT((val))))
01233
01234 #define ARG_LEVEL(val) FIXNUMARG((val), Z_DEFAULT_COMPRESSION)
01235 #define ARG_WBITS(val) FIXNUMARG((val), MAX_WBITS)
01236 #define ARG_MEMLEVEL(val) FIXNUMARG((val), DEF_MEM_LEVEL)
01237 #define ARG_STRATEGY(val) FIXNUMARG((val), Z_DEFAULT_STRATEGY)
01238 #define ARG_FLUSH(val) FIXNUMARG((val), Z_NO_FLUSH)
01239
01240
01241 static VALUE
01242 rb_deflate_s_allocate(VALUE klass)
01243 {
01244 return zstream_deflate_new(klass);
01245 }
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305 static VALUE
01306 rb_deflate_initialize(int argc, VALUE *argv, VALUE obj)
01307 {
01308 struct zstream *z;
01309 VALUE level, wbits, memlevel, strategy;
01310 int err;
01311
01312 rb_scan_args(argc, argv, "04", &level, &wbits, &memlevel, &strategy);
01313 Data_Get_Struct(obj, struct zstream, z);
01314
01315 err = deflateInit2(&z->stream, ARG_LEVEL(level), Z_DEFLATED,
01316 ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel),
01317 ARG_STRATEGY(strategy));
01318 if (err != Z_OK) {
01319 raise_zlib_error(err, z->stream.msg);
01320 }
01321 ZSTREAM_READY(z);
01322
01323 return obj;
01324 }
01325
01326
01327
01328
01329
01330
01331 static VALUE
01332 rb_deflate_init_copy(VALUE self, VALUE orig)
01333 {
01334 struct zstream *z1, *z2;
01335 int err;
01336
01337 Data_Get_Struct(self, struct zstream, z1);
01338 z2 = get_zstream(orig);
01339
01340 err = deflateCopy(&z1->stream, &z2->stream);
01341 if (err != Z_OK) {
01342 raise_zlib_error(err, 0);
01343 }
01344 z1->input = NIL_P(z2->input) ? Qnil : rb_str_dup(z2->input);
01345 z1->buf = NIL_P(z2->buf) ? Qnil : rb_str_dup(z2->buf);
01346 z1->buf_filled = z2->buf_filled;
01347 z1->flags = z2->flags;
01348
01349 return self;
01350 }
01351
01352 static VALUE
01353 deflate_run(VALUE args)
01354 {
01355 struct zstream *z = (struct zstream*)((VALUE*)args)[0];
01356 VALUE src = ((VALUE*)args)[1];
01357
01358 zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_FINISH);
01359 return zstream_detach_buffer(z);
01360 }
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385 static VALUE
01386 rb_deflate_s_deflate(int argc, VALUE *argv, VALUE klass)
01387 {
01388 struct zstream z;
01389 VALUE src, level, dst, args[2];
01390 int err, lev;
01391
01392 rb_scan_args(argc, argv, "11", &src, &level);
01393
01394 lev = ARG_LEVEL(level);
01395 StringValue(src);
01396 zstream_init_deflate(&z);
01397 err = deflateInit(&z.stream, lev);
01398 if (err != Z_OK) {
01399 raise_zlib_error(err, z.stream.msg);
01400 }
01401 ZSTREAM_READY(&z);
01402
01403 args[0] = (VALUE)&z;
01404 args[1] = src;
01405 dst = rb_ensure(deflate_run, (VALUE)args, zstream_end, (VALUE)&z);
01406
01407 OBJ_INFECT(dst, src);
01408 return dst;
01409 }
01410
01411 static void
01412 do_deflate(struct zstream *z, VALUE src, int flush)
01413 {
01414 if (NIL_P(src)) {
01415 zstream_run(z, (Bytef*)"", 0, Z_FINISH);
01416 return;
01417 }
01418 StringValue(src);
01419 if (flush != Z_NO_FLUSH || RSTRING_LEN(src) > 0) {
01420 zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), flush);
01421 }
01422 }
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457 static VALUE
01458 rb_deflate_deflate(int argc, VALUE *argv, VALUE obj)
01459 {
01460 struct zstream *z = get_zstream(obj);
01461 VALUE src, flush, dst;
01462
01463 rb_scan_args(argc, argv, "11", &src, &flush);
01464 OBJ_INFECT(obj, src);
01465 do_deflate(z, src, ARG_FLUSH(flush));
01466 dst = zstream_detach_buffer(z);
01467
01468 OBJ_INFECT(dst, obj);
01469 return dst;
01470 }
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481 static VALUE
01482 rb_deflate_addstr(VALUE obj, VALUE src)
01483 {
01484 OBJ_INFECT(obj, src);
01485 do_deflate(get_zstream(obj), src, Z_NO_FLUSH);
01486 return obj;
01487 }
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501 static VALUE
01502 rb_deflate_flush(int argc, VALUE *argv, VALUE obj)
01503 {
01504 struct zstream *z = get_zstream(obj);
01505 VALUE v_flush, dst;
01506 int flush;
01507
01508 rb_scan_args(argc, argv, "01", &v_flush);
01509 flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
01510 if (flush != Z_NO_FLUSH) {
01511 zstream_run(z, (Bytef*)"", 0, flush);
01512 }
01513 dst = zstream_detach_buffer(z);
01514
01515 OBJ_INFECT(dst, obj);
01516 return dst;
01517 }
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538 static VALUE
01539 rb_deflate_params(VALUE obj, VALUE v_level, VALUE v_strategy)
01540 {
01541 struct zstream *z = get_zstream(obj);
01542 int level, strategy;
01543 int err;
01544 uInt n;
01545
01546 level = ARG_LEVEL(v_level);
01547 strategy = ARG_STRATEGY(v_strategy);
01548
01549 n = z->stream.avail_out;
01550 err = deflateParams(&z->stream, level, strategy);
01551 z->buf_filled += n - z->stream.avail_out;
01552 while (err == Z_BUF_ERROR) {
01553 rb_warning("deflateParams() returned Z_BUF_ERROR");
01554 zstream_expand_buffer(z);
01555 n = z->stream.avail_out;
01556 err = deflateParams(&z->stream, level, strategy);
01557 z->buf_filled += n - z->stream.avail_out;
01558 }
01559 if (err != Z_OK) {
01560 raise_zlib_error(err, z->stream.msg);
01561 }
01562
01563 return Qnil;
01564 }
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580 static VALUE
01581 rb_deflate_set_dictionary(VALUE obj, VALUE dic)
01582 {
01583 struct zstream *z = get_zstream(obj);
01584 VALUE src = dic;
01585 int err;
01586
01587 OBJ_INFECT(obj, dic);
01588 StringValue(src);
01589 err = deflateSetDictionary(&z->stream,
01590 (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
01591 if (err != Z_OK) {
01592 raise_zlib_error(err, z->stream.msg);
01593 }
01594
01595 return dic;
01596 }
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611 static VALUE
01612 rb_inflate_s_allocate(VALUE klass)
01613 {
01614 return zstream_inflate_new(klass);
01615 }
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657 static VALUE
01658 rb_inflate_initialize(int argc, VALUE *argv, VALUE obj)
01659 {
01660 struct zstream *z;
01661 VALUE wbits;
01662 int err;
01663
01664 rb_scan_args(argc, argv, "01", &wbits);
01665 Data_Get_Struct(obj, struct zstream, z);
01666
01667 err = inflateInit2(&z->stream, ARG_WBITS(wbits));
01668 if (err != Z_OK) {
01669 raise_zlib_error(err, z->stream.msg);
01670 }
01671 ZSTREAM_READY(z);
01672
01673 return obj;
01674 }
01675
01676 static VALUE
01677 inflate_run(VALUE args)
01678 {
01679 struct zstream *z = (struct zstream*)((VALUE*)args)[0];
01680 VALUE src = ((VALUE*)args)[1];
01681
01682 zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_SYNC_FLUSH);
01683 zstream_run(z, (Bytef*)"", 0, Z_FINISH);
01684 return zstream_detach_buffer(z);
01685 }
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708 static VALUE
01709 rb_inflate_s_inflate(VALUE obj, VALUE src)
01710 {
01711 struct zstream z;
01712 VALUE dst, args[2];
01713 int err;
01714
01715 StringValue(src);
01716 zstream_init_inflate(&z);
01717 err = inflateInit(&z.stream);
01718 if (err != Z_OK) {
01719 raise_zlib_error(err, z.stream.msg);
01720 }
01721 ZSTREAM_READY(&z);
01722
01723 args[0] = (VALUE)&z;
01724 args[1] = src;
01725 dst = rb_ensure(inflate_run, (VALUE)args, zstream_end, (VALUE)&z);
01726
01727 OBJ_INFECT(dst, src);
01728 return dst;
01729 }
01730
01731 static void
01732 do_inflate(struct zstream *z, VALUE src)
01733 {
01734 if (NIL_P(src)) {
01735 zstream_run(z, (Bytef*)"", 0, Z_FINISH);
01736 return;
01737 }
01738 StringValue(src);
01739 if (RSTRING_LEN(src) > 0 || z->stream.avail_in > 0) {
01740 zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_SYNC_FLUSH);
01741 }
01742 }
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776 static VALUE
01777 rb_inflate_inflate(VALUE obj, VALUE src)
01778 {
01779 struct zstream *z = get_zstream(obj);
01780 VALUE dst;
01781
01782 OBJ_INFECT(obj, src);
01783
01784 if (ZSTREAM_IS_FINISHED(z)) {
01785 if (NIL_P(src)) {
01786 dst = zstream_detach_buffer(z);
01787 }
01788 else {
01789 StringValue(src);
01790 zstream_append_buffer2(z, src);
01791 dst = rb_str_new(0, 0);
01792 }
01793 }
01794 else {
01795 do_inflate(z, src);
01796 dst = zstream_detach_buffer(z);
01797 if (ZSTREAM_IS_FINISHED(z)) {
01798 zstream_passthrough_input(z);
01799 }
01800 }
01801
01802 OBJ_INFECT(dst, obj);
01803 return dst;
01804 }
01805
01806
01807
01808
01809
01810
01811
01812
01813 static VALUE
01814 rb_inflate_addstr(VALUE obj, VALUE src)
01815 {
01816 struct zstream *z = get_zstream(obj);
01817
01818 OBJ_INFECT(obj, src);
01819
01820 if (ZSTREAM_IS_FINISHED(z)) {
01821 if (!NIL_P(src)) {
01822 StringValue(src);
01823 zstream_append_buffer2(z, src);
01824 }
01825 }
01826 else {
01827 do_inflate(z, src);
01828 if (ZSTREAM_IS_FINISHED(z)) {
01829 zstream_passthrough_input(z);
01830 }
01831 }
01832
01833 return obj;
01834 }
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844 static VALUE
01845 rb_inflate_sync(VALUE obj, VALUE src)
01846 {
01847 struct zstream *z = get_zstream(obj);
01848
01849 OBJ_INFECT(obj, src);
01850 StringValue(src);
01851 return zstream_sync(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src));
01852 }
01853
01854
01855
01856
01857
01858
01859
01860
01861 static VALUE
01862 rb_inflate_sync_point_p(VALUE obj)
01863 {
01864 struct zstream *z = get_zstream(obj);
01865 int err;
01866
01867 err = inflateSyncPoint(&z->stream);
01868 if (err == 1) {
01869 return Qtrue;
01870 }
01871 if (err != Z_OK) {
01872 raise_zlib_error(err, z->stream.msg);
01873 }
01874 return Qfalse;
01875 }
01876
01877
01878
01879
01880
01881
01882
01883
01884 static VALUE
01885 rb_inflate_set_dictionary(VALUE obj, VALUE dic)
01886 {
01887 struct zstream *z = get_zstream(obj);
01888 VALUE src = dic;
01889 int err;
01890
01891 OBJ_INFECT(obj, dic);
01892 StringValue(src);
01893 err = inflateSetDictionary(&z->stream,
01894 (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src));
01895 if (err != Z_OK) {
01896 raise_zlib_error(err, z->stream.msg);
01897 }
01898
01899 return dic;
01900 }
01901
01902
01903
01904 #if GZIP_SUPPORT
01905
01906
01907
01908
01909
01910
01911
01912
01913 #define GZ_MAGIC1 0x1f
01914 #define GZ_MAGIC2 0x8b
01915 #define GZ_METHOD_DEFLATE 8
01916 #define GZ_FLAG_MULTIPART 0x2
01917 #define GZ_FLAG_EXTRA 0x4
01918 #define GZ_FLAG_ORIG_NAME 0x8
01919 #define GZ_FLAG_COMMENT 0x10
01920 #define GZ_FLAG_ENCRYPT 0x20
01921 #define GZ_FLAG_UNKNOWN_MASK 0xc0
01922
01923 #define GZ_EXTRAFLAG_FAST 0x4
01924 #define GZ_EXTRAFLAG_SLOW 0x2
01925
01926
01927 #define OS_MSDOS 0x00
01928 #define OS_AMIGA 0x01
01929 #define OS_VMS 0x02
01930 #define OS_UNIX 0x03
01931 #define OS_ATARI 0x05
01932 #define OS_OS2 0x06
01933 #define OS_MACOS 0x07
01934 #define OS_TOPS20 0x0a
01935 #define OS_WIN32 0x0b
01936
01937 #define OS_VMCMS 0x04
01938 #define OS_ZSYSTEM 0x08
01939 #define OS_CPM 0x09
01940 #define OS_QDOS 0x0c
01941 #define OS_RISCOS 0x0d
01942 #define OS_UNKNOWN 0xff
01943
01944 #ifndef OS_CODE
01945 #define OS_CODE OS_UNIX
01946 #endif
01947
01948 static ID id_write, id_read, id_readpartial, id_flush, id_seek, id_close, id_path, id_input;
01949 static VALUE cGzError, cNoFooter, cCRCError, cLengthError;
01950
01951
01952
01953
01954
01955 struct gzfile {
01956 struct zstream z;
01957 VALUE io;
01958 int level;
01959 time_t mtime;
01960 int os_code;
01961 VALUE orig_name;
01962 VALUE comment;
01963 unsigned long crc;
01964 int lineno;
01965 long ungetc;
01966 void (*end)(struct gzfile *);
01967 rb_encoding *enc;
01968 rb_encoding *enc2;
01969 rb_econv_t *ec;
01970 int ecflags;
01971 VALUE ecopts;
01972 char *cbuf;
01973 VALUE path;
01974 };
01975 #define GZFILE_CBUF_CAPA 10
01976
01977 #define GZFILE_FLAG_SYNC ZSTREAM_FLAG_UNUSED
01978 #define GZFILE_FLAG_HEADER_FINISHED (ZSTREAM_FLAG_UNUSED << 1)
01979 #define GZFILE_FLAG_FOOTER_FINISHED (ZSTREAM_FLAG_UNUSED << 2)
01980
01981 #define GZFILE_IS_FINISHED(gz) \
01982 (ZSTREAM_IS_FINISHED(&(gz)->z) && (gz)->z.buf_filled == 0)
01983
01984 #define GZFILE_READ_SIZE 2048
01985
01986
01987 static void
01988 gzfile_mark(struct gzfile *gz)
01989 {
01990 rb_gc_mark(gz->io);
01991 rb_gc_mark(gz->orig_name);
01992 rb_gc_mark(gz->comment);
01993 zstream_mark(&gz->z);
01994 rb_gc_mark(gz->ecopts);
01995 rb_gc_mark(gz->path);
01996 }
01997
01998 static void
01999 gzfile_free(struct gzfile *gz)
02000 {
02001 struct zstream *z = &gz->z;
02002
02003 if (ZSTREAM_IS_READY(z)) {
02004 if (z->func == &deflate_funcs) {
02005 finalizer_warn("Zlib::GzipWriter object must be closed explicitly.");
02006 }
02007 zstream_finalize(z);
02008 }
02009 if (gz->cbuf) {
02010 xfree(gz->cbuf);
02011 }
02012 xfree(gz);
02013 }
02014
02015 static VALUE
02016 gzfile_new(klass, funcs, endfunc)
02017 VALUE klass;
02018 const struct zstream_funcs *funcs;
02019 void (*endfunc)(struct gzfile *);
02020 {
02021 VALUE obj;
02022 struct gzfile *gz;
02023
02024 obj = Data_Make_Struct(klass, struct gzfile, gzfile_mark, gzfile_free, gz);
02025 zstream_init(&gz->z, funcs);
02026 gz->io = Qnil;
02027 gz->level = 0;
02028 gz->mtime = 0;
02029 gz->os_code = OS_CODE;
02030 gz->orig_name = Qnil;
02031 gz->comment = Qnil;
02032 gz->crc = crc32(0, Z_NULL, 0);
02033 gz->lineno = 0;
02034 gz->ungetc = 0;
02035 gz->end = endfunc;
02036 gz->enc = rb_default_external_encoding();
02037 gz->enc2 = 0;
02038 gz->ec = NULL;
02039 gz->ecflags = 0;
02040 gz->ecopts = Qnil;
02041 gz->cbuf = 0;
02042 gz->path = Qnil;
02043
02044 return obj;
02045 }
02046
02047 #define gzfile_writer_new(gz) gzfile_new((gz),&deflate_funcs,gzfile_writer_end)
02048 #define gzfile_reader_new(gz) gzfile_new((gz),&inflate_funcs,gzfile_reader_end)
02049
02050 static void
02051 gzfile_reset(struct gzfile *gz)
02052 {
02053 zstream_reset(&gz->z);
02054 gz->crc = crc32(0, Z_NULL, 0);
02055 gz->lineno = 0;
02056 gz->ungetc = 0;
02057 if (gz->ec) {
02058 rb_econv_close(gz->ec);
02059 gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
02060 gz->ecflags, gz->ecopts);
02061 }
02062 }
02063
02064 static void
02065 gzfile_close(struct gzfile *gz, int closeflag)
02066 {
02067 VALUE io = gz->io;
02068
02069 gz->end(gz);
02070 gz->io = Qnil;
02071 gz->orig_name = Qnil;
02072 gz->comment = Qnil;
02073 if (closeflag && rb_respond_to(io, id_close)) {
02074 rb_funcall(io, id_close, 0);
02075 }
02076 }
02077
02078 static void
02079 gzfile_write_raw(struct gzfile *gz)
02080 {
02081 VALUE str;
02082
02083 if (gz->z.buf_filled > 0) {
02084 str = zstream_detach_buffer(&gz->z);
02085 OBJ_TAINT(str);
02086 rb_funcall(gz->io, id_write, 1, str);
02087 if ((gz->z.flags & GZFILE_FLAG_SYNC)
02088 && rb_respond_to(gz->io, id_flush))
02089 rb_funcall(gz->io, id_flush, 0);
02090 }
02091 }
02092
02093 static VALUE
02094 gzfile_read_raw_partial(VALUE arg)
02095 {
02096 struct gzfile *gz = (struct gzfile*)arg;
02097 VALUE str;
02098
02099 str = rb_funcall(gz->io, id_readpartial, 1, INT2FIX(GZFILE_READ_SIZE));
02100 Check_Type(str, T_STRING);
02101 return str;
02102 }
02103
02104 static VALUE
02105 gzfile_read_raw_rescue(VALUE arg)
02106 {
02107 struct gzfile *gz = (struct gzfile*)arg;
02108 VALUE str = Qnil;
02109 if (rb_obj_is_kind_of(rb_errinfo(), rb_eNoMethodError)) {
02110 str = rb_funcall(gz->io, id_read, 1, INT2FIX(GZFILE_READ_SIZE));
02111 if (!NIL_P(str)) {
02112 Check_Type(str, T_STRING);
02113 }
02114 }
02115 return str;
02116 }
02117
02118 static VALUE
02119 gzfile_read_raw(struct gzfile *gz)
02120 {
02121 return rb_rescue2(gzfile_read_raw_partial, (VALUE)gz,
02122 gzfile_read_raw_rescue, (VALUE)gz,
02123 rb_eEOFError, rb_eNoMethodError, (VALUE)0);
02124 }
02125
02126 static int
02127 gzfile_read_raw_ensure(struct gzfile *gz, long size)
02128 {
02129 VALUE str;
02130
02131 while (NIL_P(gz->z.input) || RSTRING_LEN(gz->z.input) < size) {
02132 str = gzfile_read_raw(gz);
02133 if (NIL_P(str)) return 0;
02134 zstream_append_input2(&gz->z, str);
02135 }
02136 return 1;
02137 }
02138
02139 static char *
02140 gzfile_read_raw_until_zero(struct gzfile *gz, long offset)
02141 {
02142 VALUE str;
02143 char *p;
02144
02145 for (;;) {
02146 p = memchr(RSTRING_PTR(gz->z.input) + offset, '\0',
02147 RSTRING_LEN(gz->z.input) - offset);
02148 if (p) break;
02149 str = gzfile_read_raw(gz);
02150 if (NIL_P(str)) {
02151 rb_raise(cGzError, "unexpected end of file");
02152 }
02153 offset = RSTRING_LEN(gz->z.input);
02154 zstream_append_input2(&gz->z, str);
02155 }
02156 return p;
02157 }
02158
02159 static unsigned int
02160 gzfile_get16(const unsigned char *src)
02161 {
02162 unsigned int n;
02163 n = *(src++) & 0xff;
02164 n |= (*(src++) & 0xff) << 8;
02165 return n;
02166 }
02167
02168 static unsigned long
02169 gzfile_get32(const unsigned char *src)
02170 {
02171 unsigned long n;
02172 n = *(src++) & 0xff;
02173 n |= (*(src++) & 0xff) << 8;
02174 n |= (*(src++) & 0xff) << 16;
02175 n |= (*(src++) & 0xffU) << 24;
02176 return n;
02177 }
02178
02179 static void
02180 gzfile_set32(unsigned long n, unsigned char *dst)
02181 {
02182 *(dst++) = n & 0xff;
02183 *(dst++) = (n >> 8) & 0xff;
02184 *(dst++) = (n >> 16) & 0xff;
02185 *dst = (n >> 24) & 0xff;
02186 }
02187
02188 static void
02189 gzfile_raise(struct gzfile *gz, VALUE klass, const char *message)
02190 {
02191 VALUE exc = rb_exc_new2(klass, message);
02192 if (!NIL_P(gz->z.input)) {
02193 rb_ivar_set(exc, id_input, rb_str_resurrect(gz->z.input));
02194 }
02195 rb_exc_raise(exc);
02196 }
02197
02198
02199
02200
02201
02202
02203 static VALUE
02204 gzfile_error_inspect(VALUE error)
02205 {
02206 VALUE str = rb_call_super(0, 0);
02207 VALUE input = rb_attr_get(error, id_input);
02208
02209 if (!NIL_P(input)) {
02210 rb_str_resize(str, RSTRING_LEN(str)-1);
02211 rb_str_cat2(str, ", input=");
02212 rb_str_append(str, rb_str_inspect(input));
02213 rb_str_cat2(str, ">");
02214 }
02215 return str;
02216 }
02217
02218 static void
02219 gzfile_make_header(struct gzfile *gz)
02220 {
02221 Bytef buf[10];
02222 unsigned char flags = 0, extraflags = 0;
02223
02224 if (!NIL_P(gz->orig_name)) {
02225 flags |= GZ_FLAG_ORIG_NAME;
02226 }
02227 if (!NIL_P(gz->comment)) {
02228 flags |= GZ_FLAG_COMMENT;
02229 }
02230 if (gz->mtime == 0) {
02231 gz->mtime = time(0);
02232 }
02233
02234 if (gz->level == Z_BEST_SPEED) {
02235 extraflags |= GZ_EXTRAFLAG_FAST;
02236 }
02237 else if (gz->level == Z_BEST_COMPRESSION) {
02238 extraflags |= GZ_EXTRAFLAG_SLOW;
02239 }
02240
02241 buf[0] = GZ_MAGIC1;
02242 buf[1] = GZ_MAGIC2;
02243 buf[2] = GZ_METHOD_DEFLATE;
02244 buf[3] = flags;
02245 gzfile_set32((unsigned long)gz->mtime, &buf[4]);
02246 buf[8] = extraflags;
02247 buf[9] = gz->os_code;
02248 zstream_append_buffer(&gz->z, buf, sizeof(buf));
02249
02250 if (!NIL_P(gz->orig_name)) {
02251 zstream_append_buffer2(&gz->z, gz->orig_name);
02252 zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
02253 }
02254 if (!NIL_P(gz->comment)) {
02255 zstream_append_buffer2(&gz->z, gz->comment);
02256 zstream_append_buffer(&gz->z, (Bytef*)"\0", 1);
02257 }
02258
02259 gz->z.flags |= GZFILE_FLAG_HEADER_FINISHED;
02260 }
02261
02262 static void
02263 gzfile_make_footer(struct gzfile *gz)
02264 {
02265 Bytef buf[8];
02266
02267 gzfile_set32(gz->crc, buf);
02268 gzfile_set32(gz->z.stream.total_in, &buf[4]);
02269 zstream_append_buffer(&gz->z, buf, sizeof(buf));
02270 gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;
02271 }
02272
02273 static void
02274 gzfile_read_header(struct gzfile *gz)
02275 {
02276 const unsigned char *head;
02277 long len;
02278 char flags, *p;
02279
02280 if (!gzfile_read_raw_ensure(gz, 10)) {
02281 gzfile_raise(gz, cGzError, "not in gzip format");
02282 }
02283
02284 head = (unsigned char*)RSTRING_PTR(gz->z.input);
02285
02286 if (head[0] != GZ_MAGIC1 || head[1] != GZ_MAGIC2) {
02287 gzfile_raise(gz, cGzError, "not in gzip format");
02288 }
02289 if (head[2] != GZ_METHOD_DEFLATE) {
02290 rb_raise(cGzError, "unsupported compression method %d", head[2]);
02291 }
02292
02293 flags = head[3];
02294 if (flags & GZ_FLAG_MULTIPART) {
02295 rb_raise(cGzError, "multi-part gzip file is not supported");
02296 }
02297 else if (flags & GZ_FLAG_ENCRYPT) {
02298 rb_raise(cGzError, "encrypted gzip file is not supported");
02299 }
02300 else if (flags & GZ_FLAG_UNKNOWN_MASK) {
02301 rb_raise(cGzError, "unknown flags 0x%02x", flags);
02302 }
02303
02304 if (head[8] & GZ_EXTRAFLAG_FAST) {
02305 gz->level = Z_BEST_SPEED;
02306 }
02307 else if (head[8] & GZ_EXTRAFLAG_SLOW) {
02308 gz->level = Z_BEST_COMPRESSION;
02309 }
02310 else {
02311 gz->level = Z_DEFAULT_COMPRESSION;
02312 }
02313
02314 gz->mtime = gzfile_get32(&head[4]);
02315 gz->os_code = head[9];
02316 zstream_discard_input(&gz->z, 10);
02317
02318 if (flags & GZ_FLAG_EXTRA) {
02319 if (!gzfile_read_raw_ensure(gz, 2)) {
02320 rb_raise(cGzError, "unexpected end of file");
02321 }
02322 len = gzfile_get16((Bytef*)RSTRING_PTR(gz->z.input));
02323 if (!gzfile_read_raw_ensure(gz, 2 + len)) {
02324 rb_raise(cGzError, "unexpected end of file");
02325 }
02326 zstream_discard_input(&gz->z, 2 + len);
02327 }
02328 if (flags & GZ_FLAG_ORIG_NAME) {
02329 if (!gzfile_read_raw_ensure(gz, 1)) {
02330 rb_raise(cGzError, "unexpected end of file");
02331 }
02332 p = gzfile_read_raw_until_zero(gz, 0);
02333 len = p - RSTRING_PTR(gz->z.input);
02334 gz->orig_name = rb_str_new(RSTRING_PTR(gz->z.input), len);
02335 OBJ_TAINT(gz->orig_name);
02336 zstream_discard_input(&gz->z, len + 1);
02337 }
02338 if (flags & GZ_FLAG_COMMENT) {
02339 if (!gzfile_read_raw_ensure(gz, 1)) {
02340 rb_raise(cGzError, "unexpected end of file");
02341 }
02342 p = gzfile_read_raw_until_zero(gz, 0);
02343 len = p - RSTRING_PTR(gz->z.input);
02344 gz->comment = rb_str_new(RSTRING_PTR(gz->z.input), len);
02345 OBJ_TAINT(gz->comment);
02346 zstream_discard_input(&gz->z, len + 1);
02347 }
02348
02349 if (gz->z.input != Qnil && RSTRING_LEN(gz->z.input) > 0) {
02350 zstream_run(&gz->z, 0, 0, Z_SYNC_FLUSH);
02351 }
02352 }
02353
02354 static void
02355 gzfile_check_footer(struct gzfile *gz)
02356 {
02357 unsigned long crc, length;
02358
02359 gz->z.flags |= GZFILE_FLAG_FOOTER_FINISHED;
02360
02361 if (!gzfile_read_raw_ensure(gz, 8)) {
02362 gzfile_raise(gz, cNoFooter, "footer is not found");
02363 }
02364
02365 crc = gzfile_get32((Bytef*)RSTRING_PTR(gz->z.input));
02366 length = gzfile_get32((Bytef*)RSTRING_PTR(gz->z.input) + 4);
02367
02368 gz->z.stream.total_in += 8;
02369 zstream_discard_input(&gz->z, 8);
02370
02371 if (gz->crc != crc) {
02372 rb_raise(cCRCError, "invalid compressed data -- crc error");
02373 }
02374 if ((uint32_t)gz->z.stream.total_out != length) {
02375 rb_raise(cLengthError, "invalid compressed data -- length error");
02376 }
02377 }
02378
02379 static void
02380 gzfile_write(struct gzfile *gz, Bytef *str, long len)
02381 {
02382 if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
02383 gzfile_make_header(gz);
02384 }
02385
02386 if (len > 0 || (gz->z.flags & GZFILE_FLAG_SYNC)) {
02387 gz->crc = checksum_long(crc32, gz->crc, str, len);
02388 zstream_run(&gz->z, str, len, (gz->z.flags & GZFILE_FLAG_SYNC)
02389 ? Z_SYNC_FLUSH : Z_NO_FLUSH);
02390 }
02391 gzfile_write_raw(gz);
02392 }
02393
02394 static long
02395 gzfile_read_more(struct gzfile *gz)
02396 {
02397 volatile VALUE str;
02398
02399 while (!ZSTREAM_IS_FINISHED(&gz->z)) {
02400 str = gzfile_read_raw(gz);
02401 if (NIL_P(str)) {
02402 if (!ZSTREAM_IS_FINISHED(&gz->z)) {
02403 rb_raise(cGzError, "unexpected end of file");
02404 }
02405 break;
02406 }
02407 if (RSTRING_LEN(str) > 0) {
02408 zstream_run(&gz->z, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str),
02409 Z_SYNC_FLUSH);
02410 }
02411 if (gz->z.buf_filled > 0) break;
02412 }
02413 return gz->z.buf_filled;
02414 }
02415
02416 static void
02417 gzfile_calc_crc(struct gzfile *gz, VALUE str)
02418 {
02419 if (RSTRING_LEN(str) <= gz->ungetc) {
02420 gz->ungetc -= RSTRING_LEN(str);
02421 }
02422 else {
02423 gz->crc = checksum_long(crc32, gz->crc, (Bytef*)RSTRING_PTR(str) + gz->ungetc,
02424 RSTRING_LEN(str) - gz->ungetc);
02425 gz->ungetc = 0;
02426 }
02427 }
02428
02429 static VALUE
02430 gzfile_newstr(struct gzfile *gz, VALUE str)
02431 {
02432 if (!gz->enc2) {
02433 rb_enc_associate(str, gz->enc);
02434 OBJ_TAINT(str);
02435 return str;
02436 }
02437 if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
02438 str = rb_econv_str_convert(gz->ec, str, ECONV_PARTIAL_INPUT);
02439 rb_enc_associate(str, gz->enc);
02440 OBJ_TAINT(str);
02441 return str;
02442 }
02443 return rb_str_conv_enc_opts(str, gz->enc2, gz->enc,
02444 gz->ecflags, gz->ecopts);
02445 }
02446
02447 static long
02448 gzfile_fill(struct gzfile *gz, long len)
02449 {
02450 if (len < 0)
02451 rb_raise(rb_eArgError, "negative length %ld given", len);
02452 if (len == 0)
02453 return 0;
02454 while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled < len) {
02455 gzfile_read_more(gz);
02456 }
02457 if (GZFILE_IS_FINISHED(gz)) {
02458 if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
02459 gzfile_check_footer(gz);
02460 }
02461 return -1;
02462 }
02463 return len < gz->z.buf_filled ? len : gz->z.buf_filled;
02464 }
02465
02466 static VALUE
02467 gzfile_read(struct gzfile *gz, long len)
02468 {
02469 VALUE dst;
02470
02471 len = gzfile_fill(gz, len);
02472 if (len == 0) return rb_str_new(0, 0);
02473 if (len < 0) return Qnil;
02474 dst = zstream_shift_buffer(&gz->z, len);
02475 gzfile_calc_crc(gz, dst);
02476 return dst;
02477 }
02478
02479 static VALUE
02480 gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
02481 {
02482 VALUE dst;
02483
02484 if (len < 0)
02485 rb_raise(rb_eArgError, "negative length %ld given", len);
02486
02487 if (!NIL_P(outbuf))
02488 OBJ_TAINT(outbuf);
02489
02490 if (len == 0) {
02491 if (NIL_P(outbuf))
02492 return rb_str_new(0, 0);
02493 else {
02494 rb_str_resize(outbuf, 0);
02495 return outbuf;
02496 }
02497 }
02498 while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled == 0) {
02499 gzfile_read_more(gz);
02500 }
02501 if (GZFILE_IS_FINISHED(gz)) {
02502 if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
02503 gzfile_check_footer(gz);
02504 }
02505 if (!NIL_P(outbuf))
02506 rb_str_resize(outbuf, 0);
02507 rb_raise(rb_eEOFError, "end of file reached");
02508 }
02509
02510 dst = zstream_shift_buffer(&gz->z, len);
02511 gzfile_calc_crc(gz, dst);
02512
02513 if (!NIL_P(outbuf)) {
02514 rb_str_resize(outbuf, RSTRING_LEN(dst));
02515 memcpy(RSTRING_PTR(outbuf), RSTRING_PTR(dst), RSTRING_LEN(dst));
02516 dst = outbuf;
02517 }
02518 OBJ_TAINT(dst);
02519 return dst;
02520 }
02521
02522 static VALUE
02523 gzfile_read_all(struct gzfile *gz)
02524 {
02525 VALUE dst;
02526
02527 while (!ZSTREAM_IS_FINISHED(&gz->z)) {
02528 gzfile_read_more(gz);
02529 }
02530 if (GZFILE_IS_FINISHED(gz)) {
02531 if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
02532 gzfile_check_footer(gz);
02533 }
02534 return rb_str_new(0, 0);
02535 }
02536
02537 dst = zstream_detach_buffer(&gz->z);
02538 gzfile_calc_crc(gz, dst);
02539 OBJ_TAINT(dst);
02540 return gzfile_newstr(gz, dst);
02541 }
02542
02543 static VALUE
02544 gzfile_getc(struct gzfile *gz)
02545 {
02546 VALUE buf, dst = 0;
02547 int len;
02548
02549 len = rb_enc_mbmaxlen(gz->enc);
02550 while (!ZSTREAM_IS_FINISHED(&gz->z) && gz->z.buf_filled < len) {
02551 gzfile_read_more(gz);
02552 }
02553 if (GZFILE_IS_FINISHED(gz)) {
02554 if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
02555 gzfile_check_footer(gz);
02556 }
02557 return Qnil;
02558 }
02559
02560 if (gz->ec && rb_enc_dummy_p(gz->enc2)) {
02561 const unsigned char *ss, *sp, *se;
02562 unsigned char *ds, *dp, *de;
02563 rb_econv_result_t res;
02564
02565 if (!gz->cbuf) {
02566 gz->cbuf = ALLOC_N(char, GZFILE_CBUF_CAPA);
02567 }
02568 ss = sp = (const unsigned char*)RSTRING_PTR(gz->z.buf);
02569 se = sp + gz->z.buf_filled;
02570 ds = dp = (unsigned char *)gz->cbuf;
02571 de = (unsigned char *)ds + GZFILE_CBUF_CAPA;
02572 res = rb_econv_convert(gz->ec, &sp, se, &dp, de, ECONV_PARTIAL_INPUT|ECONV_AFTER_OUTPUT);
02573 rb_econv_check_error(gz->ec);
02574 dst = zstream_shift_buffer(&gz->z, sp - ss);
02575 gzfile_calc_crc(gz, dst);
02576 dst = rb_str_new(gz->cbuf, dp - ds);
02577 rb_enc_associate(dst, gz->enc);
02578 OBJ_TAINT(dst);
02579 return dst;
02580 }
02581 else {
02582 buf = gz->z.buf;
02583 len = rb_enc_mbclen(RSTRING_PTR(buf), RSTRING_END(buf), gz->enc);
02584 dst = gzfile_read(gz, len);
02585 return gzfile_newstr(gz, dst);
02586 }
02587 }
02588
02589 static void
02590 gzfile_ungets(struct gzfile *gz, const Bytef *b, long len)
02591 {
02592 zstream_buffer_ungets(&gz->z, b, len);
02593 gz->ungetc+=len;
02594 }
02595
02596 static void
02597 gzfile_ungetbyte(struct gzfile *gz, int c)
02598 {
02599 zstream_buffer_ungetbyte(&gz->z, c);
02600 gz->ungetc++;
02601 }
02602
02603 static VALUE
02604 gzfile_writer_end_run(VALUE arg)
02605 {
02606 struct gzfile *gz = (struct gzfile *)arg;
02607
02608 if (!(gz->z.flags & GZFILE_FLAG_HEADER_FINISHED)) {
02609 gzfile_make_header(gz);
02610 }
02611
02612 zstream_run(&gz->z, (Bytef*)"", 0, Z_FINISH);
02613 gzfile_make_footer(gz);
02614 gzfile_write_raw(gz);
02615
02616 return Qnil;
02617 }
02618
02619 static void
02620 gzfile_writer_end(struct gzfile *gz)
02621 {
02622 if (ZSTREAM_IS_CLOSING(&gz->z)) return;
02623 gz->z.flags |= ZSTREAM_FLAG_CLOSING;
02624
02625 rb_ensure(gzfile_writer_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);
02626 }
02627
02628 static VALUE
02629 gzfile_reader_end_run(VALUE arg)
02630 {
02631 struct gzfile *gz = (struct gzfile *)arg;
02632
02633 if (GZFILE_IS_FINISHED(gz)
02634 && !(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
02635 gzfile_check_footer(gz);
02636 }
02637
02638 return Qnil;
02639 }
02640
02641 static void
02642 gzfile_reader_end(struct gzfile *gz)
02643 {
02644 if (ZSTREAM_IS_CLOSING(&gz->z)) return;
02645 gz->z.flags |= ZSTREAM_FLAG_CLOSING;
02646
02647 rb_ensure(gzfile_reader_end_run, (VALUE)gz, zstream_end, (VALUE)&gz->z);
02648 }
02649
02650 static void
02651 gzfile_reader_rewind(struct gzfile *gz)
02652 {
02653 long n;
02654
02655 n = gz->z.stream.total_in;
02656 if (!NIL_P(gz->z.input)) {
02657 n += RSTRING_LEN(gz->z.input);
02658 }
02659
02660 rb_funcall(gz->io, id_seek, 2, rb_int2inum(-n), INT2FIX(1));
02661 gzfile_reset(gz);
02662 }
02663
02664 static VALUE
02665 gzfile_reader_get_unused(struct gzfile *gz)
02666 {
02667 VALUE str;
02668
02669 if (!ZSTREAM_IS_READY(&gz->z)) return Qnil;
02670 if (!GZFILE_IS_FINISHED(gz)) return Qnil;
02671 if (!(gz->z.flags & GZFILE_FLAG_FOOTER_FINISHED)) {
02672 gzfile_check_footer(gz);
02673 }
02674 if (NIL_P(gz->z.input)) return Qnil;
02675
02676 str = rb_str_resurrect(gz->z.input);
02677 OBJ_TAINT(str);
02678 return str;
02679 }
02680
02681 static struct gzfile *
02682 get_gzfile(VALUE obj)
02683 {
02684 struct gzfile *gz;
02685
02686 Data_Get_Struct(obj, struct gzfile, gz);
02687 if (!ZSTREAM_IS_READY(&gz->z)) {
02688 rb_raise(cGzError, "closed gzip stream");
02689 }
02690 return gz;
02691 }
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734 typedef struct {
02735 int argc;
02736 VALUE *argv;
02737 VALUE klass;
02738 } new_wrap_arg_t;
02739
02740 static VALUE
02741 new_wrap(VALUE tmp)
02742 {
02743 new_wrap_arg_t *arg = (new_wrap_arg_t *)tmp;
02744 return rb_class_new_instance(arg->argc, arg->argv, arg->klass);
02745 }
02746
02747 static VALUE
02748 gzfile_ensure_close(VALUE obj)
02749 {
02750 struct gzfile *gz;
02751
02752 Data_Get_Struct(obj, struct gzfile, gz);
02753 if (ZSTREAM_IS_READY(&gz->z)) {
02754 gzfile_close(gz, 1);
02755 }
02756 return Qnil;
02757 }
02758
02759 static VALUE
02760 gzfile_wrap(int argc, VALUE *argv, VALUE klass, int close_io_on_error)
02761 {
02762 VALUE obj;
02763
02764 if (close_io_on_error) {
02765 int state = 0;
02766 new_wrap_arg_t arg;
02767 arg.argc = argc;
02768 arg.argv = argv;
02769 arg.klass = klass;
02770 obj = rb_protect(new_wrap, (VALUE)&arg, &state);
02771 if (state) {
02772 rb_io_close(argv[0]);
02773 rb_jump_tag(state);
02774 }
02775 }
02776 else {
02777 obj = rb_class_new_instance(argc, argv, klass);
02778 }
02779
02780 if (rb_block_given_p()) {
02781 return rb_ensure(rb_yield, obj, gzfile_ensure_close, obj);
02782 }
02783 else {
02784 return obj;
02785 }
02786 }
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800 static VALUE
02801 rb_gzfile_s_wrap(int argc, VALUE *argv, VALUE klass)
02802 {
02803 return gzfile_wrap(argc, argv, klass, 0);
02804 }
02805
02806
02807
02808
02809
02810
02811 static VALUE
02812 gzfile_s_open(int argc, VALUE *argv, VALUE klass, const char *mode)
02813 {
02814 VALUE io, filename;
02815
02816 if (argc < 1) {
02817 rb_raise(rb_eArgError, "wrong number of arguments (0 for 1)");
02818 }
02819 filename = argv[0];
02820 io = rb_file_open_str(filename, mode);
02821 argv[0] = io;
02822 return gzfile_wrap(argc, argv, klass, 1);
02823 }
02824
02825
02826
02827
02828
02829
02830 static VALUE
02831 rb_gzfile_to_io(VALUE obj)
02832 {
02833 return get_gzfile(obj)->io;
02834 }
02835
02836
02837
02838
02839
02840
02841 static VALUE
02842 rb_gzfile_crc(VALUE obj)
02843 {
02844 return rb_uint2inum(get_gzfile(obj)->crc);
02845 }
02846
02847
02848
02849
02850
02851
02852 static VALUE
02853 rb_gzfile_mtime(VALUE obj)
02854 {
02855 return rb_time_new(get_gzfile(obj)->mtime, (time_t)0);
02856 }
02857
02858
02859
02860
02861
02862
02863 static VALUE
02864 rb_gzfile_level(VALUE obj)
02865 {
02866 return INT2FIX(get_gzfile(obj)->level);
02867 }
02868
02869
02870
02871
02872
02873
02874 static VALUE
02875 rb_gzfile_os_code(VALUE obj)
02876 {
02877 return INT2FIX(get_gzfile(obj)->os_code);
02878 }
02879
02880
02881
02882
02883
02884
02885
02886 static VALUE
02887 rb_gzfile_orig_name(VALUE obj)
02888 {
02889 VALUE str = get_gzfile(obj)->orig_name;
02890 if (!NIL_P(str)) {
02891 str = rb_str_dup(str);
02892 }
02893 OBJ_TAINT(str);
02894 return str;
02895 }
02896
02897
02898
02899
02900
02901
02902
02903 static VALUE
02904 rb_gzfile_comment(VALUE obj)
02905 {
02906 VALUE str = get_gzfile(obj)->comment;
02907 if (!NIL_P(str)) {
02908 str = rb_str_dup(str);
02909 }
02910 OBJ_TAINT(str);
02911 return str;
02912 }
02913
02914
02915
02916
02917
02918
02919 static VALUE
02920 rb_gzfile_lineno(VALUE obj)
02921 {
02922 return INT2NUM(get_gzfile(obj)->lineno);
02923 }
02924
02925
02926
02927
02928
02929
02930 static VALUE
02931 rb_gzfile_set_lineno(VALUE obj, VALUE lineno)
02932 {
02933 struct gzfile *gz = get_gzfile(obj);
02934 gz->lineno = NUM2INT(lineno);
02935 return lineno;
02936 }
02937
02938
02939
02940
02941
02942
02943
02944 static VALUE
02945 rb_gzfile_set_mtime(VALUE obj, VALUE mtime)
02946 {
02947 struct gzfile *gz = get_gzfile(obj);
02948 VALUE val;
02949
02950 if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
02951 rb_raise(cGzError, "header is already written");
02952 }
02953
02954 if (FIXNUM_P(mtime)) {
02955 gz->mtime = FIX2INT(mtime);
02956 }
02957 else {
02958 val = rb_Integer(mtime);
02959 gz->mtime = FIXNUM_P(val) ? FIX2UINT(val) : rb_big2ulong(val);
02960 }
02961 return mtime;
02962 }
02963
02964
02965
02966
02967
02968
02969 static VALUE
02970 rb_gzfile_set_orig_name(VALUE obj, VALUE str)
02971 {
02972 struct gzfile *gz = get_gzfile(obj);
02973 VALUE s;
02974 char *p;
02975
02976 if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
02977 rb_raise(cGzError, "header is already written");
02978 }
02979 s = rb_str_dup(rb_str_to_str(str));
02980 p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
02981 if (p) {
02982 rb_str_resize(s, p - RSTRING_PTR(s));
02983 }
02984 gz->orig_name = s;
02985 return str;
02986 }
02987
02988
02989
02990
02991
02992
02993 static VALUE
02994 rb_gzfile_set_comment(VALUE obj, VALUE str)
02995 {
02996 struct gzfile *gz = get_gzfile(obj);
02997 VALUE s;
02998 char *p;
02999
03000 if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
03001 rb_raise(cGzError, "header is already written");
03002 }
03003 s = rb_str_dup(rb_str_to_str(str));
03004 p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
03005 if (p) {
03006 rb_str_resize(s, p - RSTRING_PTR(s));
03007 }
03008 gz->comment = s;
03009 return str;
03010 }
03011
03012
03013
03014
03015
03016
03017
03018 static VALUE
03019 rb_gzfile_close(VALUE obj)
03020 {
03021 struct gzfile *gz = get_gzfile(obj);
03022 VALUE io;
03023
03024 io = gz->io;
03025 gzfile_close(gz, 1);
03026 return io;
03027 }
03028
03029
03030
03031
03032
03033
03034
03035
03036 static VALUE
03037 rb_gzfile_finish(VALUE obj)
03038 {
03039 struct gzfile *gz = get_gzfile(obj);
03040 VALUE io;
03041
03042 io = gz->io;
03043 gzfile_close(gz, 0);
03044 return io;
03045 }
03046
03047
03048
03049
03050
03051
03052
03053 static VALUE
03054 rb_gzfile_closed_p(VALUE obj)
03055 {
03056 struct gzfile *gz;
03057 Data_Get_Struct(obj, struct gzfile, gz);
03058 return NIL_P(gz->io) ? Qtrue : Qfalse;
03059 }
03060
03061
03062
03063
03064
03065
03066 static VALUE
03067 rb_gzfile_eof_p(VALUE obj)
03068 {
03069 struct gzfile *gz = get_gzfile(obj);
03070 return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
03071 }
03072
03073
03074
03075
03076
03077
03078
03079 static VALUE
03080 rb_gzfile_sync(VALUE obj)
03081 {
03082 return (get_gzfile(obj)->z.flags & GZFILE_FLAG_SYNC) ? Qtrue : Qfalse;
03083 }
03084
03085
03086
03087
03088
03089
03090
03091
03092
03093
03094 static VALUE
03095 rb_gzfile_set_sync(VALUE obj, VALUE mode)
03096 {
03097 struct gzfile *gz = get_gzfile(obj);
03098
03099 if (RTEST(mode)) {
03100 gz->z.flags |= GZFILE_FLAG_SYNC;
03101 }
03102 else {
03103 gz->z.flags &= ~GZFILE_FLAG_SYNC;
03104 }
03105 return mode;
03106 }
03107
03108
03109
03110
03111
03112
03113 static VALUE
03114 rb_gzfile_total_in(VALUE obj)
03115 {
03116 return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
03117 }
03118
03119
03120
03121
03122
03123
03124 static VALUE
03125 rb_gzfile_total_out(VALUE obj)
03126 {
03127 struct gzfile *gz = get_gzfile(obj);
03128 return rb_uint2inum(gz->z.stream.total_out - gz->z.buf_filled);
03129 }
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139 static VALUE
03140 rb_gzfile_path(VALUE obj)
03141 {
03142 struct gzfile *gz;
03143 Data_Get_Struct(obj, struct gzfile, gz);
03144 return gz->path;
03145 }
03146
03147 static void
03148 rb_gzfile_ecopts(struct gzfile *gz, VALUE opts)
03149 {
03150 if (!NIL_P(opts)) {
03151 rb_io_extract_encoding_option(opts, &gz->enc, &gz->enc2, NULL);
03152 }
03153 if (gz->enc2) {
03154 gz->ecflags = rb_econv_prepare_opts(opts, &opts);
03155 gz->ec = rb_econv_open_opts(gz->enc2->name, gz->enc->name,
03156 gz->ecflags, opts);
03157 gz->ecopts = opts;
03158 }
03159 }
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196 static VALUE
03197 rb_gzwriter_s_allocate(VALUE klass)
03198 {
03199 return gzfile_writer_new(klass);
03200 }
03201
03202
03203
03204
03205
03206
03207
03208
03209 static VALUE
03210 rb_gzwriter_s_open(int argc, VALUE *argv, VALUE klass)
03211 {
03212 return gzfile_s_open(argc, argv, klass, "wb");
03213 }
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223 static VALUE
03224 rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
03225 {
03226 struct gzfile *gz;
03227 VALUE io, level, strategy, opt = Qnil;
03228 int err;
03229
03230 if (argc > 1) {
03231 opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash");
03232 if (!NIL_P(opt)) argc--;
03233 }
03234
03235 rb_scan_args(argc, argv, "12", &io, &level, &strategy);
03236 Data_Get_Struct(obj, struct gzfile, gz);
03237
03238
03239 gz->level = ARG_LEVEL(level);
03240 err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED,
03241 -MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));
03242 if (err != Z_OK) {
03243 raise_zlib_error(err, gz->z.stream.msg);
03244 }
03245 gz->io = io;
03246 ZSTREAM_READY(&gz->z);
03247 rb_gzfile_ecopts(gz, opt);
03248
03249 if (rb_respond_to(io, id_path)) {
03250 gz->path = rb_funcall(gz->io, id_path, 0);
03251 rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
03252 }
03253
03254 return obj;
03255 }
03256
03257
03258
03259
03260
03261
03262
03263
03264 static VALUE
03265 rb_gzwriter_flush(int argc, VALUE *argv, VALUE obj)
03266 {
03267 struct gzfile *gz = get_gzfile(obj);
03268 VALUE v_flush;
03269 int flush;
03270
03271 rb_scan_args(argc, argv, "01", &v_flush);
03272
03273 flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
03274 if (flush != Z_NO_FLUSH) {
03275 zstream_run(&gz->z, (Bytef*)"", 0, flush);
03276 }
03277
03278 gzfile_write_raw(gz);
03279 if (rb_respond_to(gz->io, id_flush)) {
03280 rb_funcall(gz->io, id_flush, 0);
03281 }
03282 return obj;
03283 }
03284
03285
03286
03287
03288 static VALUE
03289 rb_gzwriter_write(VALUE obj, VALUE str)
03290 {
03291 struct gzfile *gz = get_gzfile(obj);
03292
03293 if (TYPE(str) != T_STRING)
03294 str = rb_obj_as_string(str);
03295 if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
03296 str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2);
03297 }
03298 gzfile_write(gz, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str));
03299 return INT2FIX(RSTRING_LEN(str));
03300 }
03301
03302
03303
03304
03305 static VALUE
03306 rb_gzwriter_putc(VALUE obj, VALUE ch)
03307 {
03308 struct gzfile *gz = get_gzfile(obj);
03309 char c = NUM2CHR(ch);
03310
03311 gzfile_write(gz, (Bytef*)&c, 1);
03312 return ch;
03313 }
03314
03315
03316
03317
03318
03319
03320
03321 #define rb_gzwriter_addstr rb_io_addstr
03322
03323
03324
03325
03326 #define rb_gzwriter_printf rb_io_printf
03327
03328
03329
03330
03331 #define rb_gzwriter_print rb_io_print
03332
03333
03334
03335
03336 #define rb_gzwriter_puts rb_io_puts
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393 static VALUE
03394 rb_gzreader_s_allocate(VALUE klass)
03395 {
03396 return gzfile_reader_new(klass);
03397 }
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408 static VALUE
03409 rb_gzreader_s_open(int argc, VALUE *argv, VALUE klass)
03410 {
03411 return gzfile_s_open(argc, argv, klass, "rb");
03412 }
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426 static VALUE
03427 rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj)
03428 {
03429 VALUE io, opt = Qnil;
03430 struct gzfile *gz;
03431 int err;
03432
03433 Data_Get_Struct(obj, struct gzfile, gz);
03434 rb_scan_args(argc, argv, "1:", &io, &opt);
03435
03436
03437 err = inflateInit2(&gz->z.stream, -MAX_WBITS);
03438 if (err != Z_OK) {
03439 raise_zlib_error(err, gz->z.stream.msg);
03440 }
03441 gz->io = io;
03442 ZSTREAM_READY(&gz->z);
03443 gzfile_read_header(gz);
03444 rb_gzfile_ecopts(gz, opt);
03445
03446 if (rb_respond_to(io, id_path)) {
03447 gz->path = rb_funcall(gz->io, id_path, 0);
03448 rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
03449 }
03450
03451 return obj;
03452 }
03453
03454
03455
03456
03457
03458
03459
03460 static VALUE
03461 rb_gzreader_rewind(VALUE obj)
03462 {
03463 struct gzfile *gz = get_gzfile(obj);
03464 gzfile_reader_rewind(gz);
03465 return INT2FIX(0);
03466 }
03467
03468
03469
03470
03471
03472
03473
03474 static VALUE
03475 rb_gzreader_unused(VALUE obj)
03476 {
03477 struct gzfile *gz;
03478 Data_Get_Struct(obj, struct gzfile, gz);
03479 return gzfile_reader_get_unused(gz);
03480 }
03481
03482
03483
03484
03485
03486
03487 static VALUE
03488 rb_gzreader_read(int argc, VALUE *argv, VALUE obj)
03489 {
03490 struct gzfile *gz = get_gzfile(obj);
03491 VALUE vlen;
03492 long len;
03493
03494 rb_scan_args(argc, argv, "01", &vlen);
03495 if (NIL_P(vlen)) {
03496 return gzfile_read_all(gz);
03497 }
03498
03499 len = NUM2INT(vlen);
03500 if (len < 0) {
03501 rb_raise(rb_eArgError, "negative length %ld given", len);
03502 }
03503 return gzfile_read(gz, len);
03504 }
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517
03518 static VALUE
03519 rb_gzreader_readpartial(int argc, VALUE *argv, VALUE obj)
03520 {
03521 struct gzfile *gz = get_gzfile(obj);
03522 VALUE vlen, outbuf;
03523 long len;
03524
03525 rb_scan_args(argc, argv, "11", &vlen, &outbuf);
03526
03527 len = NUM2INT(vlen);
03528 if (len < 0) {
03529 rb_raise(rb_eArgError, "negative length %ld given", len);
03530 }
03531 if (!NIL_P(outbuf))
03532 Check_Type(outbuf, T_STRING);
03533 return gzfile_readpartial(gz, len, outbuf);
03534 }
03535
03536
03537
03538
03539
03540
03541 static VALUE
03542 rb_gzreader_getc(VALUE obj)
03543 {
03544 struct gzfile *gz = get_gzfile(obj);
03545
03546 return gzfile_getc(gz);
03547 }
03548
03549
03550
03551
03552
03553
03554 static VALUE
03555 rb_gzreader_readchar(VALUE obj)
03556 {
03557 VALUE dst;
03558 dst = rb_gzreader_getc(obj);
03559 if (NIL_P(dst)) {
03560 rb_raise(rb_eEOFError, "end of file reached");
03561 }
03562 return dst;
03563 }
03564
03565
03566
03567
03568
03569
03570 static VALUE
03571 rb_gzreader_getbyte(VALUE obj)
03572 {
03573 struct gzfile *gz = get_gzfile(obj);
03574 VALUE dst;
03575
03576 dst = gzfile_read(gz, 1);
03577 if (!NIL_P(dst)) {
03578 dst = INT2FIX((unsigned int)(RSTRING_PTR(dst)[0]) & 0xff);
03579 }
03580 return dst;
03581 }
03582
03583
03584
03585
03586
03587
03588 static VALUE
03589 rb_gzreader_readbyte(VALUE obj)
03590 {
03591 VALUE dst;
03592 dst = rb_gzreader_getbyte(obj);
03593 if (NIL_P(dst)) {
03594 rb_raise(rb_eEOFError, "end of file reached");
03595 }
03596 return dst;
03597 }
03598
03599
03600
03601
03602
03603
03604 static VALUE
03605 rb_gzreader_each_char(VALUE obj)
03606 {
03607 VALUE c;
03608
03609 RETURN_ENUMERATOR(obj, 0, 0);
03610
03611 while (!NIL_P(c = rb_gzreader_getc(obj))) {
03612 rb_yield(c);
03613 }
03614 return Qnil;
03615 }
03616
03617
03618
03619
03620
03621
03622 static VALUE
03623 rb_gzreader_each_byte(VALUE obj)
03624 {
03625 VALUE c;
03626
03627 RETURN_ENUMERATOR(obj, 0, 0);
03628
03629 while (!NIL_P(c = rb_gzreader_getbyte(obj))) {
03630 rb_yield(c);
03631 }
03632 return Qnil;
03633 }
03634
03635
03636
03637
03638
03639
03640 static VALUE
03641 rb_gzreader_ungetc(VALUE obj, VALUE s)
03642 {
03643 struct gzfile *gz;
03644
03645 if (FIXNUM_P(s))
03646 return rb_gzreader_ungetbyte(obj, s);
03647 gz = get_gzfile(obj);
03648 StringValue(s);
03649 if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
03650 s = rb_str_conv_enc(s, rb_enc_get(s), gz->enc2);
03651 }
03652 gzfile_ungets(gz, (const Bytef*)RSTRING_PTR(s), RSTRING_LEN(s));
03653 return Qnil;
03654 }
03655
03656
03657
03658
03659
03660
03661 static VALUE
03662 rb_gzreader_ungetbyte(VALUE obj, VALUE ch)
03663 {
03664 struct gzfile *gz = get_gzfile(obj);
03665 gzfile_ungetbyte(gz, NUM2CHR(ch));
03666 return Qnil;
03667 }
03668
03669 static void
03670 gzreader_skip_linebreaks(struct gzfile *gz)
03671 {
03672 VALUE str;
03673 char *p;
03674 int n;
03675
03676 while (gz->z.buf_filled == 0) {
03677 if (GZFILE_IS_FINISHED(gz)) return;
03678 gzfile_read_more(gz);
03679 }
03680 n = 0;
03681 p = RSTRING_PTR(gz->z.buf);
03682
03683 while (n++, *(p++) == '\n') {
03684 if (n >= gz->z.buf_filled) {
03685 str = zstream_detach_buffer(&gz->z);
03686 gzfile_calc_crc(gz, str);
03687 while (gz->z.buf_filled == 0) {
03688 if (GZFILE_IS_FINISHED(gz)) return;
03689 gzfile_read_more(gz);
03690 }
03691 n = 0;
03692 p = RSTRING_PTR(gz->z.buf);
03693 }
03694 }
03695
03696 str = zstream_shift_buffer(&gz->z, n - 1);
03697 gzfile_calc_crc(gz, str);
03698 }
03699
03700 static void
03701 rscheck(const char *rsptr, long rslen, VALUE rs)
03702 {
03703 if (RSTRING_PTR(rs) != rsptr && RSTRING_LEN(rs) != rslen)
03704 rb_raise(rb_eRuntimeError, "rs modified");
03705 }
03706
03707 static long
03708 gzreader_charboundary(struct gzfile *gz, long n)
03709 {
03710 char *s = RSTRING_PTR(gz->z.buf);
03711 char *e = s + gz->z.buf_filled;
03712 char *p = rb_enc_left_char_head(s, s + n, e, gz->enc);
03713 long l = p - s;
03714 if (l < n) {
03715 n = rb_enc_precise_mbclen(p, e, gz->enc);
03716 if (MBCLEN_NEEDMORE_P(n)) {
03717 if ((l = gzfile_fill(gz, l + MBCLEN_NEEDMORE_LEN(n))) > 0) {
03718 return l;
03719 }
03720 }
03721 else if (MBCLEN_CHARFOUND_P(n)) {
03722 return l + MBCLEN_CHARFOUND_LEN(n);
03723 }
03724 }
03725 return n;
03726 }
03727
03728 static VALUE
03729 gzreader_gets(int argc, VALUE *argv, VALUE obj)
03730 {
03731 struct gzfile *gz = get_gzfile(obj);
03732 volatile VALUE rs;
03733 VALUE dst;
03734 const char *rsptr;
03735 char *p, *res;
03736 long rslen, n, limit = -1;
03737 int rspara;
03738 rb_encoding *enc = gz->enc;
03739 int maxlen = rb_enc_mbmaxlen(enc);
03740
03741 if (argc == 0) {
03742 rs = rb_rs;
03743 }
03744 else {
03745 VALUE lim, tmp;
03746
03747 rb_scan_args(argc, argv, "11", &rs, &lim);
03748 if (!NIL_P(lim)) {
03749 if (!NIL_P(rs)) StringValue(rs);
03750 }
03751 else if (!NIL_P(rs)) {
03752 tmp = rb_check_string_type(rs);
03753 if (NIL_P(tmp)) {
03754 lim = rs;
03755 rs = rb_rs;
03756 }
03757 else {
03758 rs = tmp;
03759 }
03760 }
03761 if (!NIL_P(lim)) {
03762 limit = NUM2LONG(lim);
03763 if (limit == 0) return rb_str_new(0,0);
03764 }
03765 }
03766
03767 if (NIL_P(rs)) {
03768 if (limit < 0) {
03769 dst = gzfile_read_all(gz);
03770 if (RSTRING_LEN(dst) == 0) return Qnil;
03771 }
03772 else if ((n = gzfile_fill(gz, limit)) <= 0) {
03773 return Qnil;
03774 }
03775 else {
03776 if (maxlen > 1 && n >= limit && !GZFILE_IS_FINISHED(gz)) {
03777 n = gzreader_charboundary(gz, n);
03778 }
03779 else {
03780 n = limit;
03781 }
03782 dst = zstream_shift_buffer(&gz->z, n);
03783 gzfile_calc_crc(gz, dst);
03784 dst = gzfile_newstr(gz, dst);
03785 }
03786 gz->lineno++;
03787 return dst;
03788 }
03789
03790 if (RSTRING_LEN(rs) == 0) {
03791 rsptr = "\n\n";
03792 rslen = 2;
03793 rspara = 1;
03794 } else {
03795 rsptr = RSTRING_PTR(rs);
03796 rslen = RSTRING_LEN(rs);
03797 rspara = 0;
03798 }
03799
03800 if (rspara) {
03801 gzreader_skip_linebreaks(gz);
03802 }
03803
03804 while (gz->z.buf_filled < rslen) {
03805 if (ZSTREAM_IS_FINISHED(&gz->z)) {
03806 if (gz->z.buf_filled > 0) gz->lineno++;
03807 return gzfile_read(gz, rslen);
03808 }
03809 gzfile_read_more(gz);
03810 }
03811
03812 p = RSTRING_PTR(gz->z.buf);
03813 n = rslen;
03814 for (;;) {
03815 long filled;
03816 if (n > gz->z.buf_filled) {
03817 if (ZSTREAM_IS_FINISHED(&gz->z)) break;
03818 gzfile_read_more(gz);
03819 p = RSTRING_PTR(gz->z.buf) + n - rslen;
03820 }
03821 if (!rspara) rscheck(rsptr, rslen, rs);
03822 filled = gz->z.buf_filled;
03823 if (limit > 0 && filled >= limit) {
03824 filled = limit;
03825 }
03826 res = memchr(p, rsptr[0], (filled - n + 1));
03827 if (!res) {
03828 n = filled;
03829 if (limit > 0 && filled >= limit) break;
03830 n++;
03831 } else {
03832 n += (long)(res - p);
03833 p = res;
03834 if (rslen == 1 || memcmp(p, rsptr, rslen) == 0) break;
03835 p++, n++;
03836 }
03837 }
03838 if (maxlen > 1 && n == limit && (gz->z.buf_filled > n || !ZSTREAM_IS_FINISHED(&gz->z))) {
03839 n = gzreader_charboundary(gz, n);
03840 }
03841
03842 gz->lineno++;
03843 dst = gzfile_read(gz, n);
03844 if (rspara) {
03845 gzreader_skip_linebreaks(gz);
03846 }
03847
03848 return gzfile_newstr(gz, dst);
03849 }
03850
03851
03852
03853
03854
03855
03856 static VALUE
03857 rb_gzreader_gets(int argc, VALUE *argv, VALUE obj)
03858 {
03859 VALUE dst;
03860 dst = gzreader_gets(argc, argv, obj);
03861 if (!NIL_P(dst)) {
03862 rb_lastline_set(dst);
03863 }
03864 return dst;
03865 }
03866
03867
03868
03869
03870
03871
03872 static VALUE
03873 rb_gzreader_readline(int argc, VALUE *argv, VALUE obj)
03874 {
03875 VALUE dst;
03876 dst = rb_gzreader_gets(argc, argv, obj);
03877 if (NIL_P(dst)) {
03878 rb_raise(rb_eEOFError, "end of file reached");
03879 }
03880 return dst;
03881 }
03882
03883
03884
03885
03886
03887
03888 static VALUE
03889 rb_gzreader_each(int argc, VALUE *argv, VALUE obj)
03890 {
03891 VALUE str;
03892
03893 RETURN_ENUMERATOR(obj, 0, 0);
03894
03895 while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
03896 rb_yield(str);
03897 }
03898 return obj;
03899 }
03900
03901
03902
03903
03904
03905
03906 static VALUE
03907 rb_gzreader_readlines(int argc, VALUE *argv, VALUE obj)
03908 {
03909 VALUE str, dst;
03910 dst = rb_ary_new();
03911 while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
03912 rb_ary_push(dst, str);
03913 }
03914 return dst;
03915 }
03916
03917 #endif
03918
03919
03920
03921
03922
03923
03924
03925
03926
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938
03939
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960
03961
03962
03963
03964
03965
03966
03967
03968
03969
03970
03971
03972
03973
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985
03986
03987
03988
03989
03990
03991
03992
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002 void
04003 Init_zlib()
04004 {
04005 VALUE mZlib, cZStream, cDeflate, cInflate;
04006 #if GZIP_SUPPORT
04007 VALUE cGzipFile, cGzipWriter, cGzipReader;
04008 #endif
04009
04010 mZlib = rb_define_module("Zlib");
04011
04012 cZError = rb_define_class_under(mZlib, "Error", rb_eStandardError);
04013 cStreamEnd = rb_define_class_under(mZlib, "StreamEnd", cZError);
04014 cNeedDict = rb_define_class_under(mZlib, "NeedDict", cZError);
04015 cDataError = rb_define_class_under(mZlib, "DataError", cZError);
04016 cStreamError = rb_define_class_under(mZlib, "StreamError", cZError);
04017 cMemError = rb_define_class_under(mZlib, "MemError", cZError);
04018 cBufError = rb_define_class_under(mZlib, "BufError", cZError);
04019 cVersionError = rb_define_class_under(mZlib, "VersionError", cZError);
04020
04021 rb_define_module_function(mZlib, "zlib_version", rb_zlib_version, 0);
04022 rb_define_module_function(mZlib, "adler32", rb_zlib_adler32, -1);
04023 rb_define_module_function(mZlib, "adler32_combine", rb_zlib_adler32_combine, 3);
04024 rb_define_module_function(mZlib, "crc32", rb_zlib_crc32, -1);
04025 rb_define_module_function(mZlib, "crc32_combine", rb_zlib_crc32_combine, 3);
04026 rb_define_module_function(mZlib, "crc_table", rb_zlib_crc_table, 0);
04027
04028
04029 rb_define_const(mZlib, "VERSION", rb_str_new2(RUBY_ZLIB_VERSION));
04030
04031 rb_define_const(mZlib, "ZLIB_VERSION", rb_str_new2(ZLIB_VERSION));
04032
04033 cZStream = rb_define_class_under(mZlib, "ZStream", rb_cObject);
04034 rb_undef_alloc_func(cZStream);
04035 rb_define_method(cZStream, "avail_out", rb_zstream_avail_out, 0);
04036 rb_define_method(cZStream, "avail_out=", rb_zstream_set_avail_out, 1);
04037 rb_define_method(cZStream, "avail_in", rb_zstream_avail_in, 0);
04038 rb_define_method(cZStream, "total_in", rb_zstream_total_in, 0);
04039 rb_define_method(cZStream, "total_out", rb_zstream_total_out, 0);
04040 rb_define_method(cZStream, "data_type", rb_zstream_data_type, 0);
04041 rb_define_method(cZStream, "adler", rb_zstream_adler, 0);
04042 rb_define_method(cZStream, "finished?", rb_zstream_finished_p, 0);
04043 rb_define_method(cZStream, "stream_end?", rb_zstream_finished_p, 0);
04044 rb_define_method(cZStream, "closed?", rb_zstream_closed_p, 0);
04045 rb_define_method(cZStream, "ended?", rb_zstream_closed_p, 0);
04046 rb_define_method(cZStream, "close", rb_zstream_end, 0);
04047 rb_define_method(cZStream, "end", rb_zstream_end, 0);
04048 rb_define_method(cZStream, "reset", rb_zstream_reset, 0);
04049 rb_define_method(cZStream, "finish", rb_zstream_finish, 0);
04050 rb_define_method(cZStream, "flush_next_in", rb_zstream_flush_next_in, 0);
04051 rb_define_method(cZStream, "flush_next_out", rb_zstream_flush_next_out, 0);
04052
04053
04054
04055 rb_define_const(mZlib, "BINARY", INT2FIX(Z_BINARY));
04056
04057
04058 rb_define_const(mZlib, "ASCII", INT2FIX(Z_ASCII));
04059
04060
04061 rb_define_const(mZlib, "UNKNOWN", INT2FIX(Z_UNKNOWN));
04062
04063 cDeflate = rb_define_class_under(mZlib, "Deflate", cZStream);
04064 rb_define_singleton_method(cDeflate, "deflate", rb_deflate_s_deflate, -1);
04065 rb_define_singleton_method(mZlib, "deflate", rb_deflate_s_deflate, -1);
04066 rb_define_alloc_func(cDeflate, rb_deflate_s_allocate);
04067 rb_define_method(cDeflate, "initialize", rb_deflate_initialize, -1);
04068 rb_define_method(cDeflate, "initialize_copy", rb_deflate_init_copy, 1);
04069 rb_define_method(cDeflate, "deflate", rb_deflate_deflate, -1);
04070 rb_define_method(cDeflate, "<<", rb_deflate_addstr, 1);
04071 rb_define_method(cDeflate, "flush", rb_deflate_flush, -1);
04072 rb_define_method(cDeflate, "params", rb_deflate_params, 2);
04073 rb_define_method(cDeflate, "set_dictionary", rb_deflate_set_dictionary, 1);
04074
04075 cInflate = rb_define_class_under(mZlib, "Inflate", cZStream);
04076 rb_define_singleton_method(cInflate, "inflate", rb_inflate_s_inflate, 1);
04077 rb_define_singleton_method(mZlib, "inflate", rb_inflate_s_inflate, 1);
04078 rb_define_alloc_func(cInflate, rb_inflate_s_allocate);
04079 rb_define_method(cInflate, "initialize", rb_inflate_initialize, -1);
04080 rb_define_method(cInflate, "inflate", rb_inflate_inflate, 1);
04081 rb_define_method(cInflate, "<<", rb_inflate_addstr, 1);
04082 rb_define_method(cInflate, "sync", rb_inflate_sync, 1);
04083 rb_define_method(cInflate, "sync_point?", rb_inflate_sync_point_p, 0);
04084 rb_define_method(cInflate, "set_dictionary", rb_inflate_set_dictionary, 1);
04085
04086
04087
04088
04089 rb_define_const(mZlib, "NO_COMPRESSION", INT2FIX(Z_NO_COMPRESSION));
04090
04091
04092
04093 rb_define_const(mZlib, "BEST_SPEED", INT2FIX(Z_BEST_SPEED));
04094
04095
04096
04097 rb_define_const(mZlib, "BEST_COMPRESSION", INT2FIX(Z_BEST_COMPRESSION));
04098
04099
04100
04101 rb_define_const(mZlib, "DEFAULT_COMPRESSION",
04102 INT2FIX(Z_DEFAULT_COMPRESSION));
04103
04104
04105
04106
04107 rb_define_const(mZlib, "FILTERED", INT2FIX(Z_FILTERED));
04108
04109
04110
04111 rb_define_const(mZlib, "HUFFMAN_ONLY", INT2FIX(Z_HUFFMAN_ONLY));
04112
04113
04114
04115 rb_define_const(mZlib, "DEFAULT_STRATEGY", INT2FIX(Z_DEFAULT_STRATEGY));
04116
04117
04118
04119
04120 rb_define_const(mZlib, "MAX_WBITS", INT2FIX(MAX_WBITS));
04121
04122
04123
04124
04125 rb_define_const(mZlib, "DEF_MEM_LEVEL", INT2FIX(DEF_MEM_LEVEL));
04126
04127
04128
04129
04130 rb_define_const(mZlib, "MAX_MEM_LEVEL", INT2FIX(MAX_MEM_LEVEL));
04131
04132
04133
04134
04135
04136 rb_define_const(mZlib, "NO_FLUSH", INT2FIX(Z_NO_FLUSH));
04137
04138
04139
04140
04141 rb_define_const(mZlib, "SYNC_FLUSH", INT2FIX(Z_SYNC_FLUSH));
04142
04143
04144
04145
04146 rb_define_const(mZlib, "FULL_FLUSH", INT2FIX(Z_FULL_FLUSH));
04147
04148
04149
04150
04151 rb_define_const(mZlib, "FINISH", INT2FIX(Z_FINISH));
04152
04153 #if GZIP_SUPPORT
04154 id_write = rb_intern("write");
04155 id_read = rb_intern("read");
04156 id_readpartial = rb_intern("readpartial");
04157 id_flush = rb_intern("flush");
04158 id_seek = rb_intern("seek");
04159 id_close = rb_intern("close");
04160 id_path = rb_intern("path");
04161 id_input = rb_intern("@input");
04162
04163 cGzipFile = rb_define_class_under(mZlib, "GzipFile", rb_cObject);
04164 cGzError = rb_define_class_under(cGzipFile, "Error", cZError);
04165
04166
04167 rb_define_attr(cGzError, "input", 1, 0);
04168 rb_define_method(cGzError, "inspect", gzfile_error_inspect, 0);
04169
04170 cNoFooter = rb_define_class_under(cGzipFile, "NoFooter", cGzError);
04171 cCRCError = rb_define_class_under(cGzipFile, "CRCError", cGzError);
04172 cLengthError = rb_define_class_under(cGzipFile,"LengthError",cGzError);
04173
04174 cGzipWriter = rb_define_class_under(mZlib, "GzipWriter", cGzipFile);
04175 cGzipReader = rb_define_class_under(mZlib, "GzipReader", cGzipFile);
04176 rb_include_module(cGzipReader, rb_mEnumerable);
04177
04178 rb_define_singleton_method(cGzipFile, "wrap", rb_gzfile_s_wrap, -1);
04179 rb_undef_alloc_func(cGzipFile);
04180 rb_define_method(cGzipFile, "to_io", rb_gzfile_to_io, 0);
04181 rb_define_method(cGzipFile, "crc", rb_gzfile_crc, 0);
04182 rb_define_method(cGzipFile, "mtime", rb_gzfile_mtime, 0);
04183 rb_define_method(cGzipFile, "level", rb_gzfile_level, 0);
04184 rb_define_method(cGzipFile, "os_code", rb_gzfile_os_code, 0);
04185 rb_define_method(cGzipFile, "orig_name", rb_gzfile_orig_name, 0);
04186 rb_define_method(cGzipFile, "comment", rb_gzfile_comment, 0);
04187 rb_define_method(cGzipReader, "lineno", rb_gzfile_lineno, 0);
04188 rb_define_method(cGzipReader, "lineno=", rb_gzfile_set_lineno, 1);
04189 rb_define_method(cGzipWriter, "mtime=", rb_gzfile_set_mtime, 1);
04190 rb_define_method(cGzipWriter, "orig_name=", rb_gzfile_set_orig_name,1);
04191 rb_define_method(cGzipWriter, "comment=", rb_gzfile_set_comment, 1);
04192 rb_define_method(cGzipFile, "close", rb_gzfile_close, 0);
04193 rb_define_method(cGzipFile, "finish", rb_gzfile_finish, 0);
04194 rb_define_method(cGzipFile, "closed?", rb_gzfile_closed_p, 0);
04195 rb_define_method(cGzipReader, "eof", rb_gzfile_eof_p, 0);
04196 rb_define_method(cGzipReader, "eof?", rb_gzfile_eof_p, 0);
04197 rb_define_method(cGzipFile, "sync", rb_gzfile_sync, 0);
04198 rb_define_method(cGzipFile, "sync=", rb_gzfile_set_sync, 1);
04199 rb_define_method(cGzipReader, "pos", rb_gzfile_total_out, 0);
04200 rb_define_method(cGzipWriter, "pos", rb_gzfile_total_in, 0);
04201 rb_define_method(cGzipReader, "tell", rb_gzfile_total_out, 0);
04202 rb_define_method(cGzipWriter, "tell", rb_gzfile_total_in, 0);
04203
04204 rb_define_singleton_method(cGzipWriter, "open", rb_gzwriter_s_open,-1);
04205 rb_define_alloc_func(cGzipWriter, rb_gzwriter_s_allocate);
04206 rb_define_method(cGzipWriter, "initialize", rb_gzwriter_initialize,-1);
04207 rb_define_method(cGzipWriter, "flush", rb_gzwriter_flush, -1);
04208 rb_define_method(cGzipWriter, "write", rb_gzwriter_write, 1);
04209 rb_define_method(cGzipWriter, "putc", rb_gzwriter_putc, 1);
04210 rb_define_method(cGzipWriter, "<<", rb_gzwriter_addstr, 1);
04211 rb_define_method(cGzipWriter, "printf", rb_gzwriter_printf, -1);
04212 rb_define_method(cGzipWriter, "print", rb_gzwriter_print, -1);
04213 rb_define_method(cGzipWriter, "puts", rb_gzwriter_puts, -1);
04214
04215 rb_define_singleton_method(cGzipReader, "open", rb_gzreader_s_open,-1);
04216 rb_define_alloc_func(cGzipReader, rb_gzreader_s_allocate);
04217 rb_define_method(cGzipReader, "initialize", rb_gzreader_initialize, -1);
04218 rb_define_method(cGzipReader, "rewind", rb_gzreader_rewind, 0);
04219 rb_define_method(cGzipReader, "unused", rb_gzreader_unused, 0);
04220 rb_define_method(cGzipReader, "read", rb_gzreader_read, -1);
04221 rb_define_method(cGzipReader, "readpartial", rb_gzreader_readpartial, -1);
04222 rb_define_method(cGzipReader, "getc", rb_gzreader_getc, 0);
04223 rb_define_method(cGzipReader, "getbyte", rb_gzreader_getbyte, 0);
04224 rb_define_method(cGzipReader, "readchar", rb_gzreader_readchar, 0);
04225 rb_define_method(cGzipReader, "readbyte", rb_gzreader_readbyte, 0);
04226 rb_define_method(cGzipReader, "each_byte", rb_gzreader_each_byte, 0);
04227 rb_define_method(cGzipReader, "each_char", rb_gzreader_each_char, 0);
04228 rb_define_method(cGzipReader, "bytes", rb_gzreader_each_byte, 0);
04229 rb_define_method(cGzipReader, "ungetc", rb_gzreader_ungetc, 1);
04230 rb_define_method(cGzipReader, "ungetbyte", rb_gzreader_ungetbyte, 1);
04231 rb_define_method(cGzipReader, "gets", rb_gzreader_gets, -1);
04232 rb_define_method(cGzipReader, "readline", rb_gzreader_readline, -1);
04233 rb_define_method(cGzipReader, "each", rb_gzreader_each, -1);
04234 rb_define_method(cGzipReader, "each_line", rb_gzreader_each, -1);
04235 rb_define_method(cGzipReader, "lines", rb_gzreader_each, -1);
04236 rb_define_method(cGzipReader, "readlines", rb_gzreader_readlines, -1);
04237
04238
04239 rb_define_const(mZlib, "OS_CODE", INT2FIX(OS_CODE));
04240
04241 rb_define_const(mZlib, "OS_MSDOS", INT2FIX(OS_MSDOS));
04242
04243 rb_define_const(mZlib, "OS_AMIGA", INT2FIX(OS_AMIGA));
04244
04245 rb_define_const(mZlib, "OS_VMS", INT2FIX(OS_VMS));
04246
04247 rb_define_const(mZlib, "OS_UNIX", INT2FIX(OS_UNIX));
04248
04249 rb_define_const(mZlib, "OS_ATARI", INT2FIX(OS_ATARI));
04250
04251 rb_define_const(mZlib, "OS_OS2", INT2FIX(OS_OS2));
04252
04253 rb_define_const(mZlib, "OS_MACOS", INT2FIX(OS_MACOS));
04254
04255 rb_define_const(mZlib, "OS_TOPS20", INT2FIX(OS_TOPS20));
04256
04257 rb_define_const(mZlib, "OS_WIN32", INT2FIX(OS_WIN32));
04258
04259
04260 rb_define_const(mZlib, "OS_VMCMS", INT2FIX(OS_VMCMS));
04261
04262 rb_define_const(mZlib, "OS_ZSYSTEM", INT2FIX(OS_ZSYSTEM));
04263
04264 rb_define_const(mZlib, "OS_CPM", INT2FIX(OS_CPM));
04265
04266 rb_define_const(mZlib, "OS_QDOS", INT2FIX(OS_QDOS));
04267
04268 rb_define_const(mZlib, "OS_RISCOS", INT2FIX(OS_RISCOS));
04269
04270 rb_define_const(mZlib, "OS_UNKNOWN", INT2FIX(OS_UNKNOWN));
04271
04272 #endif
04273 }
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287
04288
04289
04290
04291
04292
04293
04294
04295
04296
04297
04298
04299
04300
04301
04302
04303
04304
04305
04306
04307
04308
04309
04310
04311
04312
04313
04314
04315
04316
04317
04318
04319
04320
04321
04322
04323
04324
04325
04326
04327
04328
04329
04330
04331
04332
04333
04334
04335
04336
04337
04338
04339
04340
04341
04342
04343
04344
04345
04346
04347
04348
04349
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364
04365
04366
04367
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382
04383
04384
04385
04386
04387
04388
04389
04390
04391
04392
04393
04394