# class Zlib::GzipReader

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

### Public Class Methods

Zlib::GzipReader.new(io, options = {})
Source

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

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.

Zlib::GzipReader.open(filename) {|gz| ... }
Source

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

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.

Zlib::GzipReader.zcat(io, options = {}, &block) → nil
Zlib::GzipReader.zcat(io, options = {}) → string
Source

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

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.

### Public Instance Methods

each (*args)
Source

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

See `Zlib::GzipReader` documentation for a description.

Also aliased as: each_line
each_byte ()
Source

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

See `Zlib::GzipReader` documentation for a description.

each_char ()
Source

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

See `Zlib::GzipReader` documentation for a description.

each_line (*args)

See `Zlib::GzipReader` documentation for a description.

Alias for: each
eof ()
Source

    static VALUE
    rb_gzfile_eof_p(VALUE obj)
    {
        struct gzfile *gz = get_gzfile(obj);
        while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) == 0) {
            gzfile_read_more(gz, Qnil);
        }
        return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
    }

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

Also aliased as: eof?
eof? ()

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

Alias for: eof
external_encoding ()
Source

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

See `Zlib::GzipReader` documentation for a description.

getbyte ()
Source

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

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

See `Zlib::GzipReader` documentation for a description.

getc ()
Source

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

        return gzfile_getc(gz);
    }

See `Zlib::GzipReader` documentation for a description.

gets (*args)
Source

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

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

lineno ()
Source

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

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

lineno= (p1)
Source

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

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

pos ()
Source

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

Total number of output bytes output so far.

Also aliased as: tell
read (p1 = v1, p2 = v2)
Source

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

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

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

See `Zlib::GzipReader` documentation for a description.

readbyte ()
Source

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

See `Zlib::GzipReader` documentation for a description.

readchar ()
Source

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

See `Zlib::GzipReader` documentation for a description.

readline (*args)
Source

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

See `Zlib::GzipReader` documentation for a description.

readlines (*args)
Source

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

See `Zlib::GzipReader` documentation for a description.

readpartial(maxlen [, outbuf]) → string, outbuf
Source

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

Reads at most maxlen bytes from the gzipped 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.

rewind ()
Source

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

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.

tell ()

Total number of output bytes output so far.

Alias for: pos
ungetbyte (p1)
Source

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

See `Zlib::GzipReader` documentation for a description.

ungetc (p1)
Source

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

See `Zlib::GzipReader` documentation for a description.

unused ()
Source

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

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