ruby-changes:22504
From: drbrain <ko1@a...>
Date: Sat, 11 Feb 2012 09:37:59 +0900 (JST)
Subject: [ruby-changes:22504] drbrain:r34553 (trunk): * ext/zlib/zlib.c (rb_inflate_add_dictionary): Added
drbrain 2012-02-11 09:37:44 +0900 (Sat, 11 Feb 2012) New Revision: 34553 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=34553 Log: * ext/zlib/zlib.c (rb_inflate_add_dictionary): Added Zlib::Inflate#add_dictionary to allow users to pre-specify for using during #inflate. [ruby-trunk - Feature #5937] Modified files: trunk/ChangeLog trunk/ext/zlib/zlib.c trunk/test/zlib/test_zlib.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 34552) +++ ChangeLog (revision 34553) @@ -1,3 +1,9 @@ +Sat Feb 11 08:34:42 2012 Eric Hodel <drbrain@s...> + + * ext/zlib/zlib.c (rb_inflate_add_dictionary): Added + Zlib::Inflate#add_dictionary to allow users to pre-specify + for using during #inflate. [ruby-trunk - Feature #5937] + Sat Feb 11 08:23:02 2012 Eric Hodel <drbrain@s...> * ext/zlib/zlib.c (do_inflate): Inflate more data if buffered data Index: ext/zlib/zlib.c =================================================================== --- ext/zlib/zlib.c (revision 34552) +++ ext/zlib/zlib.c (revision 34553) @@ -56,6 +56,8 @@ #define sizeof(x) ((int)sizeof(x)) +static ID id_dictionaries; + /*--------- Prototypes --------*/ static NORETURN(void raise_zlib_error(int, const char*)); @@ -875,6 +877,15 @@ if (z->stream.avail_in > 0) { zstream_append_input(z, z->stream.next_in, z->stream.avail_in); } + if (err == Z_NEED_DICT) { + VALUE self = (VALUE)z->stream.opaque; + VALUE dicts = rb_ivar_get(self, id_dictionaries); + VALUE dict = rb_hash_aref(dicts, rb_uint2inum(z->stream.adler)); + if (!NIL_P(dict)) { + rb_inflate_set_dictionary(self, dict); + continue; + } + } raise_zlib_error(err, z->stream.msg); } if (z->stream.avail_out > 0) { @@ -965,6 +976,7 @@ obj = Data_Make_Struct(klass, struct zstream, zstream_mark, zstream_free, z); zstream_init(z, funcs); + z->stream.opaque = (voidpf)obj; return obj; } @@ -1602,12 +1614,12 @@ * dup) itself. */ - - static VALUE rb_inflate_s_allocate(VALUE klass) { - return zstream_inflate_new(klass); + VALUE inflate = zstream_inflate_new(klass); + rb_ivar_set(inflate, id_dictionaries, rb_hash_new()); + return inflate; } /* @@ -1737,6 +1749,25 @@ } } +/* Document-method: Zlib::Inflate#add_dictionary + * + * call-seq: add_dictionary(string) + * + * Provide the inflate stream with a dictionary that may be required in the + * future. Multiple dictionaries may be provided. The inflate stream will + * automatically choose the correct user-provided dictionary based on the + * stream's required dictionary. + */ +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; +} + /* * Document-method: Zlib::Inflate#inflate * @@ -4018,6 +4049,8 @@ mZlib = rb_define_module("Zlib"); + id_dictionaries = rb_intern("@dictionaries"); + cZError = rb_define_class_under(mZlib, "Error", rb_eStandardError); cStreamEnd = rb_define_class_under(mZlib, "StreamEnd", cZError); cNeedDict = rb_define_class_under(mZlib, "NeedDict", cZError); @@ -4086,6 +4119,7 @@ rb_define_singleton_method(mZlib, "inflate", rb_inflate_s_inflate, 1); rb_define_alloc_func(cInflate, rb_inflate_s_allocate); rb_define_method(cInflate, "initialize", rb_inflate_initialize, -1); + rb_define_method(cInflate, "add_dictionary", rb_inflate_add_dictionary, 1); rb_define_method(cInflate, "inflate", rb_inflate_inflate, 1); rb_define_method(cInflate, "<<", rb_inflate_addstr, 1); rb_define_method(cInflate, "sync", rb_inflate_sync, 1); Index: test/zlib/test_zlib.rb =================================================================== --- test/zlib/test_zlib.rb (revision 34552) +++ test/zlib/test_zlib.rb (revision 34553) @@ -185,6 +185,23 @@ assert_equal("foo", z.finish) end + def test_add_dictionary + dictionary = "foo" + + deflate = Zlib::Deflate.new + deflate.set_dictionary dictionary + compressed = deflate.deflate "foofoofoo", Zlib::FINISH + deflate.close + + out = nil + inflate = Zlib::Inflate.new + inflate.add_dictionary "foo" + + out = inflate.inflate compressed + + assert_equal "foofoofoo", out + end + def test_inflate s = Zlib::Deflate.deflate("foo") z = Zlib::Inflate.new -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/