класс Zlib::GzipReader
Zlib::GzipReader — это класс для чтения сжатых gzip файлов. GzipReader должен использоваться как объект типа IO, или как объект, похожий на IO.
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 Каталог
Следующие методы в Zlib::GzipReader аналогичны своим аналогам в IO, но они генерируют исключение Zlib::Error или Zlib::GzipFile::Error, если в gzip-файле обнаружена ошибка.
Будьте внимательны к подписи gzip-файла. Gzip-файл содержит контрольную сумму предварительно сжатых данных в своей подписи. GzipReader проверяет все данные, не подвергавшиеся сжатию, по этой контрольной сумме в следующих случаях, и если проверка не пройдена, генерирует исключение Zlib::GzipFile::NoFooter, Zlib::GzipFile::CRCError, или Zlib::GzipFile::LengthError.
-
Когда запрос на чтение выходит за пределы конца файла (конца сжатых данных). То есть, когда
Zlib::GzipReader#read,Zlib::GzipReader#gets, или другие методы чтения возвращают nil. -
Когда вызывается метод
Zlib::GzipFile#closeпосле того, как объект достиг конца файла. -
Когда вызывается метод
Zlib::GzipReader#unusedпосле того, как объект достиг конца файла.
Остальные методы подробно описаны в своей документации.
Методы класса
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;
} Создает объект GzipReader, связанный с io. Объект GzipReader читает сжатые данные из io, и распаковывает их. Объект io должен иметь метод read, который ведет себя так же, как метод IO#read.
Хэш options может использоваться для задания кодировки данных. :external_encoding, :internal_encoding и :encoding могут быть настроены так же, как в IO::new.
Если заголовок gzip-файла некорректен, генерируется исключение Zlib::GzipFile::Error.
static VALUE
rb_gzreader_s_open(int argc, VALUE *argv, VALUE klass)
{
return gzfile_s_open(argc, argv, klass, "rb");
} Открывает файл, указанный в filename, как gzip-файл и возвращает объект GzipReader, связанный с этим файлом. Дополнительные подробности об этом методе см. в Zlib::GzipReader.new и ZLib::GzipFile.wrap.
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;
} Распаковывает все gzip-данные в io, обрабатывая несколько gzip-потоков до конца io. После gzip-потоков не должно быть никаких других данных.
Если задан блок, он получает строки распакованных данных, а метод возвращает nil. Если блок не задан, метод возвращает конкатенацию всех распакованных данных во всех gzip-потоках.
Методы экземпляра public
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;
} См. Zlib::GzipReader документацию для описания.
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;
} См. Zlib::GzipReader документацию для описания.
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;
} См. Zlib::GzipReader документацию для описания.
static VALUE
rb_gzfile_eof_p(VALUE obj)
{
struct gzfile *gz = get_gzfile(obj);
return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
} Возвращает true или false, указывая, достиг ли поток конца.
static VALUE
rb_gzreader_external_encoding(VALUE self)
{
return rb_enc_from_encoding(get_gzfile(self)->enc);
} См. Zlib::GzipReader документацию для описания.
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;
} См. Zlib::GzipReader документацию для описания.
static VALUE
rb_gzreader_getc(VALUE obj)
{
struct gzfile *gz = get_gzfile(obj);
return gzfile_getc(gz);
} См. Zlib::GzipReader документацию для описания.
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;
} См. Zlib::GzipReader документацию для описания. Однако обратите внимание, что этот метод может возвращать nil даже если eof? возвращает false, в отличие от поведения File#gets.
static VALUE
rb_gzfile_lineno(VALUE obj)
{
return INT2NUM(get_gzfile(obj)->lineno);
} Номер строки последней прочитанной строки из этого файла.
static VALUE
rb_gzfile_set_lineno(VALUE obj, VALUE lineno)
{
struct gzfile *gz = get_gzfile(obj);
gz->lineno = NUM2INT(lineno);
return lineno;
} Укажите номер строки последней прочитанной строки из этого файла.
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));
}
} Общее количество выведенных байтов до сих пор.
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);
} См. Zlib::GzipReader документацию для описания.
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;
} См. Zlib::GzipReader документацию для описания.
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;
} См. Zlib::GzipReader документацию для описания.
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;
} См. Zlib::GzipReader документацию для описания.
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;
} См. Zlib::GzipReader документацию для описания.
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);
} Читает не более maxlen байтов из сжатого потока gzip, но блокируется только если gzipreader не имеет данных, доступных немедленно. Если присутствует необязательный аргумент outbuf, он должен ссылаться на String, который получит данные. Вызывает EOFError при достижении конца файла.
static VALUE
rb_gzreader_rewind(VALUE obj)
{
struct gzfile *gz = get_gzfile(obj);
gzfile_reader_rewind(gz);
return INT2FIX(0);
} Сбрасывает позицию указателя файла к позиции, созданной объектом GzipReader. Ассоциированный объект IO должен отвечать на метод seek.
static VALUE
rb_gzreader_ungetbyte(VALUE obj, VALUE ch)
{
struct gzfile *gz = get_gzfile(obj);
gzfile_ungetbyte(gz, NUM2CHR(ch));
return Qnil;
} См. Zlib::GzipReader документацию для описания.
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;
} См. Zlib::GzipReader документацию для описания.
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);
} Возвращает оставшиеся данные, которые были прочитаны для разбора формата gzip, или nil если весь файл gzip еще не проанализирован.
Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.