Class: Zstdlib::GzipWriter

Inherits:
GzipFile show all
Defined in:
ext/zstdlib/ruby/zlib-3.0/zstdlib.c,
ext/zstdlib/ruby/zlib-3.0/zstdlib.c,
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.



3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
# File 'ext/zstdlib/ruby/zlib-3.0/zstdlib.c', line 3612

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)


3593
3594
3595
3596
3597
# File 'ext/zstdlib/ruby/zlib-3.0/zstdlib.c', line 3593

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.



3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
# File 'ext/zstdlib/ruby/zlib-3.0/zstdlib.c', line 3366

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.



3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
# File 'ext/zstdlib/ruby/zlib-3.0/zstdlib.c', line 3653

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



3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
# File 'ext/zstdlib/ruby/zlib-3.0/zstdlib.c', line 3320

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.



3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
# File 'ext/zstdlib/ruby/zlib-3.0/zstdlib.c', line 3342

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.



3490
3491
3492
3493
3494
# File 'ext/zstdlib/ruby/zlib-3.0/zstdlib.c', line 3490

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.



3700
3701
3702
3703
3704
3705
3706
3707
3708
# File 'ext/zstdlib/ruby/zlib-3.0/zstdlib.c', line 3700

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.



3490
3491
3492
3493
3494
# File 'ext/zstdlib/ruby/zlib-3.0/zstdlib.c', line 3490

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

#write(str) ⇒ Object

Same as IO.



3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
# File 'ext/zstdlib/ruby/zlib-3.0/zstdlib.c', line 3677

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