msgpack 1.4.2 → 1.6.0
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 +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)
|