ext/zlib/zlib.c in zlib-0.1.0 vs ext/zlib/zlib.c in zlib-1.0.0

- old
+ new

@@ -195,11 +195,11 @@ static VALUE rb_gzwriter_s_allocate(VALUE); static VALUE rb_gzwriter_s_open(int, VALUE*, VALUE); static VALUE rb_gzwriter_initialize(int, VALUE*, VALUE); static VALUE rb_gzwriter_flush(int, VALUE*, VALUE); -static VALUE rb_gzwriter_write(VALUE, VALUE); +static VALUE rb_gzwriter_write(int, VALUE*, VALUE); static VALUE rb_gzwriter_putc(VALUE, VALUE); static VALUE rb_gzreader_s_allocate(VALUE); static VALUE rb_gzreader_s_open(int, VALUE*, VALUE); static VALUE rb_gzreader_initialize(int, VALUE*, VALUE); @@ -449,11 +449,11 @@ * */ static VALUE rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2) { - return ULONG2NUM( + return ULONG2NUM( adler32_combine(NUM2ULONG(adler1), NUM2ULONG(adler2), NUM2LONG(len2))); } #else #define rb_zlib_adler32_combine rb_f_notimplement #endif @@ -487,11 +487,11 @@ * */ static VALUE rb_zlib_crc32_combine(VALUE klass, VALUE crc1, VALUE crc2, VALUE len2) { - return ULONG2NUM( + return ULONG2NUM( crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2))); } #else #define rb_zlib_crc32_combine rb_f_notimplement #endif @@ -642,11 +642,11 @@ return; } else { zstream_expand_buffer_into(z, - ZSTREAM_AVAIL_OUT_STEP_MAX - buf_filled); + ZSTREAM_AVAIL_OUT_STEP_MAX - buf_filled); } } else { zstream_expand_buffer_non_stream(z); } @@ -1379,11 +1379,11 @@ * Returns the adler-32 checksum. */ static VALUE rb_zstream_adler(VALUE obj) { - return rb_uint2inum(get_zstream(obj)->stream.adler); + return rb_uint2inum(get_zstream(obj)->stream.adler); } /* * Returns true if the stream is finished. */ @@ -2671,11 +2671,11 @@ if (RSTRING_LEN(str) <= gz->ungetc) { gz->ungetc -= RSTRING_LEN(str); } else { gz->crc = checksum_long(crc32, gz->crc, (Bytef*)RSTRING_PTR(str) + gz->ungetc, - RSTRING_LEN(str) - gz->ungetc); + RSTRING_LEN(str) - gz->ungetc); gz->ungetc = 0; } } static VALUE @@ -3564,22 +3564,27 @@ /* * Same as IO. */ static VALUE -rb_gzwriter_write(VALUE obj, VALUE str) +rb_gzwriter_write(int argc, VALUE *argv, VALUE obj) { struct gzfile *gz = get_gzfile(obj); + size_t total = 0; - if (!RB_TYPE_P(str, T_STRING)) - str = rb_obj_as_string(str); - if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) { - str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2); + while (argc-- > 0) { + VALUE str = *argv++; + if (!RB_TYPE_P(str, T_STRING)) + str = rb_obj_as_string(str); + if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) { + str = rb_str_conv_enc(str, rb_enc_get(str), gz->enc2); + } + gzfile_write(gz, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str)); + total += RSTRING_LEN(str); + RB_GC_GUARD(str); } - gzfile_write(gz, (Bytef*)RSTRING_PTR(str), RSTRING_LEN(str)); - RB_GC_GUARD(str); - return INT2FIX(RSTRING_LEN(str)); + return SIZET2NUM(total); } /* * Same as IO. */ @@ -4243,10 +4248,18 @@ rb_gzreader_external_encoding(VALUE self) { return rb_enc_from_encoding(get_gzfile(self)->enc); } +static VALUE +zlib_gzip_ensure(VALUE arg) +{ + struct gzfile *gz = (struct gzfile *)arg; + rb_rescue((VALUE(*)())gz->end, arg, NULL, Qnil); + return Qnil; +} + static void zlib_gzip_end(struct gzfile *gz) { gz->z.flags |= ZSTREAM_FLAG_CLOSING; zstream_run(&gz->z, (Bytef*)"", 0, Z_FINISH); @@ -4255,10 +4268,11 @@ } #define OPTHASH_GIVEN_P(opts) \ (argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1)) static ID id_level, id_strategy; +static VALUE zlib_gzip_run(VALUE arg); /* * call-seq: * Zlib.gzip(src, level: nil, strategy: nil) -> String * @@ -4283,13 +4297,12 @@ static VALUE zlib_s_gzip(int argc, VALUE *argv, VALUE klass) { struct gzfile gz0; struct gzfile *gz = &gz0; - long len; int err; - VALUE src, opts, level=Qnil, strategy=Qnil; + VALUE src, opts, level=Qnil, strategy=Qnil, args[2]; if (OPTHASH_GIVEN_P(opts)) { ID keyword_ids[2]; VALUE kwargs[2]; keyword_ids[0] = id_level; @@ -4307,13 +4320,27 @@ gzfile_init(gz, &deflate_funcs, zlib_gzip_end); gz->level = ARG_LEVEL(level); err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy)); if (err != Z_OK) { + zlib_gzip_end(gz); raise_zlib_error(err, gz->z.stream.msg); } ZSTREAM_READY(&gz->z); + args[0] = (VALUE)gz; + args[1] = src; + return rb_ensure(zlib_gzip_run, (VALUE)args, zlib_gzip_ensure, (VALUE)gz); +} + +static VALUE +zlib_gzip_run(VALUE arg) +{ + VALUE *args = (VALUE *)arg; + struct gzfile *gz = (struct gzfile *)args[0]; + VALUE src = args[1]; + long len; + gzfile_make_header(gz); len = RSTRING_LEN(src); if (len > 0) { Bytef *ptr = (Bytef *)RSTRING_PTR(src); gz->crc = checksum_long(crc32, gz->crc, ptr, len); @@ -4325,14 +4352,15 @@ static void zlib_gunzip_end(struct gzfile *gz) { gz->z.flags |= ZSTREAM_FLAG_CLOSING; - gzfile_check_footer(gz); zstream_end(&gz->z); } +static VALUE zlib_gunzip_run(VALUE arg); + /* * call-seq: * Zlib.gunzip(src) -> String * * Decode the given gzipped +string+. @@ -4353,11 +4381,10 @@ zlib_gunzip(VALUE klass, VALUE src) { struct gzfile gz0; struct gzfile *gz = &gz0; int err; - VALUE dst; StringValue(src); gzfile_init(gz, &inflate_funcs, zlib_gunzip_end); err = inflateInit2(&gz->z.stream, -MAX_WBITS); @@ -4365,18 +4392,28 @@ raise_zlib_error(err, gz->z.stream.msg); } gz->io = Qundef; gz->z.input = src; ZSTREAM_READY(&gz->z); + return rb_ensure(zlib_gunzip_run, (VALUE)gz, zlib_gzip_ensure, (VALUE)gz); +} + +static VALUE +zlib_gunzip_run(VALUE arg) +{ + struct gzfile *gz = (struct gzfile *)arg; + VALUE dst; + gzfile_read_header(gz); dst = zstream_detach_buffer(&gz->z); gzfile_calc_crc(gz, dst); - if (!ZSTREAM_IS_FINISHED(&gz->z)) { - rb_raise(cGzError, "unexpected end of file"); - } - if (NIL_P(gz->z.input)) + if (!ZSTREAM_IS_FINISHED(&gz->z)) { + rb_raise(cGzError, "unexpected end of file"); + } + if (NIL_P(gz->z.input)) { rb_raise(cNoFooter, "footer is not found"); + } gzfile_check_footer(gz); return dst; } #endif /* GZIP_SUPPORT */ @@ -4616,10 +4653,10 @@ rb_define_singleton_method(cGzipWriter, "open", rb_gzwriter_s_open,-1); rb_define_alloc_func(cGzipWriter, rb_gzwriter_s_allocate); rb_define_method(cGzipWriter, "initialize", rb_gzwriter_initialize,-1); rb_define_method(cGzipWriter, "flush", rb_gzwriter_flush, -1); - rb_define_method(cGzipWriter, "write", rb_gzwriter_write, 1); + rb_define_method(cGzipWriter, "write", rb_gzwriter_write, -1); rb_define_method(cGzipWriter, "putc", rb_gzwriter_putc, 1); rb_define_method(cGzipWriter, "<<", rb_gzwriter_addstr, 1); rb_define_method(cGzipWriter, "printf", rb_gzwriter_printf, -1); rb_define_method(cGzipWriter, "print", rb_gzwriter_print, -1); rb_define_method(cGzipWriter, "puts", rb_gzwriter_puts, -1);