類別 Zlib::Inflate

Zlib:Inflate 是用於解壓縮壓縮資料的類別。與 Zlib::Deflate 不同,此類別的執行個體無法複製 (clone、dup) 本身。

公開類別方法

inflate(string) 按一下以切換來源
Zlib::Inflate.inflate(string)

解壓縮 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;
}
Zlib::Inflate.new(window_bits = Zlib::MAX_WBITS) 按一下以切換來源

建立新的 inflate 串流以進行解壓縮。window_bits 設定歷程記錄緩衝區的大小,且可以有下列值

0

讓 inflate 使用壓縮串流的 zlib 標頭中的視窗大小。

(8..15)

覆寫壓縮串流中 inflate 標頭的視窗大小。視窗大小必須大於或等於壓縮串流的視窗大小。

大於 15

將 32 加到 window_bits 以啟用 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;
}

公開執行個體方法

<<(p1) 按一下以切換來源

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;
}
add_dictionary(string) 按一下以切換來源

提供 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;
}
inflate(deflate_string, buffer: nil) → String 按一下以切換來源
inflate(deflate_string, buffer: nil) { |chunk| ... } → nil

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;
}
set_dictionary(p1) 按一下以切換來源

設定預設字典並傳回 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;
}
sync(string) 按一下以切換來源

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));
}
sync_point?() 按一下以切換來源

從原始文件逐字引用

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