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