Class: Zlib::GzipWriter

Inherits:
GzipFile show all
Defined in:
zlib.c

Overview

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::GzipWriter#close etc. Otherwise, GzipWriter will be not able to write the gzip footer and will generate a broken gzip file.

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from GzipFile

#close, #closed?, #comment, #crc, #finish, #level, #mtime, #orig_name, #os_code, #sync, #sync=, #to_io, wrap

Constructor Details

#Zlib::GzipWriter.new(io, level, strategy) ⇒ Object

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.



# File 'zlib.c'

/*
 * call-seq: Zlib::GzipWriter.new(io, level, strategy)
 *
 * 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(argc, argv, obj)
    int argc;
    VALUE *argv;
    VALUE obj;
{
    struct gzfile *gz;
    VALUE io, level, strategy;
    int err;

    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);

    return obj;
}

Class Method Details

.Zlib::GzipWriter.open(filename, level = nil, strategy = nil) {|gz| ... } ⇒ Object

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 Zlib::GzipWriter.new and Zlib::GzipWriter#wrap.

Yields:

  • (gz)


# File 'zlib.c'

/*
 * call-seq: Zlib::GzipWriter.open(filename, level=nil, strategy=nil) { |gz| ... }
 *
 * 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 Zlib::GzipWriter.new and Zlib::GzipWriter#wrap.
 */
static VALUE
rb_gzwriter_s_open(argc, argv, klass)
    int argc;
    VALUE *argv;
    VALUE klass;
{
    return gzfile_s_open(argc, argv, klass, "wb");
}

Instance Method Details

#<<Object

Same as IO.

#comment=Object

???



# File 'zlib.c'

/*
 * ???
 */
static VALUE
rb_gzfile_set_comment(obj, str)
    VALUE obj, 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(s)->ptr, '\0', RSTRING(s)->len);
    if (p) {
    rb_str_resize(s, p - RSTRING(s)->ptr);
    }
    gz->comment = s;
    return str;
}

#flush(flush = nil) ⇒ Object

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.



# File 'zlib.c'

/*
 * call-seq: flush(flush=nil)
 *
 * Flushes all the internal buffers of the GzipWriter object.  The meaning of
 * +flush+ is same as in Zlib::Deflate#deflate.  <tt>Zlib::SYNC_FLUSH</tt> is used if
 * +flush+ is omitted.  It is no use giving flush <tt>Zlib::NO_FLUSH</tt>.
 */
static VALUE
rb_gzwriter_flush(argc, argv, obj)
    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, "", 0, flush);
    }

    gzfile_write_raw(gz);
    if (rb_respond_to(gz->io, id_flush)) {
    rb_funcall(gz->io, id_flush, 0);
    }
    return obj;
}

#mtime=Object

???



# File 'zlib.c'

/*
 * ???
 */
static VALUE
rb_gzfile_set_mtime(obj, mtime)
    VALUE obj, 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=Object

???



# File 'zlib.c'

/*
 * ???
 */
static VALUE
rb_gzfile_set_orig_name(obj, str)
    VALUE obj, 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(s)->ptr, '\0', RSTRING(s)->len);
    if (p) {
    rb_str_resize(s, p - RSTRING(s)->ptr);
    }
    gz->orig_name = s;
    return str;
}

#posObject

???



# File 'zlib.c'

/*
 * ???
 */
static VALUE
rb_gzfile_total_in(obj)
    VALUE obj;
{
    return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
}

Same as IO.

#printfObject

Same as IO.

#putcObject

Same as IO.



# File 'zlib.c'

/*
 * Same as IO.
 */
static VALUE
rb_gzwriter_putc(obj, ch)
    VALUE obj, ch;
{
    struct gzfile *gz = get_gzfile(obj);
    char c = NUM2CHR(ch);

    gzfile_write(gz, &c, 1);
    return ch;
}

#putsObject

Same as IO.

#tellObject

???



# File 'zlib.c'

/*
 * ???
 */
static VALUE
rb_gzfile_total_in(obj)
    VALUE obj;
{
    return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
}

#writeObject

Same as IO.



# File 'zlib.c'

/*
 * Same as IO.
 */
static VALUE
rb_gzwriter_write(obj, str)
    VALUE obj, str;
{
    struct gzfile *gz = get_gzfile(obj);

    if (TYPE(str) != T_STRING) {
    str = rb_obj_as_string(str);
    }
    gzfile_write(gz, RSTRING(str)->ptr, RSTRING(str)->len);
    return INT2FIX(RSTRING(str)->len);
}