Class: Zstdlib::GzipWriter

Inherits:
GzipFile show all
Defined in:
ext/zstdlib/ruby/zlib-2.7/zstdlib.c,
ext/zstdlib/ruby/zlib-2.7/zstdlib.c,
ext/zstdlib/ruby/zlib-2.6/zstdlib.c,
ext/zstdlib/ruby/zlib-2.6/zstdlib.c,
ext/zstdlib/ruby/zlib-2.5/zstdlib.c,
ext/zstdlib/ruby/zlib-2.5/zstdlib.c,
ext/zstdlib/ruby/zlib-2.4/zstdlib.c,
ext/zstdlib/ruby/zlib-2.4/zstdlib.c,
ext/zstdlib/ruby/zlib-2.3/zstdlib.c,
ext/zstdlib/ruby/zlib-2.3/zstdlib.c,
ext/zstdlib/ruby/zlib-2.2/zstdlib.c,
ext/zstdlib/ruby/zlib-2.2/zstdlib.c

Overview

Zstdlib::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.

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

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

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

orig = 'hoge.txt' Zstdlib::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 Zstdlib::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

#Zstdlib::GzipWriter.new(io, level = nil, strategy = nil, options = {}) ⇒ Object

Creates a GzipWriter object associated with +io+. +level+ and +strategy+ should be the same as the arguments of Zstdlib::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.



3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
# File 'ext/zstdlib/ruby/zlib-2.7/zstdlib.c', line 3543

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)) {
	gz->path = rb_funcall(gz->io, id_path, 0);
	rb_define_singleton_method(obj, "path", rb_gzfile_path, 0);
    }

    return obj;
}

Class Method Details

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

Yields:

  • (gz)


3524
3525
3526
3527
3528
# File 'ext/zstdlib/ruby/zlib-2.7/zstdlib.c', line 3524

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

Instance Method Details

#<<Object

Same as IO.

#comment=(str) ⇒ Object

Specify the comment (+str+) in the gzip header.



3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
# File 'ext/zstdlib/ruby/zlib-2.7/zstdlib.c', line 3297

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) ⇒ Object

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



3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
# File 'ext/zstdlib/ruby/zlib-2.7/zstdlib.c', line 3584

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=(mtime) ⇒ Object

Specify the modification time (+mtime+) in the gzip header. Using a Fixnum or Integer



3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
# File 'ext/zstdlib/ruby/zlib-2.7/zstdlib.c', line 3251

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) ⇒ Object

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



3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
# File 'ext/zstdlib/ruby/zlib-2.7/zstdlib.c', line 3273

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

#posObject

Total number of input bytes read so far.



3421
3422
3423
3424
3425
# File 'ext/zstdlib/ruby/zlib-2.7/zstdlib.c', line 3421

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

Same as IO.

#printfObject

Same as IO.

#putc(ch) ⇒ Object

Same as IO.



3631
3632
3633
3634
3635
3636
3637
3638
3639
# File 'ext/zstdlib/ruby/zlib-2.7/zstdlib.c', line 3631

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

#putsObject

Same as IO.

#tellObject

Total number of input bytes read so far.



3421
3422
3423
3424
3425
# File 'ext/zstdlib/ruby/zlib-2.7/zstdlib.c', line 3421

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

#write(str) ⇒ Object

Same as IO.



3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
# File 'ext/zstdlib/ruby/zlib-2.7/zstdlib.c', line 3608

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