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