Class: Zstdlib::GzipReader

Inherits:
GzipFile show all
Includes:
Enumerable
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::GzipReader is the class for reading a gzipped file. GzipReader should be used an IO, or -IO-like, object.

Zstdlib::GzipReader.open('hoge.gz') {|gz| print gz.read }

File.open('hoge.gz') do |f| gz = Zstdlib::GzipReader.new(f) print gz.read gz.close end

== Method Catalogue

The following methods in Zstdlib::GzipReader are just like their counterparts in IO, but they raise Zstdlib::Error or Zstdlib::GzipFile::Error exception if an error was found in the gzip file.

  • #each
  • #each_line
  • #each_byte
  • #gets
  • #getc
  • #lineno
  • #lineno=
  • #read
  • #readchar
  • #readline
  • #readlines
  • #ungetc

Be careful of the footer of the gzip file. A gzip file has the checksum of pre-compressed data in its footer. GzipReader checks all uncompressed data against that checksum at the following cases, and if it fails, raises Zstdlib::GzipFile::NoFooter, Zstdlib::GzipFile::CRCError, or Zstdlib::GzipFile::LengthError exception.

  • When an reading request is received beyond the end of file (the end of compressed data). That is, when Zstdlib::GzipReader#read, Zstdlib::GzipReader#gets, or some other methods for reading returns nil.
  • When Zstdlib::GzipFile#close method is called after the object reaches the end of file.
  • When Zstdlib::GzipReader#unused method is called after the object reaches the end of file.

The rest of the methods are adequately described in their own documentation.

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

#initialize(*args) ⇒ Object

call-seq: Zstdlib::GzipReader.new(io, options = {})

Creates a GzipReader object associated with +io+. The GzipReader object reads gzipped data from +io+, and parses/decompresses it. The +io+ must have a +read+ method that behaves same as the IO#read.

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.

If the gzip file header is incorrect, raises an Zstdlib::GzipFile::Error exception.



3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3960

static VALUE
rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj)
{
    VALUE io, opt = Qnil;
    struct gzfile *gz;
    int err;

    TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
    rb_scan_args(argc, argv, "1:", &io, &opt);

    /* this is undocumented feature of zlib */
    err = inflateInit2(&gz->z.stream, -MAX_WBITS);
    if (err != Z_OK) {
	raise_zlib_error(err, gz->z.stream.msg);
    }
    gz->io = io;
    ZSTREAM_READY(&gz->z);
    gzfile_read_header(gz, Qnil);
    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(*args) ⇒ Object

call-seq: Zstdlib::GzipReader.open(filename) {|gz| ... }

Opens a file specified by +filename+ as a gzipped file, and returns a GzipReader object associated with that file. Further details of this method are in Zstdlib::GzipReader.new and ZLib::GzipFile.wrap.



3883
3884
3885
3886
3887
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3883

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

.zcat(*args) ⇒ Object

call-seq: Zstdlib::GzipReader.zcat(io, options = {}, &block) => nil Zstdlib::GzipReader.zcat(io, options = {}) => string

Decompresses all gzip data in the +io+, handling multiple gzip streams until the end of the +io+. There should not be any non-gzip data after the gzip streams.

If a block is given, it is yielded strings of uncompressed data, and the method returns +nil+. If a block is not given, the method returns the concatenation of all uncompressed data in all gzip streams.



3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3905

static VALUE
rb_gzreader_s_zcat(int argc, VALUE *argv, VALUE klass)
{
    VALUE io, unused, obj, buf=0, tmpbuf;
    long pos;

    rb_check_arity(argc, 1, 2);
    io = argv[0];

    do {
        obj = rb_funcallv(klass, rb_intern("new"), argc, argv);
        if (rb_block_given_p()) {
           rb_gzreader_each(0, 0, obj);
        }
        else {
            if (!buf) {
                buf = rb_str_new(0, 0);
            }
            tmpbuf = gzfile_read_all(get_gzfile(obj));
            rb_str_cat(buf, RSTRING_PTR(tmpbuf), RSTRING_LEN(tmpbuf));
        }

        rb_gzreader_read(0, 0, obj);
        pos = NUM2LONG(rb_funcall(io, rb_intern("pos"), 0));
        unused = rb_gzreader_unused(obj);
        rb_gzfile_finish(obj);
        if (!NIL_P(unused)) {
            pos -= NUM2LONG(rb_funcall(unused, rb_intern("length"), 0));
            rb_funcall(io, rb_intern("pos="), 1, LONG2NUM(pos));
        }
    } while (pos < NUM2LONG(rb_funcall(io, rb_intern("size"), 0)));

    if (rb_block_given_p()) {
        return Qnil;
    }
    return buf;
}

Instance Method Details

#bytesObject

This is a deprecated alias for each_byte.



3971
3972
3973
3974
3975
3976
3977
3978
# File 'ext/zstdlib_c/ruby/zlib-2.7/zstdlib.c', line 3971

static VALUE
rb_gzreader_bytes(VALUE obj)
{
    rb_warn("Zstdlib::GzipReader#bytes is deprecated; use #each_byte instead");
    if (!rb_block_given_p())
	return rb_enumeratorize(obj, ID2SYM(rb_intern("each_byte")), 0, 0);
    return rb_gzreader_each_byte(obj);
}

#each(*args) ⇒ Object

See Zstdlib::GzipReader documentation for a description.



4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4430

static VALUE
rb_gzreader_each(int argc, VALUE *argv, VALUE obj)
{
    VALUE str;

    RETURN_ENUMERATOR(obj, 0, 0);

    while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
	rb_yield(str);
    }
    return obj;
}

#each_byteObject

See Zstdlib::GzipReader documentation for a description.



4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4156

static VALUE
rb_gzreader_each_byte(VALUE obj)
{
    VALUE c;

    RETURN_ENUMERATOR(obj, 0, 0);

    while (!NIL_P(c = rb_gzreader_getbyte(obj))) {
	rb_yield(c);
    }
    return Qnil;
}

#each_charObject

See Zstdlib::GzipReader documentation for a description.



4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4138

static VALUE
rb_gzreader_each_char(VALUE obj)
{
    VALUE c;

    RETURN_ENUMERATOR(obj, 0, 0);

    while (!NIL_P(c = rb_gzreader_getc(obj))) {
	rb_yield(c);
    }
    return Qnil;
}

#each_line(*args) ⇒ Object

See Zstdlib::GzipReader documentation for a description.



4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4430

static VALUE
rb_gzreader_each(int argc, VALUE *argv, VALUE obj)
{
    VALUE str;

    RETURN_ENUMERATOR(obj, 0, 0);

    while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
	rb_yield(str);
    }
    return obj;
}

#eofObject

Returns +true+ or +false+ whether the stream has reached the end.



3513
3514
3515
3516
3517
3518
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3513

static VALUE
rb_gzfile_eof_p(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
}

#eof?Boolean

Returns +true+ or +false+ whether the stream has reached the end.

Returns:

  • (Boolean)


3513
3514
3515
3516
3517
3518
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3513

static VALUE
rb_gzfile_eof_p(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
}

#external_encodingObject

See Zstdlib::GzipReader documentation for a description.



4464
4465
4466
4467
4468
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4464

static VALUE
rb_gzreader_external_encoding(VALUE self)
{
    return rb_enc_from_encoding(get_gzfile(self)->enc);
}

#getbyteObject

See Zstdlib::GzipReader documentation for a description.



4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4104

static VALUE
rb_gzreader_getbyte(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE dst;

    dst = gzfile_read(gz, 1);
    if (!NIL_P(dst)) {
	dst = INT2FIX((unsigned int)(RSTRING_PTR(dst)[0]) & 0xff);
    }
    return dst;
}

#getcObject

See Zstdlib::GzipReader documentation for a description.



4075
4076
4077
4078
4079
4080
4081
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4075

static VALUE
rb_gzreader_getc(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);

    return gzfile_getc(gz);
}

#gets(*args) ⇒ Object

See Zstdlib::GzipReader documentation for a description.



4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4398

static VALUE
rb_gzreader_gets(int argc, VALUE *argv, VALUE obj)
{
    VALUE dst;
    dst = gzreader_gets(argc, argv, obj);
    if (!NIL_P(dst)) {
	rb_lastline_set(dst);
    }
    return dst;
}

#linenoObject

The line number of the last row read from this file.



3352
3353
3354
3355
3356
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3352

static VALUE
rb_gzfile_lineno(VALUE obj)
{
    return INT2NUM(get_gzfile(obj)->lineno);
}

#lineno=(lineno) ⇒ Object

Specify line number of the last row read from this file.



3363
3364
3365
3366
3367
3368
3369
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3363

static VALUE
rb_gzfile_set_lineno(VALUE obj, VALUE lineno)
{
    struct gzfile *gz = get_gzfile(obj);
    gz->lineno = NUM2INT(lineno);
    return lineno;
}

#lines(*args) ⇒ Object

This is a deprecated alias for each_line.



4257
4258
4259
4260
4261
4262
4263
4264
# File 'ext/zstdlib_c/ruby/zlib-2.7/zstdlib.c', line 4257

static VALUE
rb_gzreader_lines(int argc, VALUE *argv, VALUE obj)
{
    rb_warn("Zstdlib::GzipReader#lines is deprecated; use #each_line instead");
    if (!rb_block_given_p())
	return rb_enumeratorize(obj, ID2SYM(rb_intern("each_line")), argc, argv);
    return rb_gzreader_each(argc, argv, obj);
}

#posObject

Total number of output bytes output so far.



3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3571

static VALUE
rb_gzfile_total_out(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    uLong total_out = gz->z.stream.total_out;
    long buf_filled = ZSTREAM_BUF_FILLED(&gz->z);

    if (total_out >= (uLong)buf_filled) {
        return rb_uint2inum(total_out - buf_filled);
    } else {
        return LONG2FIX(-(buf_filled - (long)total_out));
    }
}

#read(*args) ⇒ Object

See Zstdlib::GzipReader documentation for a description.



4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4021

static VALUE
rb_gzreader_read(int argc, VALUE *argv, VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE vlen;
    long len;

    rb_scan_args(argc, argv, "01", &vlen);
    if (NIL_P(vlen)) {
	return gzfile_read_all(gz);
    }

    len = NUM2INT(vlen);
    if (len < 0) {
	rb_raise(rb_eArgError, "negative length %ld given", len);
    }
    return gzfile_read(gz, len);
}

#readbyteObject

See Zstdlib::GzipReader documentation for a description.



4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4122

static VALUE
rb_gzreader_readbyte(VALUE obj)
{
    VALUE dst;
    dst = rb_gzreader_getbyte(obj);
    if (NIL_P(dst)) {
	rb_raise(rb_eEOFError, "end of file reached");
    }
    return dst;
}

#readcharObject

See Zstdlib::GzipReader documentation for a description.



4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4088

static VALUE
rb_gzreader_readchar(VALUE obj)
{
    VALUE dst;
    dst = rb_gzreader_getc(obj);
    if (NIL_P(dst)) {
	rb_raise(rb_eEOFError, "end of file reached");
    }
    return dst;
}

#readline(*args) ⇒ Object

See Zstdlib::GzipReader documentation for a description.



4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4414

static VALUE
rb_gzreader_readline(int argc, VALUE *argv, VALUE obj)
{
    VALUE dst;
    dst = rb_gzreader_gets(argc, argv, obj);
    if (NIL_P(dst)) {
	rb_raise(rb_eEOFError, "end of file reached");
    }
    return dst;
}

#readlines(*args) ⇒ Object

See Zstdlib::GzipReader documentation for a description.



4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4448

static VALUE
rb_gzreader_readlines(int argc, VALUE *argv, VALUE obj)
{
    VALUE str, dst;
    dst = rb_ary_new();
    while (!NIL_P(str = gzreader_gets(argc, argv, obj))) {
	rb_ary_push(dst, str);
    }
    return dst;
}

#readpartial(*args) ⇒ Object

call-seq: gzipreader.readpartial(maxlen [, outbuf]) => string, outbuf

Reads at most maxlen bytes from the gziped stream but it blocks only if gzipreader has no data immediately available. If the optional outbuf argument is present, it must reference a String, which will receive the data. It raises EOFError on end of file.



4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4052

static VALUE
rb_gzreader_readpartial(int argc, VALUE *argv, VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    VALUE vlen, outbuf;
    long len;

    rb_scan_args(argc, argv, "11", &vlen, &outbuf);

    len = NUM2INT(vlen);
    if (len < 0) {
	rb_raise(rb_eArgError, "negative length %ld given", len);
    }
    if (!NIL_P(outbuf))
        Check_Type(outbuf, T_STRING);
    return gzfile_readpartial(gz, len, outbuf);
}

#rewindObject

Resets the position of the file pointer to the point created the GzipReader object. The associated IO object needs to respond to the +seek+ method.



3994
3995
3996
3997
3998
3999
4000
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3994

static VALUE
rb_gzreader_rewind(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    gzfile_reader_rewind(gz);
    return INT2FIX(0);
}

#tellObject

Total number of output bytes output so far.



3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 3571

static VALUE
rb_gzfile_total_out(VALUE obj)
{
    struct gzfile *gz = get_gzfile(obj);
    uLong total_out = gz->z.stream.total_out;
    long buf_filled = ZSTREAM_BUF_FILLED(&gz->z);

    if (total_out >= (uLong)buf_filled) {
        return rb_uint2inum(total_out - buf_filled);
    } else {
        return LONG2FIX(-(buf_filled - (long)total_out));
    }
}

#ungetbyte(ch) ⇒ Object

See Zstdlib::GzipReader documentation for a description.



4196
4197
4198
4199
4200
4201
4202
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4196

static VALUE
rb_gzreader_ungetbyte(VALUE obj, VALUE ch)
{
    struct gzfile *gz = get_gzfile(obj);
    gzfile_ungetbyte(gz, NUM2CHR(ch));
    return Qnil;
}

#ungetc(s) ⇒ Object

See Zstdlib::GzipReader documentation for a description.



4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4174

static VALUE
rb_gzreader_ungetc(VALUE obj, VALUE s)
{
    struct gzfile *gz;

    if (FIXNUM_P(s))
	return rb_gzreader_ungetbyte(obj, s);
    gz = get_gzfile(obj);
    StringValue(s);
    if (gz->enc2 && gz->enc2 != rb_ascii8bit_encoding()) {
	s = rb_str_conv_enc(s, rb_enc_get(s), gz->enc2);
    }
    gzfile_ungets(gz, (const Bytef*)RSTRING_PTR(s), RSTRING_LEN(s));
    RB_GC_GUARD(s);
    return Qnil;
}

#unusedObject

Returns the rest of the data which had read for parsing gzip format, or +nil+ if the whole gzip file is not parsed yet.



4008
4009
4010
4011
4012
4013
4014
# File 'ext/zstdlib_c/ruby/zlib-3.3/zstdlib.c', line 4008

static VALUE
rb_gzreader_unused(VALUE obj)
{
    struct gzfile *gz;
    TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz);
    return gzfile_reader_get_unused(gz);
}