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
@@ -33,35 +33,58 @@ static VALUE eUnexpectedTypeError;
|
|
33
33
|
static VALUE eUnknownExtTypeError;
|
34
34
|
static VALUE mTypeError; // obsoleted. only for backward compatibility. See #86.
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
if(name == NULL) { \
|
40
|
-
rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be."); \
|
41
|
-
}
|
36
|
+
static VALUE sym_symbolize_keys;
|
37
|
+
static VALUE sym_freeze;
|
38
|
+
static VALUE sym_allow_unknown_ext;
|
42
39
|
|
43
|
-
static void Unpacker_free(
|
40
|
+
static void Unpacker_free(void *ptr)
|
44
41
|
{
|
42
|
+
msgpack_unpacker_t* uk = ptr;
|
45
43
|
if(uk == NULL) {
|
46
44
|
return;
|
47
45
|
}
|
48
|
-
|
46
|
+
msgpack_unpacker_ext_registry_release(uk->ext_registry);
|
49
47
|
_msgpack_unpacker_destroy(uk);
|
50
48
|
xfree(uk);
|
51
49
|
}
|
52
50
|
|
53
|
-
static void Unpacker_mark(
|
51
|
+
static void Unpacker_mark(void *ptr)
|
54
52
|
{
|
53
|
+
msgpack_unpacker_t* uk = ptr;
|
55
54
|
msgpack_unpacker_mark(uk);
|
56
|
-
msgpack_unpacker_ext_registry_mark(
|
55
|
+
msgpack_unpacker_ext_registry_mark(uk->ext_registry);
|
56
|
+
}
|
57
|
+
|
58
|
+
static size_t Unpacker_memsize(const void *ptr)
|
59
|
+
{
|
60
|
+
size_t total_size = sizeof(msgpack_unpacker_t);
|
61
|
+
|
62
|
+
const msgpack_unpacker_t* uk = ptr;
|
63
|
+
if (uk->ext_registry) {
|
64
|
+
total_size += sizeof(msgpack_unpacker_ext_registry_t) / (uk->ext_registry->borrow_count + 1);
|
65
|
+
}
|
66
|
+
|
67
|
+
total_size += (uk->stack->depth + 1) * sizeof(msgpack_unpacker_stack_t);
|
68
|
+
|
69
|
+
return total_size + msgpack_buffer_memsize(&uk->buffer);
|
57
70
|
}
|
58
71
|
|
72
|
+
const rb_data_type_t unpacker_data_type = {
|
73
|
+
.wrap_struct_name = "msgpack:unpacker",
|
74
|
+
.function = {
|
75
|
+
.dmark = Unpacker_mark,
|
76
|
+
.dfree = Unpacker_free,
|
77
|
+
.dsize = Unpacker_memsize,
|
78
|
+
},
|
79
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
80
|
+
};
|
81
|
+
|
59
82
|
VALUE MessagePack_Unpacker_alloc(VALUE klass)
|
60
83
|
{
|
61
|
-
msgpack_unpacker_t* uk
|
84
|
+
msgpack_unpacker_t* uk;
|
85
|
+
VALUE self = TypedData_Make_Struct(klass, msgpack_unpacker_t, &unpacker_data_type, uk);
|
62
86
|
_msgpack_unpacker_init(uk);
|
63
|
-
|
64
|
-
VALUE self = Data_Wrap_Struct(klass, Unpacker_mark, Unpacker_free, uk);
|
87
|
+
uk->self = self;
|
65
88
|
return self;
|
66
89
|
}
|
67
90
|
|
@@ -84,7 +107,7 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
84
107
|
} else if(argc == 2) {
|
85
108
|
io = argv[0];
|
86
109
|
options = argv[1];
|
87
|
-
if(rb_type(options) != T_HASH) {
|
110
|
+
if(options != Qnil && rb_type(options) != T_HASH) {
|
88
111
|
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
|
89
112
|
}
|
90
113
|
|
@@ -92,9 +115,8 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
92
115
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
|
93
116
|
}
|
94
117
|
|
95
|
-
|
118
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
96
119
|
|
97
|
-
msgpack_unpacker_ext_registry_init(&uk->ext_registry);
|
98
120
|
uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
|
99
121
|
|
100
122
|
MessagePack_Buffer_set_options(UNPACKER_BUFFER_(uk), io, options);
|
@@ -102,13 +124,13 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
102
124
|
if(options != Qnil) {
|
103
125
|
VALUE v;
|
104
126
|
|
105
|
-
v = rb_hash_aref(options,
|
127
|
+
v = rb_hash_aref(options, sym_symbolize_keys);
|
106
128
|
msgpack_unpacker_set_symbolized_keys(uk, RTEST(v));
|
107
129
|
|
108
|
-
v = rb_hash_aref(options,
|
130
|
+
v = rb_hash_aref(options, sym_freeze);
|
109
131
|
msgpack_unpacker_set_freeze(uk, RTEST(v));
|
110
132
|
|
111
|
-
v = rb_hash_aref(options,
|
133
|
+
v = rb_hash_aref(options, sym_allow_unknown_ext);
|
112
134
|
msgpack_unpacker_set_allow_unknown_ext(uk, RTEST(v));
|
113
135
|
}
|
114
136
|
|
@@ -117,23 +139,23 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
117
139
|
|
118
140
|
static VALUE Unpacker_symbolized_keys_p(VALUE self)
|
119
141
|
{
|
120
|
-
|
142
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
121
143
|
return uk->symbolize_keys ? Qtrue : Qfalse;
|
122
144
|
}
|
123
145
|
|
124
146
|
static VALUE Unpacker_freeze_p(VALUE self)
|
125
147
|
{
|
126
|
-
|
148
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
127
149
|
return uk->freeze ? Qtrue : Qfalse;
|
128
150
|
}
|
129
151
|
|
130
152
|
static VALUE Unpacker_allow_unknown_ext_p(VALUE self)
|
131
153
|
{
|
132
|
-
|
154
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
133
155
|
return uk->allow_unknown_ext ? Qtrue : Qfalse;
|
134
156
|
}
|
135
157
|
|
136
|
-
static void raise_unpacker_error(int r)
|
158
|
+
NORETURN(static void raise_unpacker_error(int r))
|
137
159
|
{
|
138
160
|
switch(r) {
|
139
161
|
case PRIMITIVE_EOF:
|
@@ -145,6 +167,7 @@ static void raise_unpacker_error(int r)
|
|
145
167
|
case PRIMITIVE_UNEXPECTED_TYPE:
|
146
168
|
rb_raise(eUnexpectedTypeError, "unexpected type");
|
147
169
|
case PRIMITIVE_UNEXPECTED_EXT_TYPE:
|
170
|
+
// rb_bug("unexpected extension type");
|
148
171
|
rb_raise(eUnknownExtTypeError, "unexpected extension type");
|
149
172
|
default:
|
150
173
|
rb_raise(eUnpackError, "logically unknown error %d", r);
|
@@ -153,13 +176,13 @@ static void raise_unpacker_error(int r)
|
|
153
176
|
|
154
177
|
static VALUE Unpacker_buffer(VALUE self)
|
155
178
|
{
|
156
|
-
|
179
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
157
180
|
return uk->buffer_ref;
|
158
181
|
}
|
159
182
|
|
160
183
|
static VALUE Unpacker_read(VALUE self)
|
161
184
|
{
|
162
|
-
|
185
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
163
186
|
|
164
187
|
int r = msgpack_unpacker_read(uk, 0);
|
165
188
|
if(r < 0) {
|
@@ -171,7 +194,7 @@ static VALUE Unpacker_read(VALUE self)
|
|
171
194
|
|
172
195
|
static VALUE Unpacker_skip(VALUE self)
|
173
196
|
{
|
174
|
-
|
197
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
175
198
|
|
176
199
|
int r = msgpack_unpacker_skip(uk, 0);
|
177
200
|
if(r < 0) {
|
@@ -183,7 +206,7 @@ static VALUE Unpacker_skip(VALUE self)
|
|
183
206
|
|
184
207
|
static VALUE Unpacker_skip_nil(VALUE self)
|
185
208
|
{
|
186
|
-
|
209
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
187
210
|
|
188
211
|
int r = msgpack_unpacker_skip_nil(uk);
|
189
212
|
if(r < 0) {
|
@@ -198,7 +221,7 @@ static VALUE Unpacker_skip_nil(VALUE self)
|
|
198
221
|
|
199
222
|
static VALUE Unpacker_read_array_header(VALUE self)
|
200
223
|
{
|
201
|
-
|
224
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
202
225
|
|
203
226
|
uint32_t size;
|
204
227
|
int r = msgpack_unpacker_read_array_header(uk, &size);
|
@@ -206,12 +229,12 @@ static VALUE Unpacker_read_array_header(VALUE self)
|
|
206
229
|
raise_unpacker_error(r);
|
207
230
|
}
|
208
231
|
|
209
|
-
return ULONG2NUM(size);
|
232
|
+
return ULONG2NUM(size); // long at least 32 bits
|
210
233
|
}
|
211
234
|
|
212
235
|
static VALUE Unpacker_read_map_header(VALUE self)
|
213
236
|
{
|
214
|
-
|
237
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
215
238
|
|
216
239
|
uint32_t size;
|
217
240
|
int r = msgpack_unpacker_read_map_header(uk, &size);
|
@@ -219,41 +242,13 @@ static VALUE Unpacker_read_map_header(VALUE self)
|
|
219
242
|
raise_unpacker_error((int)r);
|
220
243
|
}
|
221
244
|
|
222
|
-
return ULONG2NUM(size);
|
245
|
+
return ULONG2NUM(size); // long at least 32 bits
|
223
246
|
}
|
224
247
|
|
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
248
|
|
254
249
|
static VALUE Unpacker_feed(VALUE self, VALUE data)
|
255
250
|
{
|
256
|
-
|
251
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
257
252
|
|
258
253
|
StringValue(data);
|
259
254
|
|
@@ -264,7 +259,7 @@ static VALUE Unpacker_feed(VALUE self, VALUE data)
|
|
264
259
|
|
265
260
|
static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
|
266
261
|
{
|
267
|
-
|
262
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
268
263
|
|
269
264
|
StringValue(data);
|
270
265
|
|
@@ -275,7 +270,7 @@ static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
|
|
275
270
|
|
276
271
|
static VALUE Unpacker_each_impl(VALUE self)
|
277
272
|
{
|
278
|
-
|
273
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
279
274
|
|
280
275
|
while(true) {
|
281
276
|
int r = msgpack_unpacker_read(uk, 0);
|
@@ -296,15 +291,16 @@ static VALUE Unpacker_each_impl(VALUE self)
|
|
296
291
|
}
|
297
292
|
}
|
298
293
|
|
299
|
-
static VALUE Unpacker_rescue_EOFError(VALUE
|
294
|
+
static VALUE Unpacker_rescue_EOFError(VALUE args, VALUE error)
|
300
295
|
{
|
301
|
-
UNUSED(
|
296
|
+
UNUSED(args);
|
297
|
+
UNUSED(error);
|
302
298
|
return Qnil;
|
303
299
|
}
|
304
300
|
|
305
301
|
static VALUE Unpacker_each(VALUE self)
|
306
302
|
{
|
307
|
-
|
303
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
308
304
|
|
309
305
|
#ifdef RETURN_ENUMERATOR
|
310
306
|
RETURN_ENUMERATOR(self, 0, 0);
|
@@ -335,7 +331,7 @@ static VALUE Unpacker_feed_each(VALUE self, VALUE data)
|
|
335
331
|
|
336
332
|
static VALUE Unpacker_reset(VALUE self)
|
337
333
|
{
|
338
|
-
|
334
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
339
335
|
|
340
336
|
_msgpack_unpacker_reset(uk);
|
341
337
|
|
@@ -344,12 +340,14 @@ static VALUE Unpacker_reset(VALUE self)
|
|
344
340
|
|
345
341
|
static VALUE Unpacker_registered_types_internal(VALUE self)
|
346
342
|
{
|
347
|
-
|
343
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
348
344
|
|
349
345
|
VALUE mapping = rb_hash_new();
|
350
|
-
|
351
|
-
|
352
|
-
|
346
|
+
if (uk->ext_registry) {
|
347
|
+
for(int i=0; i < 256; i++) {
|
348
|
+
if(uk->ext_registry->array[i] != Qnil) {
|
349
|
+
rb_hash_aset(mapping, INT2FIX(i - 128), uk->ext_registry->array[i]);
|
350
|
+
}
|
353
351
|
}
|
354
352
|
}
|
355
353
|
|
@@ -358,7 +356,7 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
|
|
358
356
|
|
359
357
|
static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
360
358
|
{
|
361
|
-
|
359
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
362
360
|
|
363
361
|
int ext_type;
|
364
362
|
VALUE proc;
|
@@ -369,12 +367,7 @@ static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
|
369
367
|
case 1:
|
370
368
|
/* register_type(0x7f) {|data| block... } */
|
371
369
|
rb_need_block();
|
372
|
-
#ifdef HAVE_RB_BLOCK_LAMBDA
|
373
370
|
proc = rb_block_lambda();
|
374
|
-
#else
|
375
|
-
/* MRI 1.8 */
|
376
|
-
proc = rb_block_proc();
|
377
|
-
#endif
|
378
371
|
arg = proc;
|
379
372
|
ext_module = Qnil;
|
380
373
|
break;
|
@@ -393,14 +386,14 @@ static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
|
393
386
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
394
387
|
}
|
395
388
|
|
396
|
-
msgpack_unpacker_ext_registry_put(&uk->ext_registry, ext_module, ext_type, proc, arg);
|
389
|
+
msgpack_unpacker_ext_registry_put(&uk->ext_registry, ext_module, ext_type, 0, proc, arg);
|
397
390
|
|
398
391
|
return Qnil;
|
399
392
|
}
|
400
393
|
|
401
394
|
static VALUE Unpacker_full_unpack(VALUE self)
|
402
395
|
{
|
403
|
-
|
396
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
404
397
|
|
405
398
|
int r = msgpack_unpacker_read(uk, 0);
|
406
399
|
if(r < 0) {
|
@@ -443,6 +436,10 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
443
436
|
|
444
437
|
eUnknownExtTypeError = rb_define_class_under(mMessagePack, "UnknownExtTypeError", eUnpackError);
|
445
438
|
|
439
|
+
sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
|
440
|
+
sym_freeze = ID2SYM(rb_intern("freeze"));
|
441
|
+
sym_allow_unknown_ext = ID2SYM(rb_intern("allow_unknown_ext"));
|
442
|
+
|
446
443
|
rb_define_alloc_func(cMessagePack_Unpacker, MessagePack_Unpacker_alloc);
|
447
444
|
|
448
445
|
rb_define_method(cMessagePack_Unpacker, "initialize", MessagePack_Unpacker_initialize, -1);
|
@@ -456,7 +453,6 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
456
453
|
rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
|
457
454
|
rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
|
458
455
|
rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
|
459
|
-
//rb_define_method(cMessagePack_Unpacker, "peek_next_type", Unpacker_peek_next_type, 0); // TODO
|
460
456
|
rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1);
|
461
457
|
rb_define_method(cMessagePack_Unpacker, "feed_reference", Unpacker_feed_reference, 1);
|
462
458
|
rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
|
@@ -474,4 +470,3 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
474
470
|
|
475
471
|
rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
|
476
472
|
}
|
477
|
-
|
@@ -20,6 +20,17 @@
|
|
20
20
|
|
21
21
|
#include "unpacker.h"
|
22
22
|
|
23
|
+
extern const rb_data_type_t unpacker_data_type;
|
24
|
+
|
25
|
+
static inline msgpack_unpacker_t *MessagePack_Unpacker_get(VALUE object) {
|
26
|
+
msgpack_unpacker_t *unpacker;
|
27
|
+
TypedData_Get_Struct(object, msgpack_unpacker_t, &unpacker_data_type, unpacker);
|
28
|
+
if (!unpacker) {
|
29
|
+
rb_raise(rb_eArgError, "Uninitialized Unpacker object");
|
30
|
+
}
|
31
|
+
return unpacker;
|
32
|
+
}
|
33
|
+
|
23
34
|
extern VALUE cMessagePack_Unpacker;
|
24
35
|
|
25
36
|
void MessagePack_Unpacker_module_init(VALUE mMessagePack);
|
@@ -21,42 +21,66 @@
|
|
21
21
|
static ID s_call;
|
22
22
|
static ID s_dup;
|
23
23
|
|
24
|
-
void msgpack_unpacker_ext_registry_static_init()
|
24
|
+
void msgpack_unpacker_ext_registry_static_init(void)
|
25
25
|
{
|
26
26
|
s_call = rb_intern("call");
|
27
27
|
s_dup = rb_intern("dup");
|
28
28
|
}
|
29
29
|
|
30
|
-
|
30
|
+
|
31
|
+
void msgpack_unpacker_ext_registry_static_destroy(void)
|
31
32
|
{ }
|
32
33
|
|
33
|
-
void
|
34
|
+
void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg)
|
34
35
|
{
|
35
|
-
|
36
|
-
|
36
|
+
if (ukrg) {
|
37
|
+
for(int i=0; i < 256; i++) {
|
38
|
+
if (ukrg->array[i] != Qnil) {
|
39
|
+
rb_gc_mark(ukrg->array[i]);
|
40
|
+
}
|
41
|
+
}
|
37
42
|
}
|
38
43
|
}
|
39
44
|
|
40
|
-
|
45
|
+
msgpack_unpacker_ext_registry_t* msgpack_unpacker_ext_registry_cow(msgpack_unpacker_ext_registry_t* src)
|
41
46
|
{
|
42
|
-
|
43
|
-
|
47
|
+
msgpack_unpacker_ext_registry_t* dst;
|
48
|
+
if (src) {
|
49
|
+
if (src->borrow_count) {
|
50
|
+
dst = ALLOC(msgpack_unpacker_ext_registry_t);
|
51
|
+
dst->borrow_count = 0;
|
52
|
+
MEMCPY(dst->array, src->array, VALUE, 256);
|
53
|
+
msgpack_unpacker_ext_registry_release(src);
|
54
|
+
return dst;
|
55
|
+
} else {
|
56
|
+
return src;
|
57
|
+
}
|
58
|
+
} else {
|
59
|
+
dst = ALLOC(msgpack_unpacker_ext_registry_t);
|
60
|
+
dst->borrow_count = 0;
|
61
|
+
for(int i=0; i < 256; i++) {
|
62
|
+
dst->array[i] = Qnil;
|
63
|
+
}
|
64
|
+
return dst;
|
44
65
|
}
|
45
66
|
}
|
46
67
|
|
47
|
-
void
|
48
|
-
msgpack_unpacker_ext_registry_t* dst)
|
68
|
+
void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg)
|
49
69
|
{
|
50
|
-
|
51
|
-
|
70
|
+
if (ukrg) {
|
71
|
+
if (ukrg->borrow_count) {
|
72
|
+
ukrg->borrow_count--;
|
73
|
+
} else {
|
74
|
+
xfree(ukrg);
|
75
|
+
}
|
52
76
|
}
|
53
77
|
}
|
54
78
|
|
55
|
-
|
56
|
-
VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
|
79
|
+
void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
|
80
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg)
|
57
81
|
{
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
82
|
+
msgpack_unpacker_ext_registry_t* ext_registry = msgpack_unpacker_ext_registry_cow(*ukrg);
|
83
|
+
|
84
|
+
ext_registry->array[ext_type + 128] = rb_ary_new3(4, ext_module, proc, arg, INT2FIX(flags));
|
85
|
+
*ukrg = ext_registry;
|
62
86
|
}
|
@@ -21,39 +21,46 @@
|
|
21
21
|
#include "compat.h"
|
22
22
|
#include "ruby.h"
|
23
23
|
|
24
|
+
#define MSGPACK_EXT_RECURSIVE 0b0001
|
25
|
+
|
24
26
|
struct msgpack_unpacker_ext_registry_t;
|
25
27
|
typedef struct msgpack_unpacker_ext_registry_t msgpack_unpacker_ext_registry_t;
|
26
28
|
|
27
29
|
struct msgpack_unpacker_ext_registry_t {
|
30
|
+
unsigned int borrow_count;
|
28
31
|
VALUE array[256];
|
29
|
-
//int bitmap;
|
30
32
|
};
|
31
33
|
|
32
|
-
void msgpack_unpacker_ext_registry_static_init();
|
34
|
+
void msgpack_unpacker_ext_registry_static_init(void);
|
33
35
|
|
34
|
-
void msgpack_unpacker_ext_registry_static_destroy();
|
36
|
+
void msgpack_unpacker_ext_registry_static_destroy(void);
|
35
37
|
|
36
|
-
void
|
38
|
+
void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg);
|
37
39
|
|
38
|
-
static inline void
|
39
|
-
{
|
40
|
+
static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_registry_t* src, msgpack_unpacker_ext_registry_t** dst)
|
41
|
+
{
|
42
|
+
if (src) {
|
43
|
+
src->borrow_count++;
|
44
|
+
*dst = src;
|
45
|
+
}
|
46
|
+
}
|
40
47
|
|
41
48
|
void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg);
|
42
49
|
|
43
|
-
void
|
44
|
-
|
45
|
-
|
46
|
-
VALUE msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t* ukrg,
|
47
|
-
VALUE ext_module, int ext_type, VALUE proc, VALUE arg);
|
50
|
+
void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
|
51
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg);
|
48
52
|
|
49
53
|
static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_registry_t* ukrg,
|
50
|
-
int ext_type)
|
54
|
+
int ext_type, int* ext_flags_result)
|
51
55
|
{
|
52
|
-
|
53
|
-
|
54
|
-
|
56
|
+
if (ukrg) {
|
57
|
+
VALUE entry = ukrg->array[ext_type + 128];
|
58
|
+
if (entry != Qnil) {
|
59
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(entry, 3));
|
60
|
+
return rb_ary_entry(entry, 1);
|
61
|
+
}
|
55
62
|
}
|
56
|
-
return
|
63
|
+
return Qnil;
|
57
64
|
}
|
58
65
|
|
59
66
|
#endif
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MessagePack
|
4
|
+
module Bigint
|
5
|
+
# We split the bigint in 32bits chunks so that individual part fits into
|
6
|
+
# a MRI immediate Integer.
|
7
|
+
CHUNK_BITLENGTH = 32
|
8
|
+
FORMAT = 'CL>*'
|
9
|
+
|
10
|
+
if Integer.instance_method(:[]).arity != 1 # Ruby 2.7 and newer
|
11
|
+
# Starting from Ruby 2.7 we can address arbitrary bitranges inside an Integer with Integer#[]
|
12
|
+
# This allows to not allocate any Integer.
|
13
|
+
def self.to_msgpack_ext(bigint)
|
14
|
+
members = []
|
15
|
+
|
16
|
+
if bigint < 0
|
17
|
+
bigint = -bigint
|
18
|
+
members << 1
|
19
|
+
else
|
20
|
+
members << 0
|
21
|
+
end
|
22
|
+
|
23
|
+
offset = 0
|
24
|
+
length = bigint.bit_length
|
25
|
+
while offset < length
|
26
|
+
members << bigint[offset, CHUNK_BITLENGTH]
|
27
|
+
offset += CHUNK_BITLENGTH
|
28
|
+
end
|
29
|
+
|
30
|
+
members.pack(FORMAT)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
# On 2.6 and older since we can't address arbitrary bitranges, so we fallback to shifting the bigint.
|
34
|
+
# This means that after each shift, we may allocate another Integer instance.
|
35
|
+
BASE = (2**CHUNK_BITLENGTH) - 1
|
36
|
+
def self.to_msgpack_ext(bigint)
|
37
|
+
members = []
|
38
|
+
|
39
|
+
if bigint < 0
|
40
|
+
bigint = -bigint
|
41
|
+
members << 1
|
42
|
+
else
|
43
|
+
members << 0
|
44
|
+
end
|
45
|
+
|
46
|
+
while bigint > 0
|
47
|
+
members << (bigint & BASE)
|
48
|
+
bigint = bigint >> CHUNK_BITLENGTH
|
49
|
+
end
|
50
|
+
|
51
|
+
members.pack(FORMAT)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.from_msgpack_ext(data)
|
56
|
+
parts = data.unpack(FORMAT)
|
57
|
+
|
58
|
+
sign = parts.shift
|
59
|
+
sum = parts.pop.to_i
|
60
|
+
|
61
|
+
parts.reverse_each do |part|
|
62
|
+
sum = sum << CHUNK_BITLENGTH
|
63
|
+
sum += part
|
64
|
+
end
|
65
|
+
|
66
|
+
sign == 0 ? sum : -sum
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|