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
@@ -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
|