msgpack 1.3.3 → 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/.rubocop.yml +2 -2
- data/ChangeLog +74 -0
- data/Gemfile +1 -1
- data/README.md +266 -0
- data/Rakefile +1 -9
- 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 +46 -23
- 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 +72 -37
- data/ext/msgpack/buffer.c +42 -68
- data/ext/msgpack/buffer.h +59 -14
- data/ext/msgpack/buffer_class.c +90 -52
- data/ext/msgpack/compat.h +1 -111
- data/ext/msgpack/extconf.rb +45 -19
- data/ext/msgpack/factory_class.c +133 -43
- data/ext/msgpack/packer.c +60 -36
- data/ext/msgpack/packer.h +27 -25
- 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 +132 -115
- data/ext/msgpack/unpacker.h +23 -10
- data/ext/msgpack/unpacker_class.c +83 -78
- 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 +4 -8
- data/lib/msgpack.rb +6 -12
- data/msgpack.gemspec +4 -6
- 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 +37 -3
- data/spec/timestamp_spec.rb +38 -0
- data/spec/unpacker_spec.rb +157 -4
- metadata +31 -61
- data/.travis.yml +0 -43
- data/README.rdoc +0 -225
- 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,10 +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);
|
131
|
+
msgpack_unpacker_set_freeze(uk, RTEST(v));
|
132
|
+
|
133
|
+
v = rb_hash_aref(options, sym_allow_unknown_ext);
|
109
134
|
msgpack_unpacker_set_allow_unknown_ext(uk, RTEST(v));
|
110
135
|
}
|
111
136
|
|
@@ -114,17 +139,23 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
114
139
|
|
115
140
|
static VALUE Unpacker_symbolized_keys_p(VALUE self)
|
116
141
|
{
|
117
|
-
|
142
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
118
143
|
return uk->symbolize_keys ? Qtrue : Qfalse;
|
119
144
|
}
|
120
145
|
|
146
|
+
static VALUE Unpacker_freeze_p(VALUE self)
|
147
|
+
{
|
148
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
149
|
+
return uk->freeze ? Qtrue : Qfalse;
|
150
|
+
}
|
151
|
+
|
121
152
|
static VALUE Unpacker_allow_unknown_ext_p(VALUE self)
|
122
153
|
{
|
123
|
-
|
154
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
124
155
|
return uk->allow_unknown_ext ? Qtrue : Qfalse;
|
125
156
|
}
|
126
157
|
|
127
|
-
static void raise_unpacker_error(int r)
|
158
|
+
NORETURN(static void raise_unpacker_error(int r))
|
128
159
|
{
|
129
160
|
switch(r) {
|
130
161
|
case PRIMITIVE_EOF:
|
@@ -136,6 +167,7 @@ static void raise_unpacker_error(int r)
|
|
136
167
|
case PRIMITIVE_UNEXPECTED_TYPE:
|
137
168
|
rb_raise(eUnexpectedTypeError, "unexpected type");
|
138
169
|
case PRIMITIVE_UNEXPECTED_EXT_TYPE:
|
170
|
+
// rb_bug("unexpected extension type");
|
139
171
|
rb_raise(eUnknownExtTypeError, "unexpected extension type");
|
140
172
|
default:
|
141
173
|
rb_raise(eUnpackError, "logically unknown error %d", r);
|
@@ -144,13 +176,13 @@ static void raise_unpacker_error(int r)
|
|
144
176
|
|
145
177
|
static VALUE Unpacker_buffer(VALUE self)
|
146
178
|
{
|
147
|
-
|
179
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
148
180
|
return uk->buffer_ref;
|
149
181
|
}
|
150
182
|
|
151
183
|
static VALUE Unpacker_read(VALUE self)
|
152
184
|
{
|
153
|
-
|
185
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
154
186
|
|
155
187
|
int r = msgpack_unpacker_read(uk, 0);
|
156
188
|
if(r < 0) {
|
@@ -162,7 +194,7 @@ static VALUE Unpacker_read(VALUE self)
|
|
162
194
|
|
163
195
|
static VALUE Unpacker_skip(VALUE self)
|
164
196
|
{
|
165
|
-
|
197
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
166
198
|
|
167
199
|
int r = msgpack_unpacker_skip(uk, 0);
|
168
200
|
if(r < 0) {
|
@@ -174,7 +206,7 @@ static VALUE Unpacker_skip(VALUE self)
|
|
174
206
|
|
175
207
|
static VALUE Unpacker_skip_nil(VALUE self)
|
176
208
|
{
|
177
|
-
|
209
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
178
210
|
|
179
211
|
int r = msgpack_unpacker_skip_nil(uk);
|
180
212
|
if(r < 0) {
|
@@ -189,7 +221,7 @@ static VALUE Unpacker_skip_nil(VALUE self)
|
|
189
221
|
|
190
222
|
static VALUE Unpacker_read_array_header(VALUE self)
|
191
223
|
{
|
192
|
-
|
224
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
193
225
|
|
194
226
|
uint32_t size;
|
195
227
|
int r = msgpack_unpacker_read_array_header(uk, &size);
|
@@ -197,12 +229,12 @@ static VALUE Unpacker_read_array_header(VALUE self)
|
|
197
229
|
raise_unpacker_error(r);
|
198
230
|
}
|
199
231
|
|
200
|
-
return ULONG2NUM(size);
|
232
|
+
return ULONG2NUM(size); // long at least 32 bits
|
201
233
|
}
|
202
234
|
|
203
235
|
static VALUE Unpacker_read_map_header(VALUE self)
|
204
236
|
{
|
205
|
-
|
237
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
206
238
|
|
207
239
|
uint32_t size;
|
208
240
|
int r = msgpack_unpacker_read_map_header(uk, &size);
|
@@ -210,41 +242,13 @@ static VALUE Unpacker_read_map_header(VALUE self)
|
|
210
242
|
raise_unpacker_error((int)r);
|
211
243
|
}
|
212
244
|
|
213
|
-
return ULONG2NUM(size);
|
245
|
+
return ULONG2NUM(size); // long at least 32 bits
|
214
246
|
}
|
215
247
|
|
216
|
-
static VALUE Unpacker_peek_next_type(VALUE self)
|
217
|
-
{
|
218
|
-
UNPACKER(self, uk);
|
219
|
-
|
220
|
-
int r = msgpack_unpacker_peek_next_object_type(uk);
|
221
|
-
if(r < 0) {
|
222
|
-
raise_unpacker_error(r);
|
223
|
-
}
|
224
|
-
|
225
|
-
switch((enum msgpack_unpacker_object_type) r) {
|
226
|
-
case TYPE_NIL:
|
227
|
-
return rb_intern("nil");
|
228
|
-
case TYPE_BOOLEAN:
|
229
|
-
return rb_intern("boolean");
|
230
|
-
case TYPE_INTEGER:
|
231
|
-
return rb_intern("integer");
|
232
|
-
case TYPE_FLOAT:
|
233
|
-
return rb_intern("float");
|
234
|
-
case TYPE_RAW:
|
235
|
-
return rb_intern("raw");
|
236
|
-
case TYPE_ARRAY:
|
237
|
-
return rb_intern("array");
|
238
|
-
case TYPE_MAP:
|
239
|
-
return rb_intern("map");
|
240
|
-
default:
|
241
|
-
rb_raise(eUnpackError, "logically unknown type %d", r);
|
242
|
-
}
|
243
|
-
}
|
244
248
|
|
245
249
|
static VALUE Unpacker_feed(VALUE self, VALUE data)
|
246
250
|
{
|
247
|
-
|
251
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
248
252
|
|
249
253
|
StringValue(data);
|
250
254
|
|
@@ -255,7 +259,7 @@ static VALUE Unpacker_feed(VALUE self, VALUE data)
|
|
255
259
|
|
256
260
|
static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
|
257
261
|
{
|
258
|
-
|
262
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
259
263
|
|
260
264
|
StringValue(data);
|
261
265
|
|
@@ -266,7 +270,7 @@ static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
|
|
266
270
|
|
267
271
|
static VALUE Unpacker_each_impl(VALUE self)
|
268
272
|
{
|
269
|
-
|
273
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
270
274
|
|
271
275
|
while(true) {
|
272
276
|
int r = msgpack_unpacker_read(uk, 0);
|
@@ -287,15 +291,16 @@ static VALUE Unpacker_each_impl(VALUE self)
|
|
287
291
|
}
|
288
292
|
}
|
289
293
|
|
290
|
-
static VALUE Unpacker_rescue_EOFError(VALUE
|
294
|
+
static VALUE Unpacker_rescue_EOFError(VALUE args, VALUE error)
|
291
295
|
{
|
292
|
-
UNUSED(
|
296
|
+
UNUSED(args);
|
297
|
+
UNUSED(error);
|
293
298
|
return Qnil;
|
294
299
|
}
|
295
300
|
|
296
301
|
static VALUE Unpacker_each(VALUE self)
|
297
302
|
{
|
298
|
-
|
303
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
299
304
|
|
300
305
|
#ifdef RETURN_ENUMERATOR
|
301
306
|
RETURN_ENUMERATOR(self, 0, 0);
|
@@ -326,7 +331,7 @@ static VALUE Unpacker_feed_each(VALUE self, VALUE data)
|
|
326
331
|
|
327
332
|
static VALUE Unpacker_reset(VALUE self)
|
328
333
|
{
|
329
|
-
|
334
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
330
335
|
|
331
336
|
_msgpack_unpacker_reset(uk);
|
332
337
|
|
@@ -335,12 +340,14 @@ static VALUE Unpacker_reset(VALUE self)
|
|
335
340
|
|
336
341
|
static VALUE Unpacker_registered_types_internal(VALUE self)
|
337
342
|
{
|
338
|
-
|
343
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
339
344
|
|
340
345
|
VALUE mapping = rb_hash_new();
|
341
|
-
|
342
|
-
|
343
|
-
|
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
|
+
}
|
344
351
|
}
|
345
352
|
}
|
346
353
|
|
@@ -349,7 +356,7 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
|
|
349
356
|
|
350
357
|
static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
351
358
|
{
|
352
|
-
|
359
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
353
360
|
|
354
361
|
int ext_type;
|
355
362
|
VALUE proc;
|
@@ -360,12 +367,7 @@ static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
|
360
367
|
case 1:
|
361
368
|
/* register_type(0x7f) {|data| block... } */
|
362
369
|
rb_need_block();
|
363
|
-
#ifdef HAVE_RB_BLOCK_LAMBDA
|
364
370
|
proc = rb_block_lambda();
|
365
|
-
#else
|
366
|
-
/* MRI 1.8 */
|
367
|
-
proc = rb_block_proc();
|
368
|
-
#endif
|
369
371
|
arg = proc;
|
370
372
|
ext_module = Qnil;
|
371
373
|
break;
|
@@ -384,14 +386,14 @@ static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
|
384
386
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
385
387
|
}
|
386
388
|
|
387
|
-
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);
|
388
390
|
|
389
391
|
return Qnil;
|
390
392
|
}
|
391
393
|
|
392
394
|
static VALUE Unpacker_full_unpack(VALUE self)
|
393
395
|
{
|
394
|
-
|
396
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
395
397
|
|
396
398
|
int r = msgpack_unpacker_read(uk, 0);
|
397
399
|
if(r < 0) {
|
@@ -434,10 +436,15 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
434
436
|
|
435
437
|
eUnknownExtTypeError = rb_define_class_under(mMessagePack, "UnknownExtTypeError", eUnpackError);
|
436
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
|
+
|
437
443
|
rb_define_alloc_func(cMessagePack_Unpacker, MessagePack_Unpacker_alloc);
|
438
444
|
|
439
445
|
rb_define_method(cMessagePack_Unpacker, "initialize", MessagePack_Unpacker_initialize, -1);
|
440
446
|
rb_define_method(cMessagePack_Unpacker, "symbolize_keys?", Unpacker_symbolized_keys_p, 0);
|
447
|
+
rb_define_method(cMessagePack_Unpacker, "freeze?", Unpacker_freeze_p, 0);
|
441
448
|
rb_define_method(cMessagePack_Unpacker, "allow_unknown_ext?", Unpacker_allow_unknown_ext_p, 0);
|
442
449
|
rb_define_method(cMessagePack_Unpacker, "buffer", Unpacker_buffer, 0);
|
443
450
|
rb_define_method(cMessagePack_Unpacker, "read", Unpacker_read, 0);
|
@@ -446,7 +453,6 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
446
453
|
rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
|
447
454
|
rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
|
448
455
|
rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
|
449
|
-
//rb_define_method(cMessagePack_Unpacker, "peek_next_type", Unpacker_peek_next_type, 0); // TODO
|
450
456
|
rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1);
|
451
457
|
rb_define_method(cMessagePack_Unpacker, "feed_reference", Unpacker_feed_reference, 1);
|
452
458
|
rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
|
@@ -464,4 +470,3 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
464
470
|
|
465
471
|
rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
|
466
472
|
}
|
467
|
-
|
@@ -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
|