123456789_123456789_123456789_123456789_123456789_

Class: Zlib::GzipWriter

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, GzipFile
Instance Chain:
self, GzipFile
Inherits: Zlib::GzipFile
Defined in: ext/zlib/zlib.c,
ext/zlib/zlib.c

Overview

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

Following two example generate the same result.

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

To make like gzip(1) does, run following:

orig = 'hoge.txt'
Zlib::GzipWriter.open('hoge.gz') do |gz|
  gz.mtime = File.mtime(orig)
  gz.orig_name = orig
  gz.write IO.binread(orig)
end

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

GzipFile - Inherited

.wrap

Creates a GzipReader or GzipWriter associated with io, passing in any necessary extra options, and executes the block with the newly created object just like File.open.

Instance Attribute Summary

GzipFile - Inherited

#closed?

Same as IO#closed?

#sync

Same as IO#sync

#sync=

Same as IO.

Instance Method Summary

GzipFile - Inherited

#close

Closes the GzipFile object.

#comment

Returns comments recorded in the gzip file header, or nil if the comments is not present.

#crc

Returns CRC value of the uncompressed data.

#finish

Closes the GzipFile object.

#level

Returns compression level.

#mtime

Returns last modification time recorded in the gzip file header.

#orig_name

Returns original filename recorded in the gzip file header, or nil if original filename is not present.

#os_code

Returns OS code number recorded in the gzip file header.

#to_io

Same as IO.

Constructor Details

.new(io, level = nil, strategy = nil, options = {})

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

The options hash may be used to set the encoding of the data. :external_encoding, :internal_encoding and :encoding may be set as in IO.new.

[ GitHub ]

  
# File 'ext/zlib/zlib.c', line 3681

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);
    TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, 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);

    if (rb_respond_to(io, id_path)) {
	/* File#path may raise IOError in case when a path is unavailable */
	rb_rescue2(gzfile_initialize_path_partial, obj, NULL, Qnil, rb_eIOError, (VALUE)0);
    }

    return obj;
}

Class Method Details

.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 .new and GzipFile.wrap.

[ GitHub ]

  
# File 'ext/zlib/zlib.c', line 3662

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

Instance Attribute Details

#comment=(str) (writeonly)

Specify the comment (str) in the gzip header.

[ GitHub ]

  
# File 'ext/zlib/zlib.c', line 3422

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

#mtime=(mtime) (writeonly)

Specify the modification time (mtime) in the gzip header. Using an Integer.

Setting the mtime in the gzip header does not effect the mtime of the file generated. Different utilities that expand the gzipped files may use the mtime header. For example the gunzip utility can use the -N flag which will set the resultant file’s mtime to the value in the header. By default many tools will set the mtime of the expanded file to the mtime of the gzipped file, not the mtime in the header.

If you do not set an mtime, the default value will be the time when compression started. Setting a value of 0 indicates no time stamp is available.

[ GitHub ]

  
# File 'ext/zlib/zlib.c', line 3376

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

    val = rb_Integer(mtime);
    gz->mtime = NUM2UINT(val);
    gz->z.flags |= GZFILE_FLAG_MTIME_IS_SET;

    return mtime;
}

#orig_name=(str) (writeonly)

Specify the original name (str) in the gzip header.

[ GitHub ]

  
# File 'ext/zlib/zlib.c', line 3398

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

Instance Method Details

#<<

[ GitHub ]

#flush(flush = nil)

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

[ GitHub ]

  
# File 'ext/zlib/zlib.c', line 3722

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

#pos Also known as: #tell

Total number of input bytes read so far.

[ GitHub ]

  
# File 'ext/zlib/zlib.c', line 3549

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

#printf

Same as IO.

[ GitHub ]

#putc(ch)

Same as IO.

[ GitHub ]

  
# File 'ext/zlib/zlib.c', line 3769

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

Same as IO.

[ GitHub ]

#tell

Alias for #pos.

#write(*args)

Same as IO.

[ GitHub ]

  
# File 'ext/zlib/zlib.c', line 3746

static VALUE
rb_gzwriter_write(int argc, VALUE *argv, VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    size_t total = 0;

    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);
    }
    return SIZET2NUM(total);
}