Class: Zlib::GzipReader

Inherits:
GzipFile show all
Includes:
Enumerable
Defined in:
ext/zlib/zlib.c,
ext/zlib/zlib.c

Overview

Zlib::GzipReader is the class for reading a gzipped file. GzipReader should be used as an IO, or -IO-like, object.

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

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

Method Catalogue

The following methods in Zlib::GzipReader are just like their counterparts in IO, but they raise Zlib::Error or Zlib::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 Zlib::GzipFile::NoFooter, Zlib::GzipFile::CRCError, or Zlib::GzipFile::LengthError exception.

  • When an reading request is received beyond the end of file (the end of compressed data). That is, when Zlib::GzipReader#read, Zlib::GzipReader#gets, or some other methods for reading returns nil.

  • When Zlib::GzipFile#close method is called after the object reaches the end of file.

  • When Zlib::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 included from Enumerable

#to_set

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:

Zlib::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 Zlib::GzipFile::Error exception.



3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
# File 'ext/zlib/zlib.c', line 3946

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: Zlib::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 Zlib::GzipReader.new and ZLib::GzipFile.wrap.



3869
3870
3871
3872
3873
# File 'ext/zlib/zlib.c', line 3869

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:

Zlib::GzipReader.zcat(io, options = {}, &block) => nil
Zlib::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.



3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
# File 'ext/zlib/zlib.c', line 3891

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

#each(*args) ⇒ Object

See Zlib::GzipReader documentation for a description.



4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
# File 'ext/zlib/zlib.c', line 4416

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 Zlib::GzipReader documentation for a description.



4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
# File 'ext/zlib/zlib.c', line 4142

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 Zlib::GzipReader documentation for a description.



4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
# File 'ext/zlib/zlib.c', line 4124

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 Zlib::GzipReader documentation for a description.



4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
# File 'ext/zlib/zlib.c', line 4416

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.



3499
3500
3501
3502
3503
3504
# File 'ext/zlib/zlib.c', line 3499

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)


3499
3500
3501
3502
3503
3504
# File 'ext/zlib/zlib.c', line 3499

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

#external_encodingObject

See Zlib::GzipReader documentation for a description.



4450
4451
4452
4453
4454
# File 'ext/zlib/zlib.c', line 4450

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

#getbyteObject

See Zlib::GzipReader documentation for a description.



4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
# File 'ext/zlib/zlib.c', line 4090

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 Zlib::GzipReader documentation for a description.



4061
4062
4063
4064
4065
4066
4067
# File 'ext/zlib/zlib.c', line 4061

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

    return gzfile_getc(gz);
}

#gets(*args) ⇒ Object

See Zlib::GzipReader documentation for a description. However, note that this method can return nil even if #eof? returns false, unlike the behavior of File#gets.



4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
# File 'ext/zlib/zlib.c', line 4384

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.



3338
3339
3340
3341
3342
# File 'ext/zlib/zlib.c', line 3338

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.



3349
3350
3351
3352
3353
3354
3355
# File 'ext/zlib/zlib.c', line 3349

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

#posObject

Total number of output bytes output so far.



3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
# File 'ext/zlib/zlib.c', line 3557

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 Zlib::GzipReader documentation for a description.



4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
# File 'ext/zlib/zlib.c', line 4007

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 Zlib::GzipReader documentation for a description.



4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
# File 'ext/zlib/zlib.c', line 4108

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 Zlib::GzipReader documentation for a description.



4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
# File 'ext/zlib/zlib.c', line 4074

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 Zlib::GzipReader documentation for a description.



4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
# File 'ext/zlib/zlib.c', line 4400

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 Zlib::GzipReader documentation for a description.



4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
# File 'ext/zlib/zlib.c', line 4434

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 <i>maxlen</i> bytes from the gziped stream but
it blocks only if <em>gzipreader</em> has no data immediately available.
If the optional <i>outbuf</i> argument is present,
it must reference a String, which will receive the data.
It raises <code>EOFError</code> on end of file.


4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
# File 'ext/zlib/zlib.c', line 4038

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.



3980
3981
3982
3983
3984
3985
3986
# File 'ext/zlib/zlib.c', line 3980

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.



3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
# File 'ext/zlib/zlib.c', line 3557

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 Zlib::GzipReader documentation for a description.



4182
4183
4184
4185
4186
4187
4188
# File 'ext/zlib/zlib.c', line 4182

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 Zlib::GzipReader documentation for a description.



4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
# File 'ext/zlib/zlib.c', line 4160

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.



3994
3995
3996
3997
3998
3999
4000
# File 'ext/zlib/zlib.c', line 3994

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