In Files

  • zlib/zlib.c

Zlib::GzipWriter

Zlib::GzipWriter is a class for writing gzipped files. GzipWriter should be used with an instance of IO, or IO-like, object.

For example:

Zlib::GzipWriter.open('hoge.gz') do |gz|
  gz.write 'jugemu jugemu gokou no surikire...'
end

File.open('hoge.gz', 'w') do |f|
  gz = Zlib::GzipWriter.new(f)
  gz.write 'jugemu jugemu gokou no surikire...'
  gz.close
end

# TODO: test these.  Are they equivalent?  Can GzipWriter.new take a
# block?

NOTE: Due to the limitation of Ruby's finalizer, you must explicitly close GzipWriter objects by Zlib::GzipFile#close etc. Otherwise, GzipWriter will be not able to write the gzip footer and will generate a broken gzip file.

Public Class Methods

Zlib::GzipWriter.new(io, level, strategy) click to toggle source

Creates a GzipWriter object associated with io. level and strategy should be the same as the arguments of Zlib::Deflate.new. The GzipWriter object writes gzipped data to io. At least, io must respond to the write method that behaves same as write method in IO class.

 
               static VALUE
rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj)
{
    struct gzfile *gz;
    VALUE io, level, strategy, opt = Qnil;
    int err;

    if (argc > 1) {
        opt = rb_check_convert_type(argv[argc-1], T_HASH, "Hash", "to_hash");
        if (!NIL_P(opt)) argc--;
    }
    
    rb_scan_args(argc, argv, "12", &io, &level, &strategy);
    Data_Get_Struct(obj, struct gzfile, gz);

    /* this is undocumented feature of zlib */
    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) {
        raise_zlib_error(err, gz->z.stream.msg);
    }
    gz->io = io;
    ZSTREAM_READY(&gz->z);
    rb_gzfile_ecopts(gz, opt);

    return obj;
}
            
Zlib::GzipWriter.open(filename, level=nil, strategy=nil) { |gz| ... } click to toggle source

Opens a file specified by filename for writing gzip compressed data, and returns a GzipWriter object associated with that file. Further details of this method are found in ::new and Zlib::GzipWriter#wrap.

 
               static VALUE
rb_gzwriter_s_open(int argc, VALUE *argv, VALUE klass)
{
    return gzfile_s_open(argc, argv, klass, "wb");
}
            

Public Instance Methods

<<(p1) click to toggle source

Document-method: << Same as IO.

 
               #define rb_gzwriter_addstr  rb_io_addstr
            
comment=(p1) click to toggle source

???

 
               static VALUE
rb_gzfile_set_comment(VALUE obj, VALUE str)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE s;
    char *p;

    if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
        rb_raise(cGzError, "header is already written");
    }
    s = rb_str_dup(rb_str_to_str(str));
    p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
    if (p) {
        rb_str_resize(s, p - RSTRING_PTR(s));
    }
    gz->comment = s;
    return str;
}
            
flush(flush=nil) click to toggle source

Flushes all the internal buffers of the GzipWriter object. The meaning of flush is same as in Zlib::Deflate#deflate. Zlib::SYNC_FLUSH is used if flush is omitted. It is no use giving flush Zlib::NO_FLUSH.

 
               static VALUE
rb_gzwriter_flush(int argc, VALUE *argv, VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE v_flush;
    int flush;

    rb_scan_args(argc, argv, "01", &v_flush);

    flush = FIXNUMARG(v_flush, Z_SYNC_FLUSH);
    if (flush != Z_NO_FLUSH) {  /* prevent Z_BUF_ERROR */
        zstream_run(&gz->z, (Bytef*)"", 0, flush);
    }

    gzfile_write_raw(gz);
    if (rb_respond_to(gz->io, id_flush)) {
        rb_funcall(gz->io, id_flush, 0);
    }
    return obj;
}
            
mtime=(p1) click to toggle source

???

 
               static VALUE
rb_gzfile_set_mtime(VALUE obj, VALUE mtime)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE val;

    if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
        rb_raise(cGzError, "header is already written");
    }

    if (FIXNUM_P(mtime)) {
        gz->mtime = FIX2INT(mtime);
    }
    else {
        val = rb_Integer(mtime);
        gz->mtime = FIXNUM_P(val) ? FIX2INT(val) : rb_big2ulong(val);
    }
    return mtime;
}
            
orig_name=(p1) click to toggle source

???

 
               static VALUE
rb_gzfile_set_orig_name(VALUE obj, VALUE str)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE s;
    char *p;

    if (gz->z.flags & GZFILE_FLAG_HEADER_FINISHED) {
        rb_raise(cGzError, "header is already written");
    }
    s = rb_str_dup(rb_str_to_str(str));
    p = memchr(RSTRING_PTR(s), '\0', RSTRING_LEN(s));
    if (p) {
        rb_str_resize(s, p - RSTRING_PTR(s));
    }
    gz->orig_name = s;
    return str;
}
            
pos() click to toggle source

???

 
               static VALUE
rb_gzfile_total_in(VALUE obj)
{
    return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
}
            
printf(*args) click to toggle source

Same as IO.

 
               #define rb_gzwriter_printf  rb_io_printf
            
putc(p1) click to toggle source

Same as IO.

 
               static VALUE
rb_gzwriter_putc(VALUE obj, VALUE ch)
{
    struct gzfile *gz = get_gzfile(obj);
    char c = NUM2CHR(ch);

    gzfile_write(gz, (Bytef*)&c, 1);
    return ch;
}
            
puts(*args) click to toggle source

Same as IO.

 
               #define rb_gzwriter_puts  rb_io_puts
            
tell() click to toggle source

???

 
               static VALUE
rb_gzfile_total_in(VALUE obj)
{
    return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
}
            
write(p1) click to toggle source

Same as IO.

 
               static VALUE
rb_gzwriter_write(VALUE obj, VALUE str)
{
    struct gzfile *gz = get_gzfile(obj);

    if (TYPE(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));
    return INT2FIX(RSTRING_LEN(str));
}
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.

blog comments powered by Disqus