msgpack 1.4.2 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yaml +57 -0
- data/ChangeLog +60 -0
- data/README.md +25 -1
- data/Rakefile +1 -2
- data/bench/bench.rb +78 -0
- data/bin/console +8 -0
- data/doclib/msgpack/factory.rb +47 -3
- data/doclib/msgpack/packer.rb +5 -4
- data/doclib/msgpack/unpacker.rb +2 -2
- data/ext/java/org/msgpack/jruby/Buffer.java +23 -16
- data/ext/java/org/msgpack/jruby/Decoder.java +29 -21
- data/ext/java/org/msgpack/jruby/Encoder.java +68 -30
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +37 -49
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +5 -8
- data/ext/java/org/msgpack/jruby/Factory.java +47 -7
- data/ext/java/org/msgpack/jruby/Packer.java +29 -17
- data/ext/java/org/msgpack/jruby/Unpacker.java +66 -42
- data/ext/msgpack/buffer.c +38 -57
- data/ext/msgpack/buffer.h +19 -10
- data/ext/msgpack/buffer_class.c +90 -52
- data/ext/msgpack/compat.h +0 -99
- data/ext/msgpack/extconf.rb +9 -22
- data/ext/msgpack/factory_class.c +133 -43
- data/ext/msgpack/packer.c +60 -36
- data/ext/msgpack/packer.h +27 -18
- data/ext/msgpack/packer_class.c +84 -77
- data/ext/msgpack/packer_class.h +11 -0
- data/ext/msgpack/packer_ext_registry.c +24 -32
- data/ext/msgpack/packer_ext_registry.h +40 -33
- data/ext/msgpack/sysdep.h +5 -2
- data/ext/msgpack/unpacker.c +128 -97
- data/ext/msgpack/unpacker.h +17 -10
- data/ext/msgpack/unpacker_class.c +75 -80
- data/ext/msgpack/unpacker_class.h +11 -0
- data/ext/msgpack/unpacker_ext_registry.c +42 -18
- data/ext/msgpack/unpacker_ext_registry.h +23 -16
- data/lib/msgpack/bigint.rb +69 -0
- data/lib/msgpack/factory.rb +103 -0
- data/lib/msgpack/symbol.rb +21 -4
- data/lib/msgpack/time.rb +1 -1
- data/lib/msgpack/version.rb +1 -1
- data/lib/msgpack.rb +5 -7
- data/msgpack.gemspec +2 -2
- data/spec/bigint_spec.rb +26 -0
- data/spec/cruby/buffer_spec.rb +17 -0
- data/spec/factory_spec.rb +351 -12
- data/spec/msgpack_spec.rb +1 -1
- data/spec/packer_spec.rb +18 -0
- data/spec/spec_helper.rb +20 -3
- data/spec/timestamp_spec.rb +38 -0
- data/spec/unpacker_spec.rb +54 -4
- metadata +25 -41
- data/.travis.yml +0 -39
- data/bench/pack.rb +0 -23
- data/bench/pack_log.rb +0 -33
- data/bench/pack_log_long.rb +0 -65
- data/bench/pack_symbols.rb +0 -28
- data/bench/run.sh +0 -14
- data/bench/run_long.sh +0 -35
- data/bench/run_symbols.sh +0 -26
- data/bench/unpack.rb +0 -21
- data/bench/unpack_log.rb +0 -34
- data/bench/unpack_log_long.rb +0 -67
data/ext/msgpack/packer_class.c
CHANGED
@@ -28,18 +28,14 @@ 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
|
|
34
|
-
|
35
|
-
msgpack_packer_t* name; \
|
36
|
-
Data_Get_Struct(from, msgpack_packer_t, name); \
|
37
|
-
if(name == NULL) { \
|
38
|
-
rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be."); \
|
39
|
-
}
|
40
|
-
|
41
|
-
static void Packer_free(msgpack_packer_t* pk)
|
36
|
+
static void Packer_free(void *ptr)
|
42
37
|
{
|
38
|
+
msgpack_packer_t* pk = ptr;
|
43
39
|
if(pk == NULL) {
|
44
40
|
return;
|
45
41
|
}
|
@@ -48,52 +44,66 @@ static void Packer_free(msgpack_packer_t* pk)
|
|
48
44
|
xfree(pk);
|
49
45
|
}
|
50
46
|
|
51
|
-
static void Packer_mark(
|
47
|
+
static void Packer_mark(void *ptr)
|
52
48
|
{
|
49
|
+
msgpack_packer_t* pk = ptr;
|
53
50
|
msgpack_packer_mark(pk);
|
54
51
|
msgpack_packer_ext_registry_mark(&pk->ext_registry);
|
55
52
|
}
|
56
53
|
|
57
|
-
|
54
|
+
static size_t Packer_memsize(const void *ptr)
|
58
55
|
{
|
59
|
-
msgpack_packer_t* pk =
|
60
|
-
|
56
|
+
const msgpack_packer_t* pk = ptr;
|
57
|
+
return sizeof(msgpack_packer_t) + msgpack_buffer_memsize(&pk->buffer);
|
58
|
+
}
|
61
59
|
|
62
|
-
|
60
|
+
const rb_data_type_t packer_data_type = {
|
61
|
+
.wrap_struct_name = "msgpack:packer",
|
62
|
+
.function = {
|
63
|
+
.dmark = Packer_mark,
|
64
|
+
.dfree = Packer_free,
|
65
|
+
.dsize = Packer_memsize,
|
66
|
+
},
|
67
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
68
|
+
};
|
63
69
|
|
64
|
-
msgpack_packer_set_to_msgpack_method(pk, s_to_msgpack, self);
|
65
70
|
|
71
|
+
VALUE MessagePack_Packer_alloc(VALUE klass)
|
72
|
+
{
|
73
|
+
msgpack_packer_t* pk;
|
74
|
+
VALUE self = TypedData_Make_Struct(klass, msgpack_packer_t, &packer_data_type, pk);
|
75
|
+
msgpack_packer_init(pk);
|
76
|
+
msgpack_packer_set_to_msgpack_method(pk, s_to_msgpack, self);
|
66
77
|
return self;
|
67
78
|
}
|
68
79
|
|
69
80
|
VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
|
70
81
|
{
|
82
|
+
if(argc > 2) {
|
83
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
|
84
|
+
}
|
85
|
+
|
71
86
|
VALUE io = Qnil;
|
72
87
|
VALUE options = Qnil;
|
73
88
|
|
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) {
|
89
|
+
if(argc >= 1) {
|
86
90
|
io = argv[0];
|
91
|
+
}
|
92
|
+
|
93
|
+
if(argc == 2) {
|
87
94
|
options = argv[1];
|
88
|
-
|
89
|
-
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
|
90
|
-
}
|
95
|
+
}
|
91
96
|
|
92
|
-
|
93
|
-
|
97
|
+
if (options == Qnil && rb_type(io) == T_HASH) {
|
98
|
+
options = io;
|
99
|
+
io = Qnil;
|
100
|
+
}
|
101
|
+
|
102
|
+
if(options != Qnil) {
|
103
|
+
Check_Type(options, T_HASH);
|
94
104
|
}
|
95
105
|
|
96
|
-
|
106
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
97
107
|
|
98
108
|
msgpack_packer_ext_registry_init(&pk->ext_registry);
|
99
109
|
pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self);
|
@@ -103,7 +113,7 @@ VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
|
|
103
113
|
if(options != Qnil) {
|
104
114
|
VALUE v;
|
105
115
|
|
106
|
-
v = rb_hash_aref(options,
|
116
|
+
v = rb_hash_aref(options, sym_compatibility_mode);
|
107
117
|
msgpack_packer_set_compat(pk, RTEST(v));
|
108
118
|
}
|
109
119
|
|
@@ -112,54 +122,54 @@ VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
|
|
112
122
|
|
113
123
|
static VALUE Packer_compatibility_mode_p(VALUE self)
|
114
124
|
{
|
115
|
-
|
125
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
116
126
|
return pk->compatibility_mode ? Qtrue : Qfalse;
|
117
127
|
}
|
118
128
|
|
119
129
|
static VALUE Packer_buffer(VALUE self)
|
120
130
|
{
|
121
|
-
|
131
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
122
132
|
return pk->buffer_ref;
|
123
133
|
}
|
124
134
|
|
125
135
|
static VALUE Packer_write(VALUE self, VALUE v)
|
126
136
|
{
|
127
|
-
|
137
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
128
138
|
msgpack_packer_write_value(pk, v);
|
129
139
|
return self;
|
130
140
|
}
|
131
141
|
|
132
142
|
static VALUE Packer_write_nil(VALUE self)
|
133
143
|
{
|
134
|
-
|
144
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
135
145
|
msgpack_packer_write_nil(pk);
|
136
146
|
return self;
|
137
147
|
}
|
138
148
|
|
139
149
|
static VALUE Packer_write_true(VALUE self)
|
140
150
|
{
|
141
|
-
|
151
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
142
152
|
msgpack_packer_write_true(pk);
|
143
153
|
return self;
|
144
154
|
}
|
145
155
|
|
146
156
|
static VALUE Packer_write_false(VALUE self)
|
147
157
|
{
|
148
|
-
|
158
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
149
159
|
msgpack_packer_write_false(pk);
|
150
160
|
return self;
|
151
161
|
}
|
152
162
|
|
153
163
|
static VALUE Packer_write_float(VALUE self, VALUE obj)
|
154
164
|
{
|
155
|
-
|
165
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
156
166
|
msgpack_packer_write_float_value(pk, obj);
|
157
167
|
return self;
|
158
168
|
}
|
159
169
|
|
160
170
|
static VALUE Packer_write_string(VALUE self, VALUE obj)
|
161
171
|
{
|
162
|
-
|
172
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
163
173
|
Check_Type(obj, T_STRING);
|
164
174
|
msgpack_packer_write_string_value(pk, obj);
|
165
175
|
return self;
|
@@ -167,7 +177,7 @@ static VALUE Packer_write_string(VALUE self, VALUE obj)
|
|
167
177
|
|
168
178
|
static VALUE Packer_write_bin(VALUE self, VALUE obj)
|
169
179
|
{
|
170
|
-
|
180
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
171
181
|
Check_Type(obj, T_STRING);
|
172
182
|
|
173
183
|
VALUE enc = rb_enc_from_encoding(rb_ascii8bit_encoding());
|
@@ -179,7 +189,7 @@ static VALUE Packer_write_bin(VALUE self, VALUE obj)
|
|
179
189
|
|
180
190
|
static VALUE Packer_write_array(VALUE self, VALUE obj)
|
181
191
|
{
|
182
|
-
|
192
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
183
193
|
Check_Type(obj, T_ARRAY);
|
184
194
|
msgpack_packer_write_array_value(pk, obj);
|
185
195
|
return self;
|
@@ -187,7 +197,7 @@ static VALUE Packer_write_array(VALUE self, VALUE obj)
|
|
187
197
|
|
188
198
|
static VALUE Packer_write_hash(VALUE self, VALUE obj)
|
189
199
|
{
|
190
|
-
|
200
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
191
201
|
Check_Type(obj, T_HASH);
|
192
202
|
msgpack_packer_write_hash_value(pk, obj);
|
193
203
|
return self;
|
@@ -195,7 +205,7 @@ static VALUE Packer_write_hash(VALUE self, VALUE obj)
|
|
195
205
|
|
196
206
|
static VALUE Packer_write_symbol(VALUE self, VALUE obj)
|
197
207
|
{
|
198
|
-
|
208
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
199
209
|
Check_Type(obj, T_SYMBOL);
|
200
210
|
msgpack_packer_write_symbol_value(pk, obj);
|
201
211
|
return self;
|
@@ -203,7 +213,7 @@ static VALUE Packer_write_symbol(VALUE self, VALUE obj)
|
|
203
213
|
|
204
214
|
static VALUE Packer_write_int(VALUE self, VALUE obj)
|
205
215
|
{
|
206
|
-
|
216
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
207
217
|
|
208
218
|
if (FIXNUM_P(obj)) {
|
209
219
|
msgpack_packer_write_fixnum_value(pk, obj);
|
@@ -216,7 +226,7 @@ static VALUE Packer_write_int(VALUE self, VALUE obj)
|
|
216
226
|
|
217
227
|
static VALUE Packer_write_extension(VALUE self, VALUE obj)
|
218
228
|
{
|
219
|
-
|
229
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
220
230
|
Check_Type(obj, T_STRUCT);
|
221
231
|
|
222
232
|
int ext_type = FIX2INT(RSTRUCT_GET(obj, 0));
|
@@ -232,21 +242,21 @@ static VALUE Packer_write_extension(VALUE self, VALUE obj)
|
|
232
242
|
|
233
243
|
static VALUE Packer_write_array_header(VALUE self, VALUE n)
|
234
244
|
{
|
235
|
-
|
245
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
236
246
|
msgpack_packer_write_array_header(pk, NUM2UINT(n));
|
237
247
|
return self;
|
238
248
|
}
|
239
249
|
|
240
250
|
static VALUE Packer_write_map_header(VALUE self, VALUE n)
|
241
251
|
{
|
242
|
-
|
252
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
243
253
|
msgpack_packer_write_map_header(pk, NUM2UINT(n));
|
244
254
|
return self;
|
245
255
|
}
|
246
256
|
|
247
257
|
static VALUE Packer_write_bin_header(VALUE self, VALUE n)
|
248
258
|
{
|
249
|
-
|
259
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
250
260
|
msgpack_packer_write_bin_header(pk, NUM2UINT(n));
|
251
261
|
return self;
|
252
262
|
}
|
@@ -257,14 +267,14 @@ static VALUE Packer_write_float32(VALUE self, VALUE numeric)
|
|
257
267
|
rb_raise(rb_eArgError, "Expected numeric");
|
258
268
|
}
|
259
269
|
|
260
|
-
|
270
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
261
271
|
msgpack_packer_write_float(pk, (float)rb_num2dbl(numeric));
|
262
272
|
return self;
|
263
273
|
}
|
264
274
|
|
265
275
|
static VALUE Packer_write_ext(VALUE self, VALUE type, VALUE data)
|
266
276
|
{
|
267
|
-
|
277
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
268
278
|
int ext_type = NUM2INT(type);
|
269
279
|
if(ext_type < -128 || ext_type > 127) {
|
270
280
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
@@ -276,28 +286,28 @@ static VALUE Packer_write_ext(VALUE self, VALUE type, VALUE data)
|
|
276
286
|
|
277
287
|
static VALUE Packer_flush(VALUE self)
|
278
288
|
{
|
279
|
-
|
289
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
280
290
|
msgpack_buffer_flush(PACKER_BUFFER_(pk));
|
281
291
|
return self;
|
282
292
|
}
|
283
293
|
|
284
|
-
static VALUE
|
294
|
+
static VALUE Packer_reset(VALUE self)
|
285
295
|
{
|
286
|
-
|
296
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
287
297
|
msgpack_buffer_clear(PACKER_BUFFER_(pk));
|
288
298
|
return Qnil;
|
289
299
|
}
|
290
300
|
|
291
301
|
static VALUE Packer_size(VALUE self)
|
292
302
|
{
|
293
|
-
|
303
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
294
304
|
size_t size = msgpack_buffer_all_readable_size(PACKER_BUFFER_(pk));
|
295
305
|
return SIZET2NUM(size);
|
296
306
|
}
|
297
307
|
|
298
308
|
static VALUE Packer_empty_p(VALUE self)
|
299
309
|
{
|
300
|
-
|
310
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
301
311
|
if(msgpack_buffer_top_readable_size(PACKER_BUFFER_(pk)) == 0) {
|
302
312
|
return Qtrue;
|
303
313
|
} else {
|
@@ -307,26 +317,26 @@ static VALUE Packer_empty_p(VALUE self)
|
|
307
317
|
|
308
318
|
static VALUE Packer_to_str(VALUE self)
|
309
319
|
{
|
310
|
-
|
320
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
311
321
|
return msgpack_buffer_all_as_string(PACKER_BUFFER_(pk));
|
312
322
|
}
|
313
323
|
|
314
324
|
static VALUE Packer_to_a(VALUE self)
|
315
325
|
{
|
316
|
-
|
326
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
317
327
|
return msgpack_buffer_all_as_string_array(PACKER_BUFFER_(pk));
|
318
328
|
}
|
319
329
|
|
320
330
|
static VALUE Packer_write_to(VALUE self, VALUE io)
|
321
331
|
{
|
322
|
-
|
332
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
323
333
|
size_t sz = msgpack_buffer_flush_to_io(PACKER_BUFFER_(pk), io, s_write, true);
|
324
|
-
return
|
334
|
+
return SIZET2NUM(sz);
|
325
335
|
}
|
326
336
|
|
327
337
|
//static VALUE Packer_append(VALUE self, VALUE string_or_buffer)
|
328
338
|
//{
|
329
|
-
//
|
339
|
+
// msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
330
340
|
//
|
331
341
|
// // TODO if string_or_buffer is a Buffer
|
332
342
|
// VALUE string = string_or_buffer;
|
@@ -338,17 +348,16 @@ static VALUE Packer_write_to(VALUE self, VALUE io)
|
|
338
348
|
|
339
349
|
static VALUE Packer_registered_types_internal(VALUE self)
|
340
350
|
{
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
return
|
346
|
-
#endif
|
351
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
352
|
+
if (RTEST(pk->ext_registry.hash)) {
|
353
|
+
return rb_hash_dup(pk->ext_registry.hash);
|
354
|
+
}
|
355
|
+
return rb_hash_new();
|
347
356
|
}
|
348
357
|
|
349
358
|
static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
|
350
359
|
{
|
351
|
-
|
360
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
352
361
|
|
353
362
|
int ext_type;
|
354
363
|
VALUE ext_module;
|
@@ -359,12 +368,7 @@ static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
|
|
359
368
|
case 2:
|
360
369
|
/* register_type(0x7f, Time) {|obj| block... } */
|
361
370
|
rb_need_block();
|
362
|
-
#ifdef HAVE_RB_BLOCK_LAMBDA
|
363
371
|
proc = rb_block_lambda();
|
364
|
-
#else
|
365
|
-
/* MRI 1.8 */
|
366
|
-
proc = rb_block_proc();
|
367
|
-
#endif
|
368
372
|
arg = proc;
|
369
373
|
break;
|
370
374
|
case 3:
|
@@ -386,7 +390,7 @@ static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
|
|
386
390
|
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
387
391
|
}
|
388
392
|
|
389
|
-
msgpack_packer_ext_registry_put(&pk->ext_registry, ext_module, ext_type, proc, arg);
|
393
|
+
msgpack_packer_ext_registry_put(&pk->ext_registry, ext_module, ext_type, 0, proc, arg);
|
390
394
|
|
391
395
|
if (ext_module == rb_cSymbol) {
|
392
396
|
pk->has_symbol_ext_type = true;
|
@@ -399,7 +403,7 @@ VALUE Packer_full_pack(VALUE self)
|
|
399
403
|
{
|
400
404
|
VALUE retval;
|
401
405
|
|
402
|
-
|
406
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
403
407
|
|
404
408
|
if(msgpack_buffer_has_io(PACKER_BUFFER_(pk))) {
|
405
409
|
msgpack_buffer_flush(PACKER_BUFFER_(pk));
|
@@ -418,6 +422,8 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
|
|
418
422
|
s_to_msgpack = rb_intern("to_msgpack");
|
419
423
|
s_write = rb_intern("write");
|
420
424
|
|
425
|
+
sym_compatibility_mode = ID2SYM(rb_intern("compatibility_mode"));
|
426
|
+
|
421
427
|
msgpack_packer_static_init();
|
422
428
|
msgpack_packer_ext_registry_static_init();
|
423
429
|
|
@@ -449,7 +455,8 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
|
|
449
455
|
rb_define_method(cMessagePack_Packer, "flush", Packer_flush, 0);
|
450
456
|
|
451
457
|
/* delegation methods */
|
452
|
-
rb_define_method(cMessagePack_Packer, "
|
458
|
+
rb_define_method(cMessagePack_Packer, "reset", Packer_reset, 0);
|
459
|
+
rb_define_alias(cMessagePack_Packer, "clear", "reset");
|
453
460
|
rb_define_method(cMessagePack_Packer, "size", Packer_size, 0);
|
454
461
|
rb_define_method(cMessagePack_Packer, "empty?", Packer_empty_p, 0);
|
455
462
|
rb_define_method(cMessagePack_Packer, "write_to", Packer_write_to, 1);
|
data/ext/msgpack/packer_class.h
CHANGED
@@ -22,6 +22,17 @@
|
|
22
22
|
|
23
23
|
extern VALUE cMessagePack_Packer;
|
24
24
|
|
25
|
+
extern const rb_data_type_t packer_data_type;
|
26
|
+
|
27
|
+
static inline msgpack_packer_t *MessagePack_Packer_get(VALUE object) {
|
28
|
+
msgpack_packer_t *packer;
|
29
|
+
TypedData_Get_Struct(object, msgpack_packer_t, &packer_data_type, packer);
|
30
|
+
if (!packer) {
|
31
|
+
rb_raise(rb_eArgError, "Uninitialized Packer object");
|
32
|
+
}
|
33
|
+
return packer;
|
34
|
+
}
|
35
|
+
|
25
36
|
void MessagePack_Packer_module_init(VALUE mMessagePack);
|
26
37
|
|
27
38
|
VALUE MessagePack_Packer_alloc(VALUE klass);
|
@@ -20,18 +20,18 @@
|
|
20
20
|
|
21
21
|
static ID s_call;
|
22
22
|
|
23
|
-
void msgpack_packer_ext_registry_static_init()
|
23
|
+
void msgpack_packer_ext_registry_static_init(void)
|
24
24
|
{
|
25
25
|
s_call = rb_intern("call");
|
26
26
|
}
|
27
27
|
|
28
|
-
void msgpack_packer_ext_registry_static_destroy()
|
28
|
+
void msgpack_packer_ext_registry_static_destroy(void)
|
29
29
|
{ }
|
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,37 +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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
}
|
54
|
-
|
55
|
-
#ifndef HAVE_RB_HASH_CLEAR
|
56
|
-
|
57
|
-
static int
|
58
|
-
__rb_hash_clear_clear_i(key, value, dummy)
|
59
|
-
VALUE key, value, dummy;
|
60
|
-
{
|
61
|
-
return ST_DELETE;
|
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
|
+
}
|
62
54
|
}
|
63
55
|
|
64
|
-
#endif
|
65
|
-
|
66
56
|
VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
|
67
|
-
VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
|
57
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg)
|
68
58
|
{
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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);
|
76
66
|
}
|
77
|
-
|
78
|
-
|
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);
|
79
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
|
|
@@ -29,9 +31,9 @@ struct msgpack_packer_ext_registry_t {
|
|
29
31
|
VALUE cache; // lookup cache for ext types inherited from a super class
|
30
32
|
};
|
31
33
|
|
32
|
-
void msgpack_packer_ext_registry_static_init();
|
34
|
+
void msgpack_packer_ext_registry_static_init(void);
|
33
35
|
|
34
|
-
void msgpack_packer_ext_registry_static_destroy();
|
36
|
+
void msgpack_packer_ext_registry_static_destroy(void);
|
35
37
|
|
36
38
|
void msgpack_packer_ext_registry_init(msgpack_packer_ext_registry_t* pkrg);
|
37
39
|
|
@@ -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/sysdep.h
CHANGED
@@ -35,8 +35,11 @@
|
|
35
35
|
# define _msgpack_be16(x) ((uint16_t)_byteswap_ushort((unsigned short)x))
|
36
36
|
# else
|
37
37
|
# define _msgpack_be16(x) ( \
|
38
|
-
(
|
39
|
-
|
38
|
+
( \
|
39
|
+
((((uint16_t)x) << 8) ) | \
|
40
|
+
((((uint16_t)x) >> 8) ) \
|
41
|
+
) \
|
42
|
+
& 0x0000FFFF )
|
40
43
|
# endif
|
41
44
|
#else
|
42
45
|
# define _msgpack_be16(x) ntohs(x)
|