класс Zlib::GzipWriter
Zlib::GzipWriter — это класс для записи сжатых файлов gzip. GzipWriter следует использовать с экземпляром объекта IO или подобного ему.
Два следующих примера генерируют один и тот же результат.
Zlib::GzipWriter.open('hoge.gz') do |gz|
gz.write 'jugemu jugemu gokou no surikire...'
end
File.open('hoge.gz', 'w') do |f|
gz = Zlib::GzipWriter.new(f)
gz.write 'jugemu jugemu gokou no surikire...'
gz.close
end
Чтобы получить результат, аналогичный gzip(1), выполните следующее:
orig = 'hoge.txt'
Zlib::GzipWriter.open('hoge.gz') do |gz|
gz.mtime = File.mtime(orig)
gz.orig_name = orig
gz.write IO.binread(orig)
end
ПРИМЕЧАНИЕ: Из-за ограничений финализатора Ruby необходимо явно закрывать объекты GzipWriter с помощью Zlib::GzipWriter#close и т. д. В противном случае GzipWriter не сможет записать подпись gzip и сгенерирует поврежденный gzip-файл.
Публичные методы класса
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;
} Создаёт объект GzipWriter, связанный с io. level и strategy должны быть такими же, как аргументы метода Zlib::Deflate.new. Объект GzipWriter записывает сжатые данные в io. io должен поддерживать метод write, поведение которого аналогично методу IO#write.
Хэш options может быть использован для установки кодировки данных. :external_encoding, :internal_encoding и :encoding могут быть установлены так же, как и в IO::new.
static VALUE
rb_gzwriter_s_open(int argc, VALUE *argv, VALUE klass)
{
return gzfile_s_open(argc, argv, klass, "wb");
} Открывает файл, указанный по filename, для записи сжатых данных gzip и возвращает объект GzipWriter, связанный с этим файлом. Более подробные сведения об этом методе можно найти в Zlib::GzipWriter.new и Zlib::GzipFile.wrap.
Публичные методы экземпляра
#define rb_gzwriter_addstr rb_io_addstr
Аналогично IO.
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;
} Устанавливает комментарий (str) в заголовке gzip.
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;
} Очищает все внутренние буферы объекта GzipWriter. Значение flush совпадает со значением в Zlib::Deflate#deflate. Если flush опущено, используется Zlib::SYNC_FLUSH. Не имеет смысла указывать аргумент flush Zlib::NO_FLUSH.
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;
} Устанавливает время изменения (mtime) в заголовке gzip. Используйте целое число Integer.
Установка времени изменения в заголовке gzip не влияет на время изменения создаваемого файла. Разные утилиты, которые распаковывают сжатые файлы, могут использовать заголовок с временем изменения. Например, утилита gunzip может использовать флаг `-N`, который установит время изменения результирующего файла в соответствии со значением в заголовке. По умолчанию многие инструменты устанавливают время изменения распакованного файла в соответствии с временем изменения сжатого файла, а не со значением из заголовка.
Если время изменения не установлено, используется значение по умолчанию, соответствующее времени начала сжатия. Установка значения 0 указывает, что отметка времени недоступна.
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;
} Устанавливает исходное имя (str) в заголовке gzip.
static VALUE
rb_gzfile_total_in(VALUE obj)
{
return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
} Общее количество считанных входных байтов.
#define rb_gzwriter_print rb_io_print
Аналогично IO.
#define rb_gzwriter_printf rb_io_printf
Аналогично IO.
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;
} Аналогично IO.
#define rb_gzwriter_puts rb_io_puts
Аналогично IO.
static VALUE
rb_gzfile_total_in(VALUE obj)
{
return rb_uint2inum(get_gzfile(obj)->z.stream.total_in);
} Общее количество считанных входных байтов.
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);
} Аналогично IO.
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.