类 Zlib::Inflate
Zlib:Inflate 是用于解压缩压缩数据的类。与 Zlib::Deflate
不同,此类的实例无法自我复制(克隆、dup)。
公共类方法
解压缩 string
。如果解压缩需要预设字典,则会引发 Zlib::NeedDict
异常。
此方法几乎等效于以下代码
def inflate(string) zstream = Zlib::Inflate.new buf = zstream.inflate(string) zstream.finish zstream.close buf end
另请参见 Zlib.deflate
static VALUE rb_inflate_s_inflate(VALUE obj, VALUE src) { struct zstream z; VALUE dst, args[2]; int err; StringValue(src); zstream_init_inflate(&z); err = inflateInit(&z.stream); if (err != Z_OK) { raise_zlib_error(err, z.stream.msg); } ZSTREAM_READY(&z); args[0] = (VALUE)&z; args[1] = src; dst = rb_ensure(inflate_run, (VALUE)args, zstream_ensure_end, (VALUE)&z); return dst; }
创建一个用于解压缩的新 inflate 流。window_bits
设置历史缓冲区的大小,可以具有以下值
- 0
-
让 inflate 使用压缩流的 zlib 头部的窗口大小。
- (8..15)
-
覆盖压缩流中 inflate 头部的窗口大小。窗口大小必须大于或等于压缩流的窗口大小。
- 大于 15
-
在 window_bits 中添加 32 以启用 zlib 和 gzip 解码,并自动检测头文件,或添加 16 以仅解码 gzip 格式(对于非 gzip 流,将引发
Zlib::DataError
)。 - (-8..-15)
-
启用原始 deflate 模式,该模式不会生成校验值,也不会在流末尾查找任何校验值进行比较。
这适用于使用 deflate 压缩数据格式的其他格式,例如 zip,它们提供自己的校验值。
示例¶ ↑
open "compressed.file" do |compressed_io| zi = Zlib::Inflate.new(Zlib::MAX_WBITS + 32) begin open "uncompressed.file", "w+" do |uncompressed_io| uncompressed_io << zi.inflate(compressed_io.read) end ensure zi.close end end
static VALUE rb_inflate_initialize(int argc, VALUE *argv, VALUE obj) { struct zstream *z; VALUE wbits; int err; rb_scan_args(argc, argv, "01", &wbits); TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z); err = inflateInit2(&z->stream, ARG_WBITS(wbits)); if (err != Z_OK) { raise_zlib_error(err, z->stream.msg); } ZSTREAM_READY(z); return obj; }
公共实例方法
与 IO
相同。
static VALUE rb_inflate_addstr(VALUE obj, VALUE src) { struct zstream *z = get_zstream(obj); if (ZSTREAM_IS_FINISHED(z)) { if (!NIL_P(src)) { StringValue(src); zstream_append_buffer2(z, src); } } else { do_inflate(z, src); if (ZSTREAM_IS_FINISHED(z)) { zstream_passthrough_input(z); } } return obj; }
为 inflate 流提供一个字典,该字典可能在将来需要。可以提供多个字典。inflate 流将根据流所需的字典自动选择正确用户提供的字典。
static VALUE rb_inflate_add_dictionary(VALUE obj, VALUE dictionary) { VALUE dictionaries = rb_ivar_get(obj, id_dictionaries); VALUE checksum = do_checksum(1, &dictionary, adler32); rb_hash_aset(dictionaries, checksum, dictionary); return obj; }
将 deflate_string
输入 inflate 流并返回流的输出。调用此方法时,流的输入和输出缓冲区都将被刷新。如果字符串为 nil
,则此方法将完成流,就像 Zlib::ZStream#finish
一样。
如果给定一个块,则来自 deflate_string
的连续膨胀块将被传递给该块,并返回 nil
。
如果给定 :buffer 关键字参数且不为 nil
-
:buffer 关键字应该是一个
String
,并将用作输出缓冲区。使用此选项可以重用膨胀期间所需的内存。 -
不传递块时,返回值将与 :buffer 关键字参数相同。
-
传递块时,传递的块将与 :buffer 关键字参数相同。
如果需要预设字典来解压缩,则会引发 Zlib::NeedDict
异常。通过 Zlib::Inflate#set_dictionary
设置字典,然后使用空字符串再次调用此方法来刷新流
inflater = Zlib::Inflate.new begin out = inflater.inflate compressed rescue Zlib::NeedDict # ensure the dictionary matches the stream's required dictionary raise unless inflater.adler == Zlib.adler32(dictionary) inflater.set_dictionary dictionary inflater.inflate '' end # ... inflater.close
另请参阅 Zlib::Inflate.new
static VALUE rb_inflate_inflate(int argc, VALUE* argv, VALUE obj) { struct zstream *z = get_zstream(obj); VALUE dst, src, opts, buffer = Qnil; if (OPTHASH_GIVEN_P(opts)) { VALUE buf; rb_get_kwargs(opts, &id_buffer, 0, 1, &buf); if (buf != Qundef && buf != Qnil) { buffer = StringValue(buf); } } if (buffer != Qnil) { if (!(ZSTREAM_REUSE_BUFFER_P(z) && z->buf == buffer)) { long len = RSTRING_LEN(buffer); if (len >= ZSTREAM_AVAIL_OUT_STEP_MAX) { rb_str_modify(buffer); } else { len = ZSTREAM_AVAIL_OUT_STEP_MAX - len; rb_str_modify_expand(buffer, len); } rb_str_set_len(buffer, 0); z->flags |= ZSTREAM_REUSE_BUFFER; z->buf = buffer; } } else if (ZSTREAM_REUSE_BUFFER_P(z)) { z->flags &= ~ZSTREAM_REUSE_BUFFER; z->buf = Qnil; } rb_scan_args(argc, argv, "10", &src); if (ZSTREAM_IS_FINISHED(z)) { if (NIL_P(src)) { dst = zstream_detach_buffer(z); } else { StringValue(src); zstream_append_buffer2(z, src); if (ZSTREAM_REUSE_BUFFER_P(z)) { dst = rb_str_resize(buffer, 0); } else { dst = rb_str_new(0, 0); } } } else { do_inflate(z, src); dst = zstream_detach_buffer(z); if (ZSTREAM_IS_FINISHED(z)) { zstream_passthrough_input(z); } } return dst; }
设置预设字典并返回string
。此方法仅在抛出Zlib::NeedDict
异常后可用。有关详细信息,请参阅zlib.h。
static VALUE rb_inflate_set_dictionary(VALUE obj, VALUE dic) { struct zstream *z = get_zstream(obj); VALUE src = dic; int err; StringValue(src); err = inflateSetDictionary(&z->stream, (Bytef*)RSTRING_PTR(src), RSTRING_LENINT(src)); if (err != Z_OK) { raise_zlib_error(err, z->stream.msg); } return dic; }
将string
输入到输入缓冲区的末尾,并跳过数据,直到找到一个完整的刷新点。如果在缓冲区中找到该点,此方法将刷新缓冲区并返回false。否则,它将返回true
,并且完整的刷新点的后续数据将保留在缓冲区中。
static VALUE rb_inflate_sync(VALUE obj, VALUE src) { struct zstream *z = get_zstream(obj); StringValue(src); return zstream_sync(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src)); }
从原始文档中逐字引用
What is this?
:)
static VALUE rb_inflate_sync_point_p(VALUE obj) { struct zstream *z = get_zstream(obj); int err; err = inflateSyncPoint(&z->stream); if (err == 1) { return Qtrue; } if (err != Z_OK) { raise_zlib_error(err, z->stream.msg); } return Qfalse; }