msgpack 1.4.4 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.github/workflows/ci.yaml +4 -3
 - data/ChangeLog +18 -0
 - data/README.md +22 -0
 - data/doclib/msgpack/factory.rb +46 -3
 - data/doclib/msgpack/packer.rb +5 -4
 - data/doclib/msgpack/unpacker.rb +2 -2
 - data/ext/java/org/msgpack/jruby/Buffer.java +6 -0
 - data/ext/java/org/msgpack/jruby/Decoder.java +23 -19
 - data/ext/java/org/msgpack/jruby/Encoder.java +46 -18
 - data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +28 -40
 - data/ext/java/org/msgpack/jruby/Factory.java +40 -5
 - data/ext/java/org/msgpack/jruby/Packer.java +21 -11
 - data/ext/java/org/msgpack/jruby/Unpacker.java +44 -22
 - data/ext/msgpack/buffer.h +2 -2
 - data/ext/msgpack/buffer_class.c +23 -15
 - data/ext/msgpack/factory_class.c +78 -16
 - data/ext/msgpack/packer.c +42 -5
 - data/ext/msgpack/packer.h +24 -0
 - data/ext/msgpack/packer_class.c +29 -22
 - data/ext/msgpack/packer_ext_registry.c +23 -9
 - data/ext/msgpack/packer_ext_registry.h +38 -31
 - data/ext/msgpack/unpacker.c +72 -32
 - data/ext/msgpack/unpacker.h +2 -2
 - data/ext/msgpack/unpacker_class.c +26 -45
 - data/ext/msgpack/unpacker_ext_registry.c +40 -16
 - data/ext/msgpack/unpacker_ext_registry.h +21 -14
 - data/lib/msgpack/bigint.rb +69 -0
 - data/lib/msgpack/factory.rb +103 -0
 - data/lib/msgpack/symbol.rb +8 -1
 - data/lib/msgpack/version.rb +1 -1
 - data/lib/msgpack.rb +4 -5
 - data/spec/bigint_spec.rb +26 -0
 - data/spec/factory_spec.rb +284 -14
 - data/spec/spec_helper.rb +4 -4
 - data/spec/timestamp_spec.rb +0 -2
 - data/spec/unpacker_spec.rb +22 -3
 - metadata +4 -2
 
    
        data/ext/msgpack/packer_class.c
    CHANGED
    
    | 
         @@ -28,6 +28,8 @@ VALUE cMessagePack_Packer; 
     | 
|
| 
       28 
28 
     | 
    
         
             
            static ID s_to_msgpack;
         
     | 
| 
       29 
29 
     | 
    
         
             
            static ID s_write;
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
      
 31 
     | 
    
         
            +
            static VALUE sym_compatibility_mode;
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
       31 
33 
     | 
    
         
             
            //static VALUE s_packer_value;
         
     | 
| 
       32 
34 
     | 
    
         
             
            //static msgpack_packer_t* s_packer;
         
     | 
| 
       33 
35 
     | 
    
         | 
| 
         @@ -68,29 +70,28 @@ VALUE MessagePack_Packer_alloc(VALUE klass) 
     | 
|
| 
       68 
70 
     | 
    
         | 
| 
       69 
71 
     | 
    
         
             
            VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
         
     | 
| 
       70 
72 
     | 
    
         
             
            {
         
     | 
| 
      
 73 
     | 
    
         
            +
                if(argc > 2) {
         
     | 
| 
      
 74 
     | 
    
         
            +
                    rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
         
     | 
| 
      
 75 
     | 
    
         
            +
                }
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
       71 
77 
     | 
    
         
             
                VALUE io = Qnil;
         
     | 
| 
       72 
78 
     | 
    
         
             
                VALUE options = Qnil;
         
     | 
| 
       73 
79 
     | 
    
         | 
| 
       74 
     | 
    
         
            -
                if(argc  
     | 
| 
       75 
     | 
    
         
            -
                    /* Qnil */
         
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
                } else if(argc == 1) {
         
     | 
| 
       78 
     | 
    
         
            -
                    VALUE v = argv[0];
         
     | 
| 
       79 
     | 
    
         
            -
                    if(rb_type(v) == T_HASH) {
         
     | 
| 
       80 
     | 
    
         
            -
                        options = v;
         
     | 
| 
       81 
     | 
    
         
            -
                    } else {
         
     | 
| 
       82 
     | 
    
         
            -
                        io = v;
         
     | 
| 
       83 
     | 
    
         
            -
                    }
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                } else if(argc == 2) {
         
     | 
| 
      
 80 
     | 
    
         
            +
                if(argc >= 1) {
         
     | 
| 
       86 
81 
     | 
    
         
             
                    io = argv[0];
         
     | 
| 
      
 82 
     | 
    
         
            +
                }
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                if(argc == 2) {
         
     | 
| 
       87 
85 
     | 
    
         
             
                    options = argv[1];
         
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
                        rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
         
     | 
| 
       90 
     | 
    
         
            -
                    }
         
     | 
| 
      
 86 
     | 
    
         
            +
                }
         
     | 
| 
       91 
87 
     | 
    
         | 
| 
       92 
     | 
    
         
            -
                 
     | 
| 
       93 
     | 
    
         
            -
                     
     | 
| 
      
 88 
     | 
    
         
            +
                if (options == Qnil && rb_type(io) == T_HASH) {
         
     | 
| 
      
 89 
     | 
    
         
            +
                    options = io;
         
     | 
| 
      
 90 
     | 
    
         
            +
                    io = Qnil;
         
     | 
| 
      
 91 
     | 
    
         
            +
                }
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                if(options != Qnil) {
         
     | 
| 
      
 94 
     | 
    
         
            +
                    Check_Type(options, T_HASH);
         
     | 
| 
       94 
95 
     | 
    
         
             
                }
         
     | 
| 
       95 
96 
     | 
    
         | 
| 
       96 
97 
     | 
    
         
             
                PACKER(self, pk);
         
     | 
| 
         @@ -103,7 +104,7 @@ VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self) 
     | 
|
| 
       103 
104 
     | 
    
         
             
                if(options != Qnil) {
         
     | 
| 
       104 
105 
     | 
    
         
             
                    VALUE v;
         
     | 
| 
       105 
106 
     | 
    
         | 
| 
       106 
     | 
    
         
            -
                    v = rb_hash_aref(options,  
     | 
| 
      
 107 
     | 
    
         
            +
                    v = rb_hash_aref(options, sym_compatibility_mode);
         
     | 
| 
       107 
108 
     | 
    
         
             
                    msgpack_packer_set_compat(pk, RTEST(v));
         
     | 
| 
       108 
109 
     | 
    
         
             
                }
         
     | 
| 
       109 
110 
     | 
    
         | 
| 
         @@ -281,7 +282,7 @@ static VALUE Packer_flush(VALUE self) 
     | 
|
| 
       281 
282 
     | 
    
         
             
                return self;
         
     | 
| 
       282 
283 
     | 
    
         
             
            }
         
     | 
| 
       283 
284 
     | 
    
         | 
| 
       284 
     | 
    
         
            -
            static VALUE  
     | 
| 
      
 285 
     | 
    
         
            +
            static VALUE Packer_reset(VALUE self)
         
     | 
| 
       285 
286 
     | 
    
         
             
            {
         
     | 
| 
       286 
287 
     | 
    
         
             
                PACKER(self, pk);
         
     | 
| 
       287 
288 
     | 
    
         
             
                msgpack_buffer_clear(PACKER_BUFFER_(pk));
         
     | 
| 
         @@ -339,7 +340,10 @@ static VALUE Packer_write_to(VALUE self, VALUE io) 
     | 
|
| 
       339 
340 
     | 
    
         
             
            static VALUE Packer_registered_types_internal(VALUE self)
         
     | 
| 
       340 
341 
     | 
    
         
             
            {
         
     | 
| 
       341 
342 
     | 
    
         
             
                PACKER(self, pk);
         
     | 
| 
       342 
     | 
    
         
            -
                 
     | 
| 
      
 343 
     | 
    
         
            +
                if (RTEST(pk->ext_registry.hash)) {
         
     | 
| 
      
 344 
     | 
    
         
            +
                    return rb_hash_dup(pk->ext_registry.hash);
         
     | 
| 
      
 345 
     | 
    
         
            +
                }
         
     | 
| 
      
 346 
     | 
    
         
            +
                return rb_hash_new();
         
     | 
| 
       343 
347 
     | 
    
         
             
            }
         
     | 
| 
       344 
348 
     | 
    
         | 
| 
       345 
349 
     | 
    
         
             
            static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
         
     | 
| 
         @@ -377,7 +381,7 @@ static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self) 
     | 
|
| 
       377 
381 
     | 
    
         
             
                    rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
         
     | 
| 
       378 
382 
     | 
    
         
             
                }
         
     | 
| 
       379 
383 
     | 
    
         | 
| 
       380 
     | 
    
         
            -
                msgpack_packer_ext_registry_put(&pk->ext_registry, ext_module, ext_type, proc, arg);
         
     | 
| 
      
 384 
     | 
    
         
            +
                msgpack_packer_ext_registry_put(&pk->ext_registry, ext_module, ext_type, 0, proc, arg);
         
     | 
| 
       381 
385 
     | 
    
         | 
| 
       382 
386 
     | 
    
         
             
                if (ext_module == rb_cSymbol) {
         
     | 
| 
       383 
387 
     | 
    
         
             
                    pk->has_symbol_ext_type = true;
         
     | 
| 
         @@ -409,6 +413,8 @@ void MessagePack_Packer_module_init(VALUE mMessagePack) 
     | 
|
| 
       409 
413 
     | 
    
         
             
                s_to_msgpack = rb_intern("to_msgpack");
         
     | 
| 
       410 
414 
     | 
    
         
             
                s_write = rb_intern("write");
         
     | 
| 
       411 
415 
     | 
    
         | 
| 
      
 416 
     | 
    
         
            +
                sym_compatibility_mode = ID2SYM(rb_intern("compatibility_mode"));
         
     | 
| 
      
 417 
     | 
    
         
            +
             
     | 
| 
       412 
418 
     | 
    
         
             
                msgpack_packer_static_init();
         
     | 
| 
       413 
419 
     | 
    
         
             
                msgpack_packer_ext_registry_static_init();
         
     | 
| 
       414 
420 
     | 
    
         | 
| 
         @@ -440,7 +446,8 @@ void MessagePack_Packer_module_init(VALUE mMessagePack) 
     | 
|
| 
       440 
446 
     | 
    
         
             
                rb_define_method(cMessagePack_Packer, "flush", Packer_flush, 0);
         
     | 
| 
       441 
447 
     | 
    
         | 
| 
       442 
448 
     | 
    
         
             
                /* delegation methods */
         
     | 
| 
       443 
     | 
    
         
            -
                rb_define_method(cMessagePack_Packer, " 
     | 
| 
      
 449 
     | 
    
         
            +
                rb_define_method(cMessagePack_Packer, "reset", Packer_reset, 0);
         
     | 
| 
      
 450 
     | 
    
         
            +
                rb_define_alias(cMessagePack_Packer, "clear", "reset");
         
     | 
| 
       444 
451 
     | 
    
         
             
                rb_define_method(cMessagePack_Packer, "size", Packer_size, 0);
         
     | 
| 
       445 
452 
     | 
    
         
             
                rb_define_method(cMessagePack_Packer, "empty?", Packer_empty_p, 0);
         
     | 
| 
       446 
453 
     | 
    
         
             
                rb_define_method(cMessagePack_Packer, "write_to", Packer_write_to, 1);
         
     | 
| 
         @@ -30,8 +30,8 @@ void msgpack_packer_ext_registry_static_destroy() 
     | 
|
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
            void msgpack_packer_ext_registry_init(msgpack_packer_ext_registry_t* pkrg)
         
     | 
| 
       32 
32 
     | 
    
         
             
            {
         
     | 
| 
       33 
     | 
    
         
            -
                pkrg->hash =  
     | 
| 
       34 
     | 
    
         
            -
                pkrg->cache =  
     | 
| 
      
 33 
     | 
    
         
            +
                pkrg->hash = Qnil;
         
     | 
| 
      
 34 
     | 
    
         
            +
                pkrg->cache = Qnil;
         
     | 
| 
       35 
35 
     | 
    
         
             
            }
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
            void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
         
     | 
| 
         @@ -43,15 +43,29 @@ void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg) 
     | 
|
| 
       43 
43 
     | 
    
         
             
            void msgpack_packer_ext_registry_dup(msgpack_packer_ext_registry_t* src,
         
     | 
| 
       44 
44 
     | 
    
         
             
                    msgpack_packer_ext_registry_t* dst)
         
     | 
| 
       45 
45 
     | 
    
         
             
            {
         
     | 
| 
       46 
     | 
    
         
            -
                 
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
      
 46 
     | 
    
         
            +
                if(RTEST(src->hash) && !rb_obj_frozen_p(src->hash)) {
         
     | 
| 
      
 47 
     | 
    
         
            +
                    dst->hash = rb_hash_dup(src->hash);
         
     | 
| 
      
 48 
     | 
    
         
            +
                    dst->cache = RTEST(src->cache) ? rb_hash_dup(src->cache) : Qnil;
         
     | 
| 
      
 49 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 50 
     | 
    
         
            +
                    // If the type registry is frozen we can safely share it, and share the cache as well.
         
     | 
| 
      
 51 
     | 
    
         
            +
                    dst->hash = src->hash;
         
     | 
| 
      
 52 
     | 
    
         
            +
                    dst->cache = src->cache;
         
     | 
| 
      
 53 
     | 
    
         
            +
                }
         
     | 
| 
       48 
54 
     | 
    
         
             
            }
         
     | 
| 
       49 
55 
     | 
    
         | 
| 
       50 
56 
     | 
    
         
             
            VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
         
     | 
| 
       51 
     | 
    
         
            -
                    VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg)
         
     | 
| 
       52 
58 
     | 
    
         
             
            {
         
     | 
| 
       53 
     | 
    
         
            -
                 
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
                 
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
      
 59 
     | 
    
         
            +
                if (!RTEST(pkrg->hash)) {
         
     | 
| 
      
 60 
     | 
    
         
            +
                    pkrg->hash = rb_hash_new();
         
     | 
| 
      
 61 
     | 
    
         
            +
                }
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                if (RTEST(pkrg->cache)) {
         
     | 
| 
      
 64 
     | 
    
         
            +
                    /* clear lookup cache not to miss added type */
         
     | 
| 
      
 65 
     | 
    
         
            +
                    rb_hash_clear(pkrg->cache);
         
     | 
| 
      
 66 
     | 
    
         
            +
                }
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                // TODO: Ruby embeded array limit is 3, merging `proc` and `arg` would be good.
         
     | 
| 
      
 69 
     | 
    
         
            +
                VALUE entry = rb_ary_new3(4, INT2FIX(ext_type), proc, arg, INT2FIX(flags));
         
     | 
| 
      
 70 
     | 
    
         
            +
                return rb_hash_aset(pkrg->hash, ext_module, entry);
         
     | 
| 
       57 
71 
     | 
    
         
             
            }
         
     | 
| 
         @@ -21,6 +21,8 @@ 
     | 
|
| 
       21 
21 
     | 
    
         
             
            #include "compat.h"
         
     | 
| 
       22 
22 
     | 
    
         
             
            #include "ruby.h"
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
            #define MSGPACK_EXT_RECURSIVE 0b0001
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
       24 
26 
     | 
    
         
             
            struct msgpack_packer_ext_registry_t;
         
     | 
| 
       25 
27 
     | 
    
         
             
            typedef struct msgpack_packer_ext_registry_t msgpack_packer_ext_registry_t;
         
     | 
| 
       26 
28 
     | 
    
         | 
| 
         @@ -44,7 +46,7 @@ void msgpack_packer_ext_registry_dup(msgpack_packer_ext_registry_t* src, 
     | 
|
| 
       44 
46 
     | 
    
         
             
                    msgpack_packer_ext_registry_t* dst);
         
     | 
| 
       45 
47 
     | 
    
         | 
| 
       46 
48 
     | 
    
         
             
            VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
         
     | 
| 
       47 
     | 
    
         
            -
                    VALUE ext_module, int ext_type, VALUE proc, VALUE arg);
         
     | 
| 
      
 49 
     | 
    
         
            +
                    VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg);
         
     | 
| 
       48 
50 
     | 
    
         | 
| 
       49 
51 
     | 
    
         
             
            static int msgpack_packer_ext_find_superclass(VALUE key, VALUE value, VALUE arg)
         
     | 
| 
       50 
52 
     | 
    
         
             
            {
         
     | 
| 
         @@ -60,59 +62,60 @@ static int msgpack_packer_ext_find_superclass(VALUE key, VALUE value, VALUE arg) 
     | 
|
| 
       60 
62 
     | 
    
         
             
            }
         
     | 
| 
       61 
63 
     | 
    
         | 
| 
       62 
64 
     | 
    
         
             
            static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registry_t* pkrg,
         
     | 
| 
       63 
     | 
    
         
            -
                    VALUE lookup_class, int* ext_type_result)
         
     | 
| 
      
 65 
     | 
    
         
            +
                    VALUE lookup_class, int* ext_type_result, int* ext_flags_result)
         
     | 
| 
       64 
66 
     | 
    
         
             
            {
         
     | 
| 
       65 
67 
     | 
    
         
             
                // fetch lookup_class from hash, which is a hash to register classes
         
     | 
| 
       66 
68 
     | 
    
         
             
                VALUE type = rb_hash_lookup(pkrg->hash, lookup_class);
         
     | 
| 
       67 
69 
     | 
    
         
             
                if(type != Qnil) {
         
     | 
| 
       68 
70 
     | 
    
         
             
                    *ext_type_result = FIX2INT(rb_ary_entry(type, 0));
         
     | 
| 
      
 71 
     | 
    
         
            +
                    *ext_flags_result = FIX2INT(rb_ary_entry(type, 3));
         
     | 
| 
       69 
72 
     | 
    
         
             
                    return rb_ary_entry(type, 1);
         
     | 
| 
       70 
73 
     | 
    
         
             
                }
         
     | 
| 
       71 
74 
     | 
    
         | 
| 
       72 
75 
     | 
    
         
             
                // fetch lookup_class from cache, which stores results of searching ancestors from pkrg->hash
         
     | 
| 
       73 
     | 
    
         
            -
                 
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
                     
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
      
 76 
     | 
    
         
            +
                if (RTEST(pkrg->cache)) {
         
     | 
| 
      
 77 
     | 
    
         
            +
                    VALUE type_inht = rb_hash_lookup(pkrg->cache, lookup_class);
         
     | 
| 
      
 78 
     | 
    
         
            +
                    if(type_inht != Qnil) {
         
     | 
| 
      
 79 
     | 
    
         
            +
                        *ext_type_result = FIX2INT(rb_ary_entry(type_inht, 0));
         
     | 
| 
      
 80 
     | 
    
         
            +
                        *ext_flags_result = FIX2INT(rb_ary_entry(type_inht, 3));
         
     | 
| 
      
 81 
     | 
    
         
            +
                        return rb_ary_entry(type_inht, 1);
         
     | 
| 
      
 82 
     | 
    
         
            +
                    }
         
     | 
| 
       77 
83 
     | 
    
         
             
                }
         
     | 
| 
       78 
84 
     | 
    
         | 
| 
       79 
85 
     | 
    
         
             
                return Qnil;
         
     | 
| 
       80 
86 
     | 
    
         
             
            }
         
     | 
| 
       81 
87 
     | 
    
         | 
| 
       82 
88 
     | 
    
         
             
            static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_registry_t* pkrg,
         
     | 
| 
       83 
     | 
    
         
            -
                    VALUE instance, int* ext_type_result)
         
     | 
| 
      
 89 
     | 
    
         
            +
                    VALUE instance, int* ext_type_result, int* ext_flags_result)
         
     | 
| 
       84 
90 
     | 
    
         
             
            {
         
     | 
| 
       85 
     | 
    
         
            -
                VALUE lookup_class;
         
     | 
| 
       86 
91 
     | 
    
         
             
                VALUE type;
         
     | 
| 
       87 
92 
     | 
    
         | 
| 
       88 
     | 
    
         
            -
                 
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
                 * Objects of type Integer (Fixnum, Bignum), Float, Symbol and frozen
         
     | 
| 
       92 
     | 
    
         
            -
                 * String have no singleton class and raise a TypeError when trying to get
         
     | 
| 
       93 
     | 
    
         
            -
                 * it. See implementation of #singleton_class in ruby's source code:
         
     | 
| 
       94 
     | 
    
         
            -
                 * VALUE rb_singleton_class(VALUE obj);
         
     | 
| 
       95 
     | 
    
         
            -
                 *
         
     | 
| 
       96 
     | 
    
         
            -
                 * Since all but symbols are already filtered out when reaching this code
         
     | 
| 
       97 
     | 
    
         
            -
                 * only symbols are checked here.
         
     | 
| 
       98 
     | 
    
         
            -
                 */
         
     | 
| 
       99 
     | 
    
         
            -
                if (!SYMBOL_P(instance)) {
         
     | 
| 
       100 
     | 
    
         
            -
                  lookup_class = rb_singleton_class(instance);
         
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
                  type = msgpack_packer_ext_registry_fetch(pkrg, lookup_class, ext_type_result);
         
     | 
| 
      
 93 
     | 
    
         
            +
                if (pkrg->hash == Qnil) { // No extensions registered
         
     | 
| 
      
 94 
     | 
    
         
            +
                    return Qnil;
         
     | 
| 
      
 95 
     | 
    
         
            +
                }
         
     | 
| 
       103 
96 
     | 
    
         | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
      
 97 
     | 
    
         
            +
               /*
         
     | 
| 
      
 98 
     | 
    
         
            +
                * 1. check whether singleton_class or class of this instance is registered (or resolved in past) or not.
         
     | 
| 
      
 99 
     | 
    
         
            +
                *
         
     | 
| 
      
 100 
     | 
    
         
            +
                * Objects of type Integer (Fixnum, Bignum), Float, Symbol and frozen
         
     | 
| 
      
 101 
     | 
    
         
            +
                * `rb_class_of` returns the singleton_class if the object has one, or the "real class" otherwise.
         
     | 
| 
      
 102 
     | 
    
         
            +
                */
         
     | 
| 
      
 103 
     | 
    
         
            +
                VALUE lookup_class = rb_class_of(instance);
         
     | 
| 
      
 104 
     | 
    
         
            +
                type = msgpack_packer_ext_registry_fetch(pkrg, lookup_class, ext_type_result, ext_flags_result);
         
     | 
| 
      
 105 
     | 
    
         
            +
                if(type != Qnil) {
         
     | 
| 
      
 106 
     | 
    
         
            +
                    return type;
         
     | 
| 
       107 
107 
     | 
    
         
             
                }
         
     | 
| 
       108 
108 
     | 
    
         | 
| 
       109 
109 
     | 
    
         
             
                /*
         
     | 
| 
       110 
     | 
    
         
            -
                 * 2. check the class of instance is registered 
     | 
| 
      
 110 
     | 
    
         
            +
                 * 2. If the object had a singleton_class check if the real class of instance is registered
         
     | 
| 
      
 111 
     | 
    
         
            +
                 * (or resolved in past) or not.
         
     | 
| 
       111 
112 
     | 
    
         
             
                 */
         
     | 
| 
       112 
     | 
    
         
            -
                 
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
                     
     | 
| 
      
 113 
     | 
    
         
            +
                VALUE real_class = rb_obj_class(instance);
         
     | 
| 
      
 114 
     | 
    
         
            +
                if(lookup_class != real_class) {
         
     | 
| 
      
 115 
     | 
    
         
            +
                    type = msgpack_packer_ext_registry_fetch(pkrg, real_class, ext_type_result, ext_flags_result);
         
     | 
| 
      
 116 
     | 
    
         
            +
                    if(type != Qnil) {
         
     | 
| 
      
 117 
     | 
    
         
            +
                        return type;
         
     | 
| 
      
 118 
     | 
    
         
            +
                    }
         
     | 
| 
       116 
119 
     | 
    
         
             
                }
         
     | 
| 
       117 
120 
     | 
    
         | 
| 
       118 
121 
     | 
    
         
             
                /*
         
     | 
| 
         @@ -126,8 +129,12 @@ static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_regist 
     | 
|
| 
       126 
129 
     | 
    
         
             
                VALUE superclass = args[1];
         
     | 
| 
       127 
130 
     | 
    
         
             
                if(superclass != Qnil) {
         
     | 
| 
       128 
131 
     | 
    
         
             
                    VALUE superclass_type = rb_hash_lookup(pkrg->hash, superclass);
         
     | 
| 
      
 132 
     | 
    
         
            +
                    if (!RTEST(pkrg->cache)) {
         
     | 
| 
      
 133 
     | 
    
         
            +
                        pkrg->cache = rb_hash_new();
         
     | 
| 
      
 134 
     | 
    
         
            +
                    }
         
     | 
| 
       129 
135 
     | 
    
         
             
                    rb_hash_aset(pkrg->cache, lookup_class, superclass_type);
         
     | 
| 
       130 
136 
     | 
    
         
             
                    *ext_type_result = FIX2INT(rb_ary_entry(superclass_type, 0));
         
     | 
| 
      
 137 
     | 
    
         
            +
                    *ext_flags_result = FIX2INT(rb_ary_entry(superclass_type, 3));
         
     | 
| 
       131 
138 
     | 
    
         
             
                    return rb_ary_entry(superclass_type, 1);
         
     | 
| 
       132 
139 
     | 
    
         
             
                }
         
     | 
| 
       133 
140 
     | 
    
         | 
    
        data/ext/msgpack/unpacker.c
    CHANGED
    
    | 
         @@ -52,9 +52,19 @@ void msgpack_unpacker_static_destroy() 
     | 
|
| 
       52 
52 
     | 
    
         | 
| 
       53 
53 
     | 
    
         
             
            #define HEAD_BYTE_REQUIRED 0xc1
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
      
 55 
     | 
    
         
            +
            static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
         
     | 
| 
      
 56 
     | 
    
         
            +
            #ifdef UNPACKER_STACK_RMEM
         
     | 
| 
      
 57 
     | 
    
         
            +
                return msgpack_rmem_alloc(&s_stack_rmem);
         
     | 
| 
      
 58 
     | 
    
         
            +
                /*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
         
     | 
| 
      
 59 
     | 
    
         
            +
            #else
         
     | 
| 
      
 60 
     | 
    
         
            +
                /*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_t));*/
         
     | 
| 
      
 61 
     | 
    
         
            +
                return xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_t));
         
     | 
| 
      
 62 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 63 
     | 
    
         
            +
            }
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            msgpack_unpacker_t* _msgpack_unpacker_new(void)
         
     | 
| 
       56 
66 
     | 
    
         
             
            {
         
     | 
| 
       57 
     | 
    
         
            -
                 
     | 
| 
      
 67 
     | 
    
         
            +
                msgpack_unpacker_t* uk = ZALLOC_N(msgpack_unpacker_t, 1);
         
     | 
| 
       58 
68 
     | 
    
         | 
| 
       59 
69 
     | 
    
         
             
                msgpack_buffer_init(UNPACKER_BUFFER_(uk));
         
     | 
| 
       60 
70 
     | 
    
         | 
| 
         @@ -63,24 +73,23 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk) 
     | 
|
| 
       63 
73 
     | 
    
         
             
                uk->last_object = Qnil;
         
     | 
| 
       64 
74 
     | 
    
         
             
                uk->reading_raw = Qnil;
         
     | 
| 
       65 
75 
     | 
    
         | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
                uk->stack = msgpack_rmem_alloc(&s_stack_rmem);
         
     | 
| 
       68 
     | 
    
         
            -
                /*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
         
     | 
| 
       69 
     | 
    
         
            -
            #else
         
     | 
| 
       70 
     | 
    
         
            -
                /*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_t));*/
         
     | 
| 
       71 
     | 
    
         
            -
                uk->stack = xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_t));
         
     | 
| 
       72 
     | 
    
         
            -
            #endif
         
     | 
| 
      
 76 
     | 
    
         
            +
                uk->stack = _msgpack_unpacker_new_stack();
         
     | 
| 
       73 
77 
     | 
    
         
             
                uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                return uk;
         
     | 
| 
      
 80 
     | 
    
         
            +
            }
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
            static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
         
     | 
| 
      
 83 
     | 
    
         
            +
                #ifdef UNPACKER_STACK_RMEM
         
     | 
| 
      
 84 
     | 
    
         
            +
                    msgpack_rmem_free(&s_stack_rmem, stack);
         
     | 
| 
      
 85 
     | 
    
         
            +
                #else
         
     | 
| 
      
 86 
     | 
    
         
            +
                    xfree(stack);
         
     | 
| 
      
 87 
     | 
    
         
            +
                #endif
         
     | 
| 
       74 
88 
     | 
    
         
             
            }
         
     | 
| 
       75 
89 
     | 
    
         | 
| 
       76 
90 
     | 
    
         
             
            void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
         
     | 
| 
       77 
91 
     | 
    
         
             
            {
         
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
                msgpack_rmem_free(&s_stack_rmem, uk->stack);
         
     | 
| 
       80 
     | 
    
         
            -
            #else
         
     | 
| 
       81 
     | 
    
         
            -
                xfree(uk->stack);
         
     | 
| 
       82 
     | 
    
         
            -
            #endif
         
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
      
 92 
     | 
    
         
            +
                _msgpack_unpacker_free_stack(uk->stack);
         
     | 
| 
       84 
93 
     | 
    
         
             
                msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
         
     | 
| 
       85 
94 
     | 
    
         
             
            }
         
     | 
| 
       86 
95 
     | 
    
         | 
| 
         @@ -164,14 +173,17 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU 
     | 
|
| 
       164 
173 
     | 
    
         
             
                    return object_complete_symbol(uk, rb_str_intern(str));
         
     | 
| 
       165 
174 
     | 
    
         
             
                }
         
     | 
| 
       166 
175 
     | 
    
         | 
| 
       167 
     | 
    
         
            -
                 
     | 
| 
      
 176 
     | 
    
         
            +
                int ext_flags;
         
     | 
| 
      
 177 
     | 
    
         
            +
                VALUE proc = msgpack_unpacker_ext_registry_lookup(uk->ext_registry, ext_type, &ext_flags);
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
       168 
179 
     | 
    
         
             
                if(proc != Qnil) {
         
     | 
| 
       169 
     | 
    
         
            -
                    VALUE obj 
     | 
| 
      
 180 
     | 
    
         
            +
                    VALUE obj;
         
     | 
| 
      
 181 
     | 
    
         
            +
                    obj = rb_funcall(proc, s_call, 1, str == Qnil ? rb_str_buf_new(0) : str);
         
     | 
| 
       170 
182 
     | 
    
         
             
                    return object_complete(uk, obj);
         
     | 
| 
       171 
183 
     | 
    
         
             
                }
         
     | 
| 
       172 
184 
     | 
    
         | 
| 
       173 
185 
     | 
    
         
             
                if(uk->allow_unknown_ext) {
         
     | 
| 
       174 
     | 
    
         
            -
                    VALUE obj = MessagePack_ExtensionValue_new(ext_type, str);
         
     | 
| 
      
 186 
     | 
    
         
            +
                    VALUE obj = MessagePack_ExtensionValue_new(ext_type, str == Qnil ? rb_str_buf_new(0) : str);
         
     | 
| 
       175 
187 
     | 
    
         
             
                    return object_complete(uk, obj);
         
     | 
| 
       176 
188 
     | 
    
         
             
                }
         
     | 
| 
       177 
189 
     | 
    
         | 
| 
         @@ -281,29 +293,57 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type) 
     | 
|
| 
       281 
293 
     | 
    
         
             
            {
         
     | 
| 
       282 
294 
     | 
    
         
             
                /* assuming uk->reading_raw == Qnil */
         
     | 
| 
       283 
295 
     | 
    
         | 
| 
      
 296 
     | 
    
         
            +
                int ext_flags;
         
     | 
| 
      
 297 
     | 
    
         
            +
                VALUE proc;
         
     | 
| 
      
 298 
     | 
    
         
            +
             
     | 
| 
      
 299 
     | 
    
         
            +
                if(!(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY)) {
         
     | 
| 
      
 300 
     | 
    
         
            +
                    proc = msgpack_unpacker_ext_registry_lookup(uk->ext_registry, raw_type, &ext_flags);
         
     | 
| 
      
 301 
     | 
    
         
            +
                    if(proc != Qnil && ext_flags & MSGPACK_EXT_RECURSIVE) {
         
     | 
| 
      
 302 
     | 
    
         
            +
                        VALUE obj;
         
     | 
| 
      
 303 
     | 
    
         
            +
                        uk->last_object = Qnil;
         
     | 
| 
      
 304 
     | 
    
         
            +
                        reset_head_byte(uk);
         
     | 
| 
      
 305 
     | 
    
         
            +
                        size_t ext_size = uk->reading_raw_remaining;
         
     | 
| 
      
 306 
     | 
    
         
            +
                        uk->reading_raw_remaining = 0;
         
     | 
| 
      
 307 
     | 
    
         
            +
             
     | 
| 
      
 308 
     | 
    
         
            +
                        msgpack_unpacker_stack_t* stack = uk->stack;
         
     | 
| 
      
 309 
     | 
    
         
            +
                        size_t stack_depth = uk->stack_depth;
         
     | 
| 
      
 310 
     | 
    
         
            +
                        size_t stack_capacity = uk->stack_capacity;
         
     | 
| 
      
 311 
     | 
    
         
            +
             
     | 
| 
      
 312 
     | 
    
         
            +
                        uk->stack = _msgpack_unpacker_new_stack();
         
     | 
| 
      
 313 
     | 
    
         
            +
                        uk->stack_depth = 0;
         
     | 
| 
      
 314 
     | 
    
         
            +
                        uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
         
     | 
| 
      
 315 
     | 
    
         
            +
             
     | 
| 
      
 316 
     | 
    
         
            +
                        obj = rb_funcall(proc, s_call, 1, uk->buffer.owner);
         
     | 
| 
      
 317 
     | 
    
         
            +
             
     | 
| 
      
 318 
     | 
    
         
            +
                        _msgpack_unpacker_free_stack(uk->stack);
         
     | 
| 
      
 319 
     | 
    
         
            +
                        uk->stack = stack;
         
     | 
| 
      
 320 
     | 
    
         
            +
                        uk->stack_depth = stack_depth;
         
     | 
| 
      
 321 
     | 
    
         
            +
                        uk->stack_capacity = stack_capacity;
         
     | 
| 
      
 322 
     | 
    
         
            +
             
     | 
| 
      
 323 
     | 
    
         
            +
                        msgpack_buffer_skip(UNPACKER_BUFFER_(uk), ext_size);
         
     | 
| 
      
 324 
     | 
    
         
            +
                        return object_complete(uk, obj);
         
     | 
| 
      
 325 
     | 
    
         
            +
                    }
         
     | 
| 
      
 326 
     | 
    
         
            +
                }
         
     | 
| 
      
 327 
     | 
    
         
            +
             
     | 
| 
       284 
328 
     | 
    
         
             
                /* try optimized read */
         
     | 
| 
       285 
329 
     | 
    
         
             
                size_t length = uk->reading_raw_remaining;
         
     | 
| 
       286 
330 
     | 
    
         
             
                if(length <= msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk))) {
         
     | 
| 
       287 
331 
     | 
    
         
             
                    int ret;
         
     | 
| 
       288 
332 
     | 
    
         
             
                    if ((uk->optimized_symbol_ext_type && uk->symbol_ext_type == raw_type) || (uk->symbolize_keys && is_reading_map_key(uk))) {
         
     | 
| 
       289 
     | 
    
         
            -
                        VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length);
         
     | 
| 
      
 333 
     | 
    
         
            +
                        VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, raw_type != RAW_TYPE_BINARY);
         
     | 
| 
       290 
334 
     | 
    
         
             
                        ret = object_complete_symbol(uk, symbol);
         
     | 
| 
       291 
335 
     | 
    
         
             
                    } else {
         
     | 
| 
       292 
     | 
    
         
            -
                         
     | 
| 
       293 
     | 
    
         
            -
                         * because rb_hash_aset freezes keys and it causes copying */
         
     | 
| 
       294 
     | 
    
         
            -
                        bool will_freeze = uk->freeze || is_reading_map_key(uk);
         
     | 
| 
       295 
     | 
    
         
            -
                        VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
         
     | 
| 
      
 336 
     | 
    
         
            +
                        bool will_freeze = uk->freeze;
         
     | 
| 
       296 
337 
     | 
    
         
             
                        if(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY) {
         
     | 
| 
      
 338 
     | 
    
         
            +
                           /* don't use zerocopy for hash keys but get a frozen string directly
         
     | 
| 
      
 339 
     | 
    
         
            +
                            * because rb_hash_aset freezes keys and it causes copying */
         
     | 
| 
      
 340 
     | 
    
         
            +
                            will_freeze = will_freeze || is_reading_map_key(uk);
         
     | 
| 
      
 341 
     | 
    
         
            +
                            VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
         
     | 
| 
       297 
342 
     | 
    
         
             
                            ret = object_complete(uk, string);
         
     | 
| 
       298 
343 
     | 
    
         
             
                        } else {
         
     | 
| 
      
 344 
     | 
    
         
            +
                            VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, false, false);
         
     | 
| 
       299 
345 
     | 
    
         
             
                            ret = object_complete_ext(uk, raw_type, string);
         
     | 
| 
       300 
346 
     | 
    
         
             
                        }
         
     | 
| 
       301 
     | 
    
         
            -
             
     | 
| 
       302 
     | 
    
         
            -
            # if !HASH_ASET_DEDUPE
         
     | 
| 
       303 
     | 
    
         
            -
                        if(will_freeze) {
         
     | 
| 
       304 
     | 
    
         
            -
                            rb_obj_freeze(string);
         
     | 
| 
       305 
     | 
    
         
            -
                        }
         
     | 
| 
       306 
     | 
    
         
            -
            # endif
         
     | 
| 
       307 
347 
     | 
    
         
             
                    }
         
     | 
| 
       308 
348 
     | 
    
         
             
                    uk->reading_raw_remaining = 0;
         
     | 
| 
       309 
349 
     | 
    
         
             
                    return ret;
         
     | 
| 
         @@ -373,7 +413,7 @@ static int read_primitive(msgpack_unpacker_t* uk) 
     | 
|
| 
       373 
413 
     | 
    
         
             
                            uint8_t length = cb->u8;
         
     | 
| 
       374 
414 
     | 
    
         
             
                            int ext_type = (signed char) cb->buffer[1];
         
     | 
| 
       375 
415 
     | 
    
         
             
                            if(length == 0) {
         
     | 
| 
       376 
     | 
    
         
            -
                                return object_complete_ext(uk, ext_type,  
     | 
| 
      
 416 
     | 
    
         
            +
                                return object_complete_ext(uk, ext_type, Qnil);
         
     | 
| 
       377 
417 
     | 
    
         
             
                            }
         
     | 
| 
       378 
418 
     | 
    
         
             
                            uk->reading_raw_remaining = length;
         
     | 
| 
       379 
419 
     | 
    
         
             
                            return read_raw_body_begin(uk, ext_type);
         
     | 
| 
         @@ -385,7 +425,7 @@ static int read_primitive(msgpack_unpacker_t* uk) 
     | 
|
| 
       385 
425 
     | 
    
         
             
                            uint16_t length = _msgpack_be16(cb->u16);
         
     | 
| 
       386 
426 
     | 
    
         
             
                            int ext_type = (signed char) cb->buffer[2];
         
     | 
| 
       387 
427 
     | 
    
         
             
                            if(length == 0) {
         
     | 
| 
       388 
     | 
    
         
            -
                                return object_complete_ext(uk, ext_type,  
     | 
| 
      
 428 
     | 
    
         
            +
                                return object_complete_ext(uk, ext_type, Qnil);
         
     | 
| 
       389 
429 
     | 
    
         
             
                            }
         
     | 
| 
       390 
430 
     | 
    
         
             
                            uk->reading_raw_remaining = length;
         
     | 
| 
       391 
431 
     | 
    
         
             
                            return read_raw_body_begin(uk, ext_type);
         
     | 
| 
         @@ -397,7 +437,7 @@ static int read_primitive(msgpack_unpacker_t* uk) 
     | 
|
| 
       397 
437 
     | 
    
         
             
                            uint32_t length = _msgpack_be32(cb->u32);
         
     | 
| 
       398 
438 
     | 
    
         
             
                            int ext_type = (signed char) cb->buffer[4];
         
     | 
| 
       399 
439 
     | 
    
         
             
                            if(length == 0) {
         
     | 
| 
       400 
     | 
    
         
            -
                                return object_complete_ext(uk, ext_type,  
     | 
| 
      
 440 
     | 
    
         
            +
                                return object_complete_ext(uk, ext_type, Qnil);
         
     | 
| 
       401 
441 
     | 
    
         
             
                            }
         
     | 
| 
       402 
442 
     | 
    
         
             
                            uk->reading_raw_remaining = length;
         
     | 
| 
       403 
443 
     | 
    
         
             
                            return read_raw_body_begin(uk, ext_type);
         
     | 
    
        data/ext/msgpack/unpacker.h
    CHANGED
    
    | 
         @@ -60,7 +60,7 @@ struct msgpack_unpacker_t { 
     | 
|
| 
       60 
60 
     | 
    
         | 
| 
       61 
61 
     | 
    
         
             
                VALUE buffer_ref;
         
     | 
| 
       62 
62 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
                msgpack_unpacker_ext_registry_t ext_registry;
         
     | 
| 
      
 63 
     | 
    
         
            +
                msgpack_unpacker_ext_registry_t *ext_registry;
         
     | 
| 
       64 
64 
     | 
    
         | 
| 
       65 
65 
     | 
    
         
             
                /* options */
         
     | 
| 
       66 
66 
     | 
    
         
             
                bool symbolize_keys;
         
     | 
| 
         @@ -86,7 +86,7 @@ void msgpack_unpacker_static_init(); 
     | 
|
| 
       86 
86 
     | 
    
         | 
| 
       87 
87 
     | 
    
         
             
            void msgpack_unpacker_static_destroy();
         
     | 
| 
       88 
88 
     | 
    
         | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
      
 89 
     | 
    
         
            +
            msgpack_unpacker_t* _msgpack_unpacker_new(void);
         
     | 
| 
       90 
90 
     | 
    
         | 
| 
       91 
91 
     | 
    
         
             
            void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk);
         
     | 
| 
       92 
92 
     | 
    
         | 
| 
         @@ -33,6 +33,10 @@ static VALUE eUnexpectedTypeError; 
     | 
|
| 
       33 
33 
     | 
    
         
             
            static VALUE eUnknownExtTypeError;
         
     | 
| 
       34 
34 
     | 
    
         
             
            static VALUE mTypeError;  // obsoleted. only for backward compatibility. See #86.
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
      
 36 
     | 
    
         
            +
            static VALUE sym_symbolize_keys;
         
     | 
| 
      
 37 
     | 
    
         
            +
            static VALUE sym_freeze;
         
     | 
| 
      
 38 
     | 
    
         
            +
            static VALUE sym_allow_unknown_ext;
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
       36 
40 
     | 
    
         
             
            #define UNPACKER(from, name) \
         
     | 
| 
       37 
41 
     | 
    
         
             
                msgpack_unpacker_t *name = NULL; \
         
     | 
| 
       38 
42 
     | 
    
         
             
                Data_Get_Struct(from, msgpack_unpacker_t, name); \
         
     | 
| 
         @@ -45,7 +49,7 @@ static void Unpacker_free(msgpack_unpacker_t* uk) 
     | 
|
| 
       45 
49 
     | 
    
         
             
                if(uk == NULL) {
         
     | 
| 
       46 
50 
     | 
    
         
             
                    return;
         
     | 
| 
       47 
51 
     | 
    
         
             
                }
         
     | 
| 
       48 
     | 
    
         
            -
                 
     | 
| 
      
 52 
     | 
    
         
            +
                msgpack_unpacker_ext_registry_release(uk->ext_registry);
         
     | 
| 
       49 
53 
     | 
    
         
             
                _msgpack_unpacker_destroy(uk);
         
     | 
| 
       50 
54 
     | 
    
         
             
                xfree(uk);
         
     | 
| 
       51 
55 
     | 
    
         
             
            }
         
     | 
| 
         @@ -53,13 +57,12 @@ static void Unpacker_free(msgpack_unpacker_t* uk) 
     | 
|
| 
       53 
57 
     | 
    
         
             
            static void Unpacker_mark(msgpack_unpacker_t* uk)
         
     | 
| 
       54 
58 
     | 
    
         
             
            {
         
     | 
| 
       55 
59 
     | 
    
         
             
                msgpack_unpacker_mark(uk);
         
     | 
| 
       56 
     | 
    
         
            -
                msgpack_unpacker_ext_registry_mark( 
     | 
| 
      
 60 
     | 
    
         
            +
                msgpack_unpacker_ext_registry_mark(uk->ext_registry);
         
     | 
| 
       57 
61 
     | 
    
         
             
            }
         
     | 
| 
       58 
62 
     | 
    
         | 
| 
       59 
63 
     | 
    
         
             
            VALUE MessagePack_Unpacker_alloc(VALUE klass)
         
     | 
| 
       60 
64 
     | 
    
         
             
            {
         
     | 
| 
       61 
     | 
    
         
            -
                msgpack_unpacker_t* uk =  
     | 
| 
       62 
     | 
    
         
            -
                _msgpack_unpacker_init(uk);
         
     | 
| 
      
 65 
     | 
    
         
            +
                msgpack_unpacker_t* uk = _msgpack_unpacker_new();
         
     | 
| 
       63 
66 
     | 
    
         | 
| 
       64 
67 
     | 
    
         
             
                VALUE self = Data_Wrap_Struct(klass, Unpacker_mark, Unpacker_free, uk);
         
     | 
| 
       65 
68 
     | 
    
         
             
                return self;
         
     | 
| 
         @@ -84,7 +87,7 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self) 
     | 
|
| 
       84 
87 
     | 
    
         
             
                } else if(argc == 2) {
         
     | 
| 
       85 
88 
     | 
    
         
             
                    io = argv[0];
         
     | 
| 
       86 
89 
     | 
    
         
             
                    options = argv[1];
         
     | 
| 
       87 
     | 
    
         
            -
                    if(rb_type(options) != T_HASH) {
         
     | 
| 
      
 90 
     | 
    
         
            +
                    if(options != Qnil && rb_type(options) != T_HASH) {
         
     | 
| 
       88 
91 
     | 
    
         
             
                        rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
         
     | 
| 
       89 
92 
     | 
    
         
             
                    }
         
     | 
| 
       90 
93 
     | 
    
         | 
| 
         @@ -94,7 +97,6 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self) 
     | 
|
| 
       94 
97 
     | 
    
         | 
| 
       95 
98 
     | 
    
         
             
                UNPACKER(self, uk);
         
     | 
| 
       96 
99 
     | 
    
         | 
| 
       97 
     | 
    
         
            -
                msgpack_unpacker_ext_registry_init(&uk->ext_registry);
         
     | 
| 
       98 
100 
     | 
    
         
             
                uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
         
     | 
| 
       99 
101 
     | 
    
         | 
| 
       100 
102 
     | 
    
         
             
                MessagePack_Buffer_set_options(UNPACKER_BUFFER_(uk), io, options);
         
     | 
| 
         @@ -102,13 +104,13 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self) 
     | 
|
| 
       102 
104 
     | 
    
         
             
                if(options != Qnil) {
         
     | 
| 
       103 
105 
     | 
    
         
             
                    VALUE v;
         
     | 
| 
       104 
106 
     | 
    
         | 
| 
       105 
     | 
    
         
            -
                    v = rb_hash_aref(options,  
     | 
| 
      
 107 
     | 
    
         
            +
                    v = rb_hash_aref(options, sym_symbolize_keys);
         
     | 
| 
       106 
108 
     | 
    
         
             
                    msgpack_unpacker_set_symbolized_keys(uk, RTEST(v));
         
     | 
| 
       107 
109 
     | 
    
         | 
| 
       108 
     | 
    
         
            -
                    v = rb_hash_aref(options,  
     | 
| 
      
 110 
     | 
    
         
            +
                    v = rb_hash_aref(options, sym_freeze);
         
     | 
| 
       109 
111 
     | 
    
         
             
                    msgpack_unpacker_set_freeze(uk, RTEST(v));
         
     | 
| 
       110 
112 
     | 
    
         | 
| 
       111 
     | 
    
         
            -
                    v = rb_hash_aref(options,  
     | 
| 
      
 113 
     | 
    
         
            +
                    v = rb_hash_aref(options, sym_allow_unknown_ext);
         
     | 
| 
       112 
114 
     | 
    
         
             
                    msgpack_unpacker_set_allow_unknown_ext(uk, RTEST(v));
         
     | 
| 
       113 
115 
     | 
    
         
             
                }
         
     | 
| 
       114 
116 
     | 
    
         | 
| 
         @@ -133,7 +135,7 @@ static VALUE Unpacker_allow_unknown_ext_p(VALUE self) 
     | 
|
| 
       133 
135 
     | 
    
         
             
                return uk->allow_unknown_ext ? Qtrue : Qfalse;
         
     | 
| 
       134 
136 
     | 
    
         
             
            }
         
     | 
| 
       135 
137 
     | 
    
         | 
| 
       136 
     | 
    
         
            -
            static void raise_unpacker_error(int r)
         
     | 
| 
      
 138 
     | 
    
         
            +
            NORETURN(static void raise_unpacker_error(int r))
         
     | 
| 
       137 
139 
     | 
    
         
             
            {
         
     | 
| 
       138 
140 
     | 
    
         
             
                switch(r) {
         
     | 
| 
       139 
141 
     | 
    
         
             
                case PRIMITIVE_EOF:
         
     | 
| 
         @@ -145,6 +147,7 @@ static void raise_unpacker_error(int r) 
     | 
|
| 
       145 
147 
     | 
    
         
             
                case PRIMITIVE_UNEXPECTED_TYPE:
         
     | 
| 
       146 
148 
     | 
    
         
             
                    rb_raise(eUnexpectedTypeError, "unexpected type");
         
     | 
| 
       147 
149 
     | 
    
         
             
                case PRIMITIVE_UNEXPECTED_EXT_TYPE:
         
     | 
| 
      
 150 
     | 
    
         
            +
                // rb_bug("unexpected extension type");
         
     | 
| 
       148 
151 
     | 
    
         
             
                    rb_raise(eUnknownExtTypeError, "unexpected extension type");
         
     | 
| 
       149 
152 
     | 
    
         
             
                default:
         
     | 
| 
       150 
153 
     | 
    
         
             
                    rb_raise(eUnpackError, "logically unknown error %d", r);
         
     | 
| 
         @@ -222,34 +225,6 @@ static VALUE Unpacker_read_map_header(VALUE self) 
     | 
|
| 
       222 
225 
     | 
    
         
             
                return ULONG2NUM(size);
         
     | 
| 
       223 
226 
     | 
    
         
             
            }
         
     | 
| 
       224 
227 
     | 
    
         | 
| 
       225 
     | 
    
         
            -
            static VALUE Unpacker_peek_next_type(VALUE self)
         
     | 
| 
       226 
     | 
    
         
            -
            {
         
     | 
| 
       227 
     | 
    
         
            -
                UNPACKER(self, uk);
         
     | 
| 
       228 
     | 
    
         
            -
             
     | 
| 
       229 
     | 
    
         
            -
                int r = msgpack_unpacker_peek_next_object_type(uk);
         
     | 
| 
       230 
     | 
    
         
            -
                if(r < 0) {
         
     | 
| 
       231 
     | 
    
         
            -
                    raise_unpacker_error(r);
         
     | 
| 
       232 
     | 
    
         
            -
                }
         
     | 
| 
       233 
     | 
    
         
            -
             
     | 
| 
       234 
     | 
    
         
            -
                switch((enum msgpack_unpacker_object_type) r) {
         
     | 
| 
       235 
     | 
    
         
            -
                case TYPE_NIL:
         
     | 
| 
       236 
     | 
    
         
            -
                    return rb_intern("nil");
         
     | 
| 
       237 
     | 
    
         
            -
                case TYPE_BOOLEAN:
         
     | 
| 
       238 
     | 
    
         
            -
                    return rb_intern("boolean");
         
     | 
| 
       239 
     | 
    
         
            -
                case TYPE_INTEGER:
         
     | 
| 
       240 
     | 
    
         
            -
                    return rb_intern("integer");
         
     | 
| 
       241 
     | 
    
         
            -
                case TYPE_FLOAT:
         
     | 
| 
       242 
     | 
    
         
            -
                    return rb_intern("float");
         
     | 
| 
       243 
     | 
    
         
            -
                case TYPE_RAW:
         
     | 
| 
       244 
     | 
    
         
            -
                    return rb_intern("raw");
         
     | 
| 
       245 
     | 
    
         
            -
                case TYPE_ARRAY:
         
     | 
| 
       246 
     | 
    
         
            -
                    return rb_intern("array");
         
     | 
| 
       247 
     | 
    
         
            -
                case TYPE_MAP:
         
     | 
| 
       248 
     | 
    
         
            -
                    return rb_intern("map");
         
     | 
| 
       249 
     | 
    
         
            -
                default:
         
     | 
| 
       250 
     | 
    
         
            -
                    rb_raise(eUnpackError, "logically unknown type %d", r);
         
     | 
| 
       251 
     | 
    
         
            -
                }
         
     | 
| 
       252 
     | 
    
         
            -
            }
         
     | 
| 
       253 
228 
     | 
    
         | 
| 
       254 
229 
     | 
    
         
             
            static VALUE Unpacker_feed(VALUE self, VALUE data)
         
     | 
| 
       255 
230 
     | 
    
         
             
            {
         
     | 
| 
         @@ -296,9 +271,10 @@ static VALUE Unpacker_each_impl(VALUE self) 
     | 
|
| 
       296 
271 
     | 
    
         
             
                }
         
     | 
| 
       297 
272 
     | 
    
         
             
            }
         
     | 
| 
       298 
273 
     | 
    
         | 
| 
       299 
     | 
    
         
            -
            static VALUE Unpacker_rescue_EOFError(VALUE  
     | 
| 
      
 274 
     | 
    
         
            +
            static VALUE Unpacker_rescue_EOFError(VALUE args, VALUE error)
         
     | 
| 
       300 
275 
     | 
    
         
             
            {
         
     | 
| 
       301 
     | 
    
         
            -
                UNUSED( 
     | 
| 
      
 276 
     | 
    
         
            +
                UNUSED(args);
         
     | 
| 
      
 277 
     | 
    
         
            +
                UNUSED(error);
         
     | 
| 
       302 
278 
     | 
    
         
             
                return Qnil;
         
     | 
| 
       303 
279 
     | 
    
         
             
            }
         
     | 
| 
       304 
280 
     | 
    
         | 
| 
         @@ -347,9 +323,11 @@ static VALUE Unpacker_registered_types_internal(VALUE self) 
     | 
|
| 
       347 
323 
     | 
    
         
             
                UNPACKER(self, uk);
         
     | 
| 
       348 
324 
     | 
    
         | 
| 
       349 
325 
     | 
    
         
             
                VALUE mapping = rb_hash_new();
         
     | 
| 
       350 
     | 
    
         
            -
                 
     | 
| 
       351 
     | 
    
         
            -
                     
     | 
| 
       352 
     | 
    
         
            -
                         
     | 
| 
      
 326 
     | 
    
         
            +
                if (uk->ext_registry) {
         
     | 
| 
      
 327 
     | 
    
         
            +
                    for(int i=0; i < 256; i++) {
         
     | 
| 
      
 328 
     | 
    
         
            +
                        if(uk->ext_registry->array[i] != Qnil) {
         
     | 
| 
      
 329 
     | 
    
         
            +
                            rb_hash_aset(mapping, INT2FIX(i - 128), uk->ext_registry->array[i]);
         
     | 
| 
      
 330 
     | 
    
         
            +
                        }
         
     | 
| 
       353 
331 
     | 
    
         
             
                    }
         
     | 
| 
       354 
332 
     | 
    
         
             
                }
         
     | 
| 
       355 
333 
     | 
    
         | 
| 
         @@ -388,7 +366,7 @@ static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self) 
     | 
|
| 
       388 
366 
     | 
    
         
             
                    rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
         
     | 
| 
       389 
367 
     | 
    
         
             
                }
         
     | 
| 
       390 
368 
     | 
    
         | 
| 
       391 
     | 
    
         
            -
                msgpack_unpacker_ext_registry_put(&uk->ext_registry, ext_module, ext_type, proc, arg);
         
     | 
| 
      
 369 
     | 
    
         
            +
                msgpack_unpacker_ext_registry_put(&uk->ext_registry, ext_module, ext_type, 0, proc, arg);
         
     | 
| 
       392 
370 
     | 
    
         | 
| 
       393 
371 
     | 
    
         
             
                return Qnil;
         
     | 
| 
       394 
372 
     | 
    
         
             
            }
         
     | 
| 
         @@ -438,6 +416,10 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack) 
     | 
|
| 
       438 
416 
     | 
    
         | 
| 
       439 
417 
     | 
    
         
             
                eUnknownExtTypeError = rb_define_class_under(mMessagePack, "UnknownExtTypeError", eUnpackError);
         
     | 
| 
       440 
418 
     | 
    
         | 
| 
      
 419 
     | 
    
         
            +
                sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
         
     | 
| 
      
 420 
     | 
    
         
            +
                sym_freeze = ID2SYM(rb_intern("freeze"));
         
     | 
| 
      
 421 
     | 
    
         
            +
                sym_allow_unknown_ext = ID2SYM(rb_intern("allow_unknown_ext"));
         
     | 
| 
      
 422 
     | 
    
         
            +
             
     | 
| 
       441 
423 
     | 
    
         
             
                rb_define_alloc_func(cMessagePack_Unpacker, MessagePack_Unpacker_alloc);
         
     | 
| 
       442 
424 
     | 
    
         | 
| 
       443 
425 
     | 
    
         
             
                rb_define_method(cMessagePack_Unpacker, "initialize", MessagePack_Unpacker_initialize, -1);
         
     | 
| 
         @@ -451,7 +433,6 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack) 
     | 
|
| 
       451 
433 
     | 
    
         
             
                rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
         
     | 
| 
       452 
434 
     | 
    
         
             
                rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
         
     | 
| 
       453 
435 
     | 
    
         
             
                rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
         
     | 
| 
       454 
     | 
    
         
            -
                //rb_define_method(cMessagePack_Unpacker, "peek_next_type", Unpacker_peek_next_type, 0);  // TODO
         
     | 
| 
       455 
436 
     | 
    
         
             
                rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1);
         
     | 
| 
       456 
437 
     | 
    
         
             
                rb_define_method(cMessagePack_Unpacker, "feed_reference", Unpacker_feed_reference, 1);
         
     | 
| 
       457 
438 
     | 
    
         
             
                rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
         
     |