msgpack 1.7.0 → 1.7.2
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/ChangeLog +11 -0
- data/ext/java/org/msgpack/jruby/Buffer.java +3 -3
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +7 -11
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +1 -1
- data/ext/java/org/msgpack/jruby/Factory.java +11 -50
- data/ext/java/org/msgpack/jruby/Packer.java +9 -27
- data/ext/java/org/msgpack/jruby/Unpacker.java +15 -35
- data/ext/msgpack/buffer.c +7 -5
- data/ext/msgpack/buffer.h +3 -1
- data/ext/msgpack/buffer_class.c +72 -1
- data/ext/msgpack/buffer_class.h +1 -0
- data/ext/msgpack/extconf.rb +16 -12
- data/ext/msgpack/factory_class.c +27 -61
- data/ext/msgpack/packer.c +12 -14
- data/ext/msgpack/packer.h +0 -4
- data/ext/msgpack/packer_class.c +12 -37
- data/ext/msgpack/packer_ext_registry.c +31 -28
- data/ext/msgpack/packer_ext_registry.h +10 -14
- data/ext/msgpack/unpacker.c +9 -10
- data/ext/msgpack/unpacker_class.c +5 -30
- data/ext/msgpack/unpacker_ext_registry.c +4 -16
- data/ext/msgpack/unpacker_ext_registry.h +3 -7
- data/lib/msgpack/factory.rb +49 -10
- data/lib/msgpack/packer.rb +6 -1
- data/lib/msgpack/unpacker.rb +10 -1
- data/lib/msgpack/version.rb +1 -1
- metadata +3 -3
data/ext/msgpack/factory_class.c
CHANGED
@@ -75,7 +75,7 @@ static const rb_data_type_t factory_data_type = {
|
|
75
75
|
.dfree = Factory_free,
|
76
76
|
.dsize = Factory_memsize,
|
77
77
|
},
|
78
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
78
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
79
79
|
};
|
80
80
|
|
81
81
|
static inline msgpack_factory_t *Factory_get(VALUE object)
|
@@ -98,7 +98,7 @@ static VALUE Factory_initialize(int argc, VALUE* argv, VALUE self)
|
|
98
98
|
{
|
99
99
|
msgpack_factory_t *fc = Factory_get(self);
|
100
100
|
|
101
|
-
msgpack_packer_ext_registry_init(&fc->pkrg);
|
101
|
+
msgpack_packer_ext_registry_init(self, &fc->pkrg);
|
102
102
|
// fc->ukrg is lazily initialized
|
103
103
|
|
104
104
|
fc->has_symbol_ext_type = false;
|
@@ -124,7 +124,7 @@ static VALUE Factory_dup(VALUE self)
|
|
124
124
|
cloned_fc->has_symbol_ext_type = fc->has_symbol_ext_type;
|
125
125
|
cloned_fc->pkrg = fc->pkrg;
|
126
126
|
msgpack_unpacker_ext_registry_borrow(fc->ukrg, &cloned_fc->ukrg);
|
127
|
-
msgpack_packer_ext_registry_dup(&fc->pkrg, &cloned_fc->pkrg);
|
127
|
+
msgpack_packer_ext_registry_dup(clone, &fc->pkrg, &cloned_fc->pkrg);
|
128
128
|
|
129
129
|
return clone;
|
130
130
|
}
|
@@ -139,7 +139,7 @@ static VALUE Factory_freeze(VALUE self) {
|
|
139
139
|
// If the factory is frozen, we can safely share the packer cache between
|
140
140
|
// all packers. So we eagerly create it now so it's available when #packer
|
141
141
|
// is called.
|
142
|
-
fc->pkrg.cache
|
142
|
+
RB_OBJ_WRITE(self, &fc->pkrg.cache, rb_hash_new());
|
143
143
|
}
|
144
144
|
}
|
145
145
|
|
@@ -158,7 +158,7 @@ VALUE MessagePack_Factory_packer(int argc, VALUE* argv, VALUE self)
|
|
158
158
|
|
159
159
|
msgpack_packer_t* pk = MessagePack_Packer_get(packer);
|
160
160
|
msgpack_packer_ext_registry_destroy(&pk->ext_registry);
|
161
|
-
|
161
|
+
msgpack_packer_ext_registry_borrow(packer, &fc->pkrg, &pk->ext_registry);
|
162
162
|
pk->has_bigint_ext_type = fc->has_bigint_ext_type;
|
163
163
|
pk->has_symbol_ext_type = fc->has_symbol_ext_type;
|
164
164
|
|
@@ -187,7 +187,7 @@ static VALUE Factory_registered_types_internal(VALUE self)
|
|
187
187
|
VALUE uk_mapping = rb_hash_new();
|
188
188
|
if (fc->ukrg) {
|
189
189
|
for(int i=0; i < 256; i++) {
|
190
|
-
if(fc->ukrg->array[i]
|
190
|
+
if(!NIL_P(fc->ukrg->array[i])) {
|
191
191
|
rb_hash_aset(uk_mapping, INT2FIX(i - 128), fc->ukrg->array[i]);
|
192
192
|
}
|
193
193
|
}
|
@@ -200,73 +200,39 @@ static VALUE Factory_registered_types_internal(VALUE self)
|
|
200
200
|
);
|
201
201
|
}
|
202
202
|
|
203
|
-
static VALUE
|
203
|
+
static VALUE Factory_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE options)
|
204
204
|
{
|
205
205
|
msgpack_factory_t *fc = Factory_get(self);
|
206
206
|
|
207
|
-
|
208
|
-
int flags = 0;
|
209
|
-
VALUE ext_module;
|
210
|
-
VALUE options = Qnil;
|
211
|
-
VALUE packer_arg, unpacker_arg;
|
212
|
-
VALUE packer_proc, unpacker_proc;
|
207
|
+
Check_Type(rb_ext_type, T_FIXNUM);
|
213
208
|
|
214
|
-
if
|
215
|
-
rb_raise(
|
209
|
+
if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
|
210
|
+
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
216
211
|
}
|
217
212
|
|
218
|
-
|
219
|
-
case 2:
|
220
|
-
/* register_type(0x7f, Time) */
|
221
|
-
packer_arg = ID2SYM(rb_intern("to_msgpack_ext"));
|
222
|
-
unpacker_arg = ID2SYM(rb_intern("from_msgpack_ext"));
|
223
|
-
break;
|
224
|
-
case 3:
|
225
|
-
/* register_type(0x7f, Time, packer: proc-like, unapcker: proc-like) */
|
226
|
-
options = argv[2];
|
227
|
-
if(rb_type(options) != T_HASH) {
|
228
|
-
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
|
229
|
-
}
|
230
|
-
packer_arg = rb_hash_aref(options, ID2SYM(rb_intern("packer")));
|
231
|
-
unpacker_arg = rb_hash_aref(options, ID2SYM(rb_intern("unpacker")));
|
232
|
-
break;
|
233
|
-
default:
|
234
|
-
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2..3)", argc);
|
235
|
-
}
|
213
|
+
int flags = 0;
|
236
214
|
|
237
|
-
|
215
|
+
VALUE packer_proc = Qnil;
|
216
|
+
VALUE unpacker_proc = Qnil;
|
217
|
+
if(!NIL_P(options)) {
|
238
218
|
Check_Type(options, T_HASH);
|
219
|
+
packer_proc = rb_hash_aref(options, ID2SYM(rb_intern("packer")));
|
220
|
+
unpacker_proc = rb_hash_aref(options, ID2SYM(rb_intern("unpacker")));
|
239
221
|
}
|
240
222
|
|
241
|
-
|
242
|
-
|
243
|
-
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
244
|
-
}
|
245
|
-
|
246
|
-
ext_module = argv[1];
|
247
|
-
if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
|
248
|
-
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
249
|
-
}
|
250
|
-
|
251
|
-
packer_proc = Qnil;
|
252
|
-
unpacker_proc = Qnil;
|
253
|
-
|
254
|
-
if(packer_arg != Qnil) {
|
255
|
-
packer_proc = rb_funcall(packer_arg, rb_intern("to_proc"), 0);
|
223
|
+
if (OBJ_FROZEN(self)) {
|
224
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Factory");
|
256
225
|
}
|
257
226
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
} else if (rb_respond_to(unpacker_arg, rb_intern("call"))) {
|
262
|
-
unpacker_proc = unpacker_arg;
|
263
|
-
} else {
|
264
|
-
unpacker_proc = rb_funcall(unpacker_arg, rb_intern("method"), 1, ID2SYM(rb_intern("call")));
|
265
|
-
}
|
227
|
+
int ext_type = NUM2INT(rb_ext_type);
|
228
|
+
if(ext_type < -128 || ext_type > 127) {
|
229
|
+
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
266
230
|
}
|
267
231
|
|
268
232
|
if(ext_module == rb_cSymbol) {
|
269
|
-
|
233
|
+
if(NIL_P(options) || RTEST(rb_hash_aref(options, ID2SYM(rb_intern("packer"))))) {
|
234
|
+
fc->has_symbol_ext_type = true;
|
235
|
+
}
|
270
236
|
if(RTEST(options) && RTEST(rb_hash_aref(options, ID2SYM(rb_intern("optimized_symbols_parsing"))))) {
|
271
237
|
fc->optimized_symbol_ext_type = true;
|
272
238
|
}
|
@@ -286,8 +252,8 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
286
252
|
}
|
287
253
|
}
|
288
254
|
|
289
|
-
msgpack_packer_ext_registry_put(&fc->pkrg, ext_module, ext_type, flags, packer_proc
|
290
|
-
msgpack_unpacker_ext_registry_put(&fc->ukrg, ext_module, ext_type, flags, unpacker_proc
|
255
|
+
msgpack_packer_ext_registry_put(self, &fc->pkrg, ext_module, ext_type, flags, packer_proc);
|
256
|
+
msgpack_unpacker_ext_registry_put(self, &fc->ukrg, ext_module, ext_type, flags, unpacker_proc);
|
291
257
|
|
292
258
|
return Qnil;
|
293
259
|
}
|
@@ -306,5 +272,5 @@ void MessagePack_Factory_module_init(VALUE mMessagePack)
|
|
306
272
|
rb_define_method(cMessagePack_Factory, "unpacker", MessagePack_Factory_unpacker, -1);
|
307
273
|
|
308
274
|
rb_define_private_method(cMessagePack_Factory, "registered_types_internal", Factory_registered_types_internal, 0);
|
309
|
-
|
275
|
+
rb_define_private_method(cMessagePack_Factory, "register_type_internal", Factory_register_type_internal, 3);
|
310
276
|
}
|
data/ext/msgpack/packer.c
CHANGED
@@ -17,16 +17,11 @@
|
|
17
17
|
*/
|
18
18
|
|
19
19
|
#include "packer.h"
|
20
|
+
#include "buffer_class.h"
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
{
|
25
|
-
s_call = rb_intern("call");
|
26
|
-
}
|
27
|
-
|
28
|
-
void msgpack_packer_static_destroy(void)
|
29
|
-
{ }
|
22
|
+
#if !defined(HAVE_RB_PROC_CALL_WITH_BLOCK)
|
23
|
+
#define rb_proc_call_with_block(recv, argc, argv, block) rb_funcallv(recv, rb_intern("call"), argc, argv)
|
24
|
+
#endif
|
30
25
|
|
31
26
|
void msgpack_packer_init(msgpack_packer_t* pk)
|
32
27
|
{
|
@@ -100,14 +95,13 @@ struct msgpack_call_proc_args_t;
|
|
100
95
|
typedef struct msgpack_call_proc_args_t msgpack_call_proc_args_t;
|
101
96
|
struct msgpack_call_proc_args_t {
|
102
97
|
VALUE proc;
|
103
|
-
VALUE
|
104
|
-
VALUE packer;
|
98
|
+
VALUE args[2];
|
105
99
|
};
|
106
100
|
|
107
101
|
VALUE msgpack_packer_try_calling_proc(VALUE value)
|
108
102
|
{
|
109
103
|
msgpack_call_proc_args_t *args = (msgpack_call_proc_args_t *)value;
|
110
|
-
return
|
104
|
+
return rb_proc_call_with_block(args->proc, 2, args->args, Qnil);
|
111
105
|
}
|
112
106
|
|
113
107
|
bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v)
|
@@ -121,11 +115,13 @@ bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v
|
|
121
115
|
}
|
122
116
|
|
123
117
|
if(ext_flags & MSGPACK_EXT_RECURSIVE) {
|
118
|
+
VALUE held_buffer = MessagePack_Buffer_hold(&pk->buffer);
|
119
|
+
|
124
120
|
msgpack_buffer_t parent_buffer = pk->buffer;
|
125
121
|
msgpack_buffer_init(PACKER_BUFFER_(pk));
|
126
122
|
|
127
123
|
int exception_occured = 0;
|
128
|
-
msgpack_call_proc_args_t args = { proc, v, pk->to_msgpack_arg };
|
124
|
+
msgpack_call_proc_args_t args = { proc, { v, pk->to_msgpack_arg } };
|
129
125
|
rb_protect(msgpack_packer_try_calling_proc, (VALUE)&args, &exception_occured);
|
130
126
|
|
131
127
|
if (exception_occured) {
|
@@ -139,8 +135,10 @@ bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v
|
|
139
135
|
pk->buffer = parent_buffer;
|
140
136
|
msgpack_packer_write_ext(pk, ext_type, payload);
|
141
137
|
}
|
138
|
+
|
139
|
+
RB_GC_GUARD(held_buffer);
|
142
140
|
} else {
|
143
|
-
VALUE payload =
|
141
|
+
VALUE payload = rb_proc_call_with_block(proc, 1, &v, Qnil);
|
144
142
|
StringValue(payload);
|
145
143
|
msgpack_packer_write_ext(pk, ext_type, payload);
|
146
144
|
}
|
data/ext/msgpack/packer.h
CHANGED
@@ -47,10 +47,6 @@ struct msgpack_packer_t {
|
|
47
47
|
|
48
48
|
#define PACKER_BUFFER_(pk) (&(pk)->buffer)
|
49
49
|
|
50
|
-
void msgpack_packer_static_init(void);
|
51
|
-
|
52
|
-
void msgpack_packer_static_destroy(void);
|
53
|
-
|
54
50
|
void msgpack_packer_init(msgpack_packer_t* pk);
|
55
51
|
|
56
52
|
void msgpack_packer_destroy(msgpack_packer_t* pk);
|
data/ext/msgpack/packer_class.c
CHANGED
@@ -106,8 +106,8 @@ VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
|
|
106
106
|
|
107
107
|
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
108
108
|
|
109
|
-
msgpack_packer_ext_registry_init(&pk->ext_registry);
|
110
|
-
pk->buffer_ref =
|
109
|
+
msgpack_packer_ext_registry_init(self, &pk->ext_registry);
|
110
|
+
pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self);
|
111
111
|
|
112
112
|
MessagePack_Buffer_set_options(PACKER_BUFFER_(pk), io, options);
|
113
113
|
|
@@ -233,7 +233,12 @@ static VALUE Packer_write_extension(VALUE self, VALUE obj)
|
|
233
233
|
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
234
234
|
Check_Type(obj, T_STRUCT);
|
235
235
|
|
236
|
-
|
236
|
+
VALUE rb_ext_type = RSTRUCT_GET(obj, 0);
|
237
|
+
if(!RB_TYPE_P(rb_ext_type, T_FIXNUM)) {
|
238
|
+
rb_raise(rb_eRangeError, "integer %s too big to convert to `signed char'", RSTRING_PTR(rb_String(rb_ext_type)));
|
239
|
+
}
|
240
|
+
|
241
|
+
int ext_type = FIX2INT(rb_ext_type);
|
237
242
|
if(ext_type < -128 || ext_type > 127) {
|
238
243
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
239
244
|
}
|
@@ -347,7 +352,7 @@ static VALUE Packer_registered_types_internal(VALUE self)
|
|
347
352
|
return rb_hash_new();
|
348
353
|
}
|
349
354
|
|
350
|
-
static VALUE
|
355
|
+
static VALUE Packer_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
|
351
356
|
{
|
352
357
|
if (OBJ_FROZEN(self)) {
|
353
358
|
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Packer");
|
@@ -355,38 +360,12 @@ static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
|
|
355
360
|
|
356
361
|
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
357
362
|
|
358
|
-
int ext_type;
|
359
|
-
VALUE ext_module;
|
360
|
-
VALUE proc;
|
361
|
-
VALUE arg;
|
362
|
-
|
363
|
-
switch (argc) {
|
364
|
-
case 2:
|
365
|
-
/* register_type(0x7f, Time) {|obj| block... } */
|
366
|
-
rb_need_block();
|
367
|
-
proc = rb_block_lambda();
|
368
|
-
arg = proc;
|
369
|
-
break;
|
370
|
-
case 3:
|
371
|
-
/* register_type(0x7f, Time, :to_msgpack_ext) */
|
372
|
-
arg = argv[2];
|
373
|
-
proc = rb_funcall(arg, rb_intern("to_proc"), 0);
|
374
|
-
break;
|
375
|
-
default:
|
376
|
-
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2..3)", argc);
|
377
|
-
}
|
378
|
-
|
379
|
-
ext_type = NUM2INT(argv[0]);
|
363
|
+
int ext_type = NUM2INT(rb_ext_type);
|
380
364
|
if(ext_type < -128 || ext_type > 127) {
|
381
365
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
382
366
|
}
|
383
367
|
|
384
|
-
ext_module
|
385
|
-
if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
|
386
|
-
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
387
|
-
}
|
388
|
-
|
389
|
-
msgpack_packer_ext_registry_put(&pk->ext_registry, ext_module, ext_type, 0, proc, arg);
|
368
|
+
msgpack_packer_ext_registry_put(self, &pk->ext_registry, ext_module, ext_type, 0, proc);
|
390
369
|
|
391
370
|
if (ext_module == rb_cSymbol) {
|
392
371
|
pk->has_symbol_ext_type = true;
|
@@ -419,10 +398,6 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
|
|
419
398
|
s_write = rb_intern("write");
|
420
399
|
|
421
400
|
sym_compatibility_mode = ID2SYM(rb_intern("compatibility_mode"));
|
422
|
-
|
423
|
-
msgpack_packer_static_init();
|
424
|
-
msgpack_packer_ext_registry_static_init();
|
425
|
-
|
426
401
|
cMessagePack_Packer = rb_define_class_under(mMessagePack, "Packer", rb_cObject);
|
427
402
|
|
428
403
|
rb_define_alloc_func(cMessagePack_Packer, MessagePack_Packer_alloc);
|
@@ -461,7 +436,7 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
|
|
461
436
|
rb_define_method(cMessagePack_Packer, "to_a", Packer_to_a, 0);
|
462
437
|
|
463
438
|
rb_define_private_method(cMessagePack_Packer, "registered_types_internal", Packer_registered_types_internal, 0);
|
464
|
-
rb_define_method(cMessagePack_Packer, "
|
439
|
+
rb_define_method(cMessagePack_Packer, "register_type_internal", Packer_register_type_internal, 3);
|
465
440
|
|
466
441
|
rb_define_method(cMessagePack_Packer, "full_pack", Packer_full_pack, 0);
|
467
442
|
}
|
@@ -18,20 +18,10 @@
|
|
18
18
|
|
19
19
|
#include "packer_ext_registry.h"
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
void msgpack_packer_ext_registry_static_init(void)
|
24
|
-
{
|
25
|
-
s_call = rb_intern("call");
|
26
|
-
}
|
27
|
-
|
28
|
-
void msgpack_packer_ext_registry_static_destroy(void)
|
29
|
-
{ }
|
30
|
-
|
31
|
-
void msgpack_packer_ext_registry_init(msgpack_packer_ext_registry_t* pkrg)
|
21
|
+
void msgpack_packer_ext_registry_init(VALUE owner, msgpack_packer_ext_registry_t* pkrg)
|
32
22
|
{
|
33
|
-
pkrg->hash
|
34
|
-
pkrg->cache
|
23
|
+
RB_OBJ_WRITE(owner, &pkrg->hash, Qnil);
|
24
|
+
RB_OBJ_WRITE(owner, &pkrg->cache, Qnil);
|
35
25
|
}
|
36
26
|
|
37
27
|
void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
|
@@ -40,32 +30,45 @@ void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
|
|
40
30
|
rb_gc_mark(pkrg->cache);
|
41
31
|
}
|
42
32
|
|
43
|
-
void
|
33
|
+
void msgpack_packer_ext_registry_borrow(VALUE owner, msgpack_packer_ext_registry_t* src,
|
44
34
|
msgpack_packer_ext_registry_t* dst)
|
45
35
|
{
|
46
|
-
if(RTEST(src->hash)
|
47
|
-
|
48
|
-
|
36
|
+
if(RTEST(src->hash)) {
|
37
|
+
if(rb_obj_frozen_p(src->hash)) {
|
38
|
+
// If the type registry is frozen we can safely share it, and share the cache as well.
|
39
|
+
RB_OBJ_WRITE(owner, &dst->hash, src->hash);
|
40
|
+
RB_OBJ_WRITE(owner, &dst->cache, src->cache);
|
41
|
+
} else {
|
42
|
+
RB_OBJ_WRITE(owner, &dst->hash, rb_hash_dup(src->hash));
|
43
|
+
RB_OBJ_WRITE(owner, &dst->cache, NIL_P(src->cache) ? Qnil : rb_hash_dup(src->cache));
|
44
|
+
}
|
49
45
|
} else {
|
50
|
-
|
51
|
-
dst->
|
52
|
-
dst->cache = src->cache;
|
46
|
+
RB_OBJ_WRITE(owner, &dst->hash, Qnil);
|
47
|
+
RB_OBJ_WRITE(owner, &dst->cache, Qnil);
|
53
48
|
}
|
54
49
|
}
|
55
50
|
|
56
|
-
VALUE
|
57
|
-
|
51
|
+
void msgpack_packer_ext_registry_dup(VALUE owner, msgpack_packer_ext_registry_t* src,
|
52
|
+
msgpack_packer_ext_registry_t* dst)
|
58
53
|
{
|
59
|
-
|
60
|
-
|
54
|
+
RB_OBJ_WRITE(owner, &dst->hash, NIL_P(src->hash) ? Qnil : rb_hash_dup(src->hash));
|
55
|
+
RB_OBJ_WRITE(owner, &dst->cache, NIL_P(src->cache) ? Qnil : rb_hash_dup(src->cache));
|
56
|
+
}
|
57
|
+
|
58
|
+
void msgpack_packer_ext_registry_put(VALUE owner, msgpack_packer_ext_registry_t* pkrg,
|
59
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc)
|
60
|
+
{
|
61
|
+
if(NIL_P(pkrg->hash)) {
|
62
|
+
RB_OBJ_WRITE(owner, &pkrg->hash, rb_hash_new());
|
61
63
|
}
|
62
64
|
|
63
|
-
if
|
65
|
+
if(NIL_P(pkrg->cache)) {
|
66
|
+
RB_OBJ_WRITE(owner, &pkrg->cache, rb_hash_new());
|
67
|
+
} else {
|
64
68
|
/* clear lookup cache not to miss added type */
|
65
69
|
rb_hash_clear(pkrg->cache);
|
66
70
|
}
|
67
71
|
|
68
|
-
|
69
|
-
|
70
|
-
return rb_hash_aset(pkrg->hash, ext_module, entry);
|
72
|
+
VALUE entry = rb_ary_new3(3, INT2FIX(ext_type), proc, INT2FIX(flags));
|
73
|
+
rb_hash_aset(pkrg->hash, ext_module, entry);
|
71
74
|
}
|
@@ -31,22 +31,21 @@ struct msgpack_packer_ext_registry_t {
|
|
31
31
|
VALUE cache; // lookup cache for ext types inherited from a super class
|
32
32
|
};
|
33
33
|
|
34
|
-
void
|
35
|
-
|
36
|
-
void msgpack_packer_ext_registry_static_destroy(void);
|
37
|
-
|
38
|
-
void msgpack_packer_ext_registry_init(msgpack_packer_ext_registry_t* pkrg);
|
34
|
+
void msgpack_packer_ext_registry_init(VALUE owner, msgpack_packer_ext_registry_t* pkrg);
|
39
35
|
|
40
36
|
static inline void msgpack_packer_ext_registry_destroy(msgpack_packer_ext_registry_t* pkrg)
|
41
37
|
{ }
|
42
38
|
|
43
39
|
void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg);
|
44
40
|
|
45
|
-
void
|
41
|
+
void msgpack_packer_ext_registry_borrow(VALUE owner, msgpack_packer_ext_registry_t* src,
|
46
42
|
msgpack_packer_ext_registry_t* dst);
|
47
43
|
|
48
|
-
VALUE
|
49
|
-
|
44
|
+
void msgpack_packer_ext_registry_dup(VALUE owner, msgpack_packer_ext_registry_t* src,
|
45
|
+
msgpack_packer_ext_registry_t* dst);
|
46
|
+
|
47
|
+
void msgpack_packer_ext_registry_put(VALUE owner, msgpack_packer_ext_registry_t* pkrg,
|
48
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc);
|
50
49
|
|
51
50
|
static int msgpack_packer_ext_find_superclass(VALUE key, VALUE value, VALUE arg)
|
52
51
|
{
|
@@ -68,7 +67,7 @@ static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registr
|
|
68
67
|
VALUE type = rb_hash_lookup(pkrg->hash, lookup_class);
|
69
68
|
if(type != Qnil) {
|
70
69
|
*ext_type_result = FIX2INT(rb_ary_entry(type, 0));
|
71
|
-
*ext_flags_result = FIX2INT(rb_ary_entry(type,
|
70
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(type, 2));
|
72
71
|
return rb_ary_entry(type, 1);
|
73
72
|
}
|
74
73
|
|
@@ -77,7 +76,7 @@ static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registr
|
|
77
76
|
VALUE type_inht = rb_hash_lookup(pkrg->cache, lookup_class);
|
78
77
|
if(type_inht != Qnil) {
|
79
78
|
*ext_type_result = FIX2INT(rb_ary_entry(type_inht, 0));
|
80
|
-
*ext_flags_result = FIX2INT(rb_ary_entry(type_inht,
|
79
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(type_inht, 2));
|
81
80
|
return rb_ary_entry(type_inht, 1);
|
82
81
|
}
|
83
82
|
}
|
@@ -129,12 +128,9 @@ static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_regist
|
|
129
128
|
VALUE superclass = args[1];
|
130
129
|
if(superclass != Qnil) {
|
131
130
|
VALUE superclass_type = rb_hash_lookup(pkrg->hash, superclass);
|
132
|
-
if (!RTEST(pkrg->cache)) {
|
133
|
-
pkrg->cache = rb_hash_new();
|
134
|
-
}
|
135
131
|
rb_hash_aset(pkrg->cache, lookup_class, superclass_type);
|
136
132
|
*ext_type_result = FIX2INT(rb_ary_entry(superclass_type, 0));
|
137
|
-
*ext_flags_result = FIX2INT(rb_ary_entry(superclass_type,
|
133
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(superclass_type, 2));
|
138
134
|
return rb_ary_entry(superclass_type, 1);
|
139
135
|
}
|
140
136
|
|
data/ext/msgpack/unpacker.c
CHANGED
@@ -19,17 +19,15 @@
|
|
19
19
|
#include "unpacker.h"
|
20
20
|
#include "rmem.h"
|
21
21
|
#include "extension_value_class.h"
|
22
|
+
#include <assert.h>
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
);
|
24
|
+
#if !defined(HAVE_RB_PROC_CALL_WITH_BLOCK)
|
25
|
+
#define rb_proc_call_with_block(recv, argc, argv, block) rb_funcallv(recv, rb_intern("call"), argc, argv)
|
26
|
+
#endif
|
27
27
|
|
28
28
|
static int RAW_TYPE_STRING = 256;
|
29
29
|
static int RAW_TYPE_BINARY = 257;
|
30
30
|
|
31
|
-
static ID s_call;
|
32
|
-
|
33
31
|
static msgpack_rmem_t s_stack_rmem;
|
34
32
|
|
35
33
|
#if !defined(HAVE_RB_HASH_NEW_CAPA)
|
@@ -41,9 +39,9 @@ static inline VALUE rb_hash_new_capa(long capa)
|
|
41
39
|
|
42
40
|
void msgpack_unpacker_static_init(void)
|
43
41
|
{
|
44
|
-
|
42
|
+
assert(sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE);
|
45
43
|
|
46
|
-
|
44
|
+
msgpack_rmem_init(&s_stack_rmem);
|
47
45
|
}
|
48
46
|
|
49
47
|
void msgpack_unpacker_static_destroy(void)
|
@@ -180,7 +178,8 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
180
178
|
|
181
179
|
if(proc != Qnil) {
|
182
180
|
VALUE obj;
|
183
|
-
|
181
|
+
VALUE arg = (str == Qnil ? rb_str_buf_new(0) : str);
|
182
|
+
obj = rb_proc_call_with_block(proc, 1, &arg, Qnil);
|
184
183
|
return object_complete(uk, obj);
|
185
184
|
}
|
186
185
|
|
@@ -310,7 +309,7 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
310
309
|
child_stack->parent = uk->stack;
|
311
310
|
uk->stack = child_stack;
|
312
311
|
|
313
|
-
obj =
|
312
|
+
obj = rb_proc_call_with_block(proc, 1, &uk->self, Qnil);
|
314
313
|
|
315
314
|
uk->stack = child_stack->parent;
|
316
315
|
_msgpack_unpacker_free_stack(child_stack);
|
@@ -346,43 +346,19 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
|
|
346
346
|
return mapping;
|
347
347
|
}
|
348
348
|
|
349
|
-
static VALUE
|
349
|
+
static VALUE Unpacker_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
|
350
350
|
{
|
351
351
|
if (OBJ_FROZEN(self)) {
|
352
352
|
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Unpacker");
|
353
353
|
}
|
354
354
|
|
355
|
-
|
356
|
-
|
357
|
-
int ext_type;
|
358
|
-
VALUE proc;
|
359
|
-
VALUE arg;
|
360
|
-
VALUE ext_module;
|
361
|
-
|
362
|
-
switch (argc) {
|
363
|
-
case 1:
|
364
|
-
/* register_type(0x7f) {|data| block... } */
|
365
|
-
rb_need_block();
|
366
|
-
proc = rb_block_lambda();
|
367
|
-
arg = proc;
|
368
|
-
ext_module = Qnil;
|
369
|
-
break;
|
370
|
-
case 3:
|
371
|
-
/* register_type(0x7f, Time, :from_msgpack_ext) */
|
372
|
-
ext_module = argv[1];
|
373
|
-
arg = argv[2];
|
374
|
-
proc = rb_obj_method(ext_module, arg);
|
375
|
-
break;
|
376
|
-
default:
|
377
|
-
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 3)", argc);
|
378
|
-
}
|
379
|
-
|
380
|
-
ext_type = NUM2INT(argv[0]);
|
355
|
+
int ext_type = NUM2INT(rb_ext_type);
|
381
356
|
if(ext_type < -128 || ext_type > 127) {
|
382
357
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
383
358
|
}
|
384
359
|
|
385
|
-
|
360
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
361
|
+
msgpack_unpacker_ext_registry_put(self, &uk->ext_registry, ext_module, ext_type, 0, proc);
|
386
362
|
|
387
363
|
return Qnil;
|
388
364
|
}
|
@@ -415,7 +391,6 @@ VALUE MessagePack_Unpacker_new(int argc, VALUE* argv)
|
|
415
391
|
void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
416
392
|
{
|
417
393
|
msgpack_unpacker_static_init();
|
418
|
-
msgpack_unpacker_ext_registry_static_init();
|
419
394
|
|
420
395
|
mTypeError = rb_define_module_under(mMessagePack, "TypeError");
|
421
396
|
|
@@ -456,7 +431,7 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
456
431
|
rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
|
457
432
|
|
458
433
|
rb_define_private_method(cMessagePack_Unpacker, "registered_types_internal", Unpacker_registered_types_internal, 0);
|
459
|
-
|
434
|
+
rb_define_private_method(cMessagePack_Unpacker, "register_type_internal", Unpacker_register_type_internal, 3);
|
460
435
|
|
461
436
|
rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
|
462
437
|
}
|
@@ -18,19 +18,6 @@
|
|
18
18
|
|
19
19
|
#include "unpacker_ext_registry.h"
|
20
20
|
|
21
|
-
static ID s_call;
|
22
|
-
static ID s_dup;
|
23
|
-
|
24
|
-
void msgpack_unpacker_ext_registry_static_init(void)
|
25
|
-
{
|
26
|
-
s_call = rb_intern("call");
|
27
|
-
s_dup = rb_intern("dup");
|
28
|
-
}
|
29
|
-
|
30
|
-
|
31
|
-
void msgpack_unpacker_ext_registry_static_destroy(void)
|
32
|
-
{ }
|
33
|
-
|
34
21
|
void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg)
|
35
22
|
{
|
36
23
|
if (ukrg) {
|
@@ -76,11 +63,12 @@ void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg
|
|
76
63
|
}
|
77
64
|
}
|
78
65
|
|
79
|
-
void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
|
80
|
-
VALUE ext_module, int ext_type, int flags, VALUE proc
|
66
|
+
void msgpack_unpacker_ext_registry_put(VALUE owner, msgpack_unpacker_ext_registry_t** ukrg,
|
67
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc)
|
81
68
|
{
|
82
69
|
msgpack_unpacker_ext_registry_t* ext_registry = msgpack_unpacker_ext_registry_cow(*ukrg);
|
83
70
|
|
84
|
-
|
71
|
+
VALUE entry = rb_ary_new3(3, ext_module, proc, INT2FIX(flags));
|
72
|
+
RB_OBJ_WRITE(owner, &ext_registry->array[ext_type + 128], entry);
|
85
73
|
*ukrg = ext_registry;
|
86
74
|
}
|
@@ -31,10 +31,6 @@ struct msgpack_unpacker_ext_registry_t {
|
|
31
31
|
VALUE array[256];
|
32
32
|
};
|
33
33
|
|
34
|
-
void msgpack_unpacker_ext_registry_static_init(void);
|
35
|
-
|
36
|
-
void msgpack_unpacker_ext_registry_static_destroy(void);
|
37
|
-
|
38
34
|
void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg);
|
39
35
|
|
40
36
|
static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_registry_t* src, msgpack_unpacker_ext_registry_t** dst)
|
@@ -47,8 +43,8 @@ static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_reg
|
|
47
43
|
|
48
44
|
void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg);
|
49
45
|
|
50
|
-
void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
|
51
|
-
VALUE ext_module, int ext_type, int flags, VALUE proc
|
46
|
+
void msgpack_unpacker_ext_registry_put(VALUE owner, msgpack_unpacker_ext_registry_t** ukrg,
|
47
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc);
|
52
48
|
|
53
49
|
static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_registry_t* ukrg,
|
54
50
|
int ext_type, int* ext_flags_result)
|
@@ -56,7 +52,7 @@ static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_re
|
|
56
52
|
if (ukrg) {
|
57
53
|
VALUE entry = ukrg->array[ext_type + 128];
|
58
54
|
if (entry != Qnil) {
|
59
|
-
*ext_flags_result = FIX2INT(rb_ary_entry(entry,
|
55
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(entry, 2));
|
60
56
|
return rb_ary_entry(entry, 1);
|
61
57
|
}
|
62
58
|
}
|