Class: Zstdlib::GzipWriter

Inherits:
GzipFile show all
Defined in:
ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c,
ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c,
ext/zstdlib_c/ruby/zlib-3.2/zstdlib.c,
ext/zstdlib_c/ruby/zlib-3.2/zstdlib.c,
ext/zstdlib_c/ruby/zlib-3.1/zstdlib.c,
ext/zstdlib_c/ruby/zlib-3.1/zstdlib.c,
ext/zstdlib_c/ruby/zlib-3.0/zstdlib.c,
ext/zstdlib_c/ruby/zlib-3.0/zstdlib.c,
ext/zstdlib_c/ruby/zlib-2.7/zstdlib.c,
ext/zstdlib_c/ruby/zlib-2.7/zstdlib.c,
ext/zstdlib_c/ruby/zlib-2.6/zstdlib.c,
ext/zstdlib_c/ruby/zlib-2.6/zstdlib.c,
ext/zstdlib_c/ruby/zlib-2.5/zstdlib.c,
ext/zstdlib_c/ruby/zlib-2.5/zstdlib.c,
ext/zstdlib_c/ruby/zlib-2.4/zstdlib.c,
ext/zstdlib_c/ruby/zlib-2.4/zstdlib.c,
ext/zstdlib_c/ruby/zlib-2.3/zstdlib.c,
ext/zstdlib_c/ruby/zlib-2.3/zstdlib.c,
ext/zstdlib_c/ruby/zlib-2.2/zstdlib.c,
ext/zstdlib_c/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.



3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3692

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

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


3673
3674
3675
3676
3677
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3673

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.



3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3436

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.



3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3733

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



3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3390

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.



3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3412

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.



3560
3561
3562
3563
3564
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3560

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.



3780
3781
3782
3783
3784
3785
3786
3787
3788
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3780

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.



3560
3561
3562
3563
3564
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3560

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

#write(str) ⇒ Object

Same as IO.



3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3757

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