msgpack 1.4.2 → 1.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +89 -0
- data/README.md +73 -13
- data/ext/java/org/msgpack/jruby/Buffer.java +26 -19
- 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 +43 -64
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +6 -9
- data/ext/java/org/msgpack/jruby/Factory.java +43 -42
- data/ext/java/org/msgpack/jruby/Packer.java +37 -40
- data/ext/java/org/msgpack/jruby/Unpacker.java +80 -73
- data/ext/msgpack/buffer.c +54 -74
- data/ext/msgpack/buffer.h +21 -18
- data/ext/msgpack/buffer_class.c +161 -52
- data/ext/msgpack/buffer_class.h +1 -0
- data/ext/msgpack/compat.h +0 -99
- data/ext/msgpack/extconf.rb +25 -46
- data/ext/msgpack/factory_class.c +143 -87
- data/ext/msgpack/packer.c +66 -43
- data/ext/msgpack/packer.h +25 -20
- data/ext/msgpack/packer_class.c +102 -130
- data/ext/msgpack/packer_class.h +11 -0
- data/ext/msgpack/packer_ext_registry.c +35 -40
- data/ext/msgpack/packer_ext_registry.h +41 -38
- data/ext/msgpack/rbinit.c +1 -1
- data/ext/msgpack/rmem.c +3 -4
- data/ext/msgpack/sysdep.h +5 -2
- data/ext/msgpack/unpacker.c +136 -111
- data/ext/msgpack/unpacker.h +16 -13
- data/ext/msgpack/unpacker_class.c +86 -126
- data/ext/msgpack/unpacker_class.h +11 -0
- data/ext/msgpack/unpacker_ext_registry.c +40 -28
- data/ext/msgpack/unpacker_ext_registry.h +21 -18
- data/lib/msgpack/bigint.rb +69 -0
- data/lib/msgpack/buffer.rb +9 -0
- data/lib/msgpack/factory.rb +140 -10
- data/lib/msgpack/packer.rb +10 -1
- data/lib/msgpack/symbol.rb +21 -4
- data/lib/msgpack/time.rb +1 -1
- data/lib/msgpack/unpacker.rb +14 -1
- data/lib/msgpack/version.rb +1 -1
- data/lib/msgpack.rb +6 -7
- data/msgpack.gemspec +8 -5
- metadata +37 -82
- data/.gitignore +0 -23
- data/.rubocop.yml +0 -36
- data/.travis.yml +0 -39
- data/Gemfile +0 -9
- data/Rakefile +0 -71
- data/appveyor.yml +0 -18
- 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/doclib/msgpack/buffer.rb +0 -193
- data/doclib/msgpack/core_ext.rb +0 -101
- data/doclib/msgpack/error.rb +0 -19
- data/doclib/msgpack/extension_value.rb +0 -9
- data/doclib/msgpack/factory.rb +0 -101
- data/doclib/msgpack/packer.rb +0 -208
- data/doclib/msgpack/time.rb +0 -22
- data/doclib/msgpack/timestamp.rb +0 -44
- data/doclib/msgpack/unpacker.rb +0 -183
- data/doclib/msgpack.rb +0 -87
- data/msgpack.org.md +0 -46
- data/spec/cases.json +0 -1
- data/spec/cases.msg +0 -0
- data/spec/cases_compact.msg +0 -0
- data/spec/cases_spec.rb +0 -39
- data/spec/cruby/buffer_io_spec.rb +0 -255
- data/spec/cruby/buffer_packer.rb +0 -29
- data/spec/cruby/buffer_spec.rb +0 -575
- data/spec/cruby/buffer_unpacker.rb +0 -19
- data/spec/cruby/unpacker_spec.rb +0 -70
- data/spec/ext_value_spec.rb +0 -99
- data/spec/exttypes.rb +0 -51
- data/spec/factory_spec.rb +0 -367
- data/spec/format_spec.rb +0 -301
- data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
- data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
- data/spec/jruby/unpacker_spec.rb +0 -186
- data/spec/msgpack_spec.rb +0 -214
- data/spec/pack_spec.rb +0 -61
- data/spec/packer_spec.rb +0 -557
- data/spec/random_compat.rb +0 -24
- data/spec/spec_helper.rb +0 -55
- data/spec/timestamp_spec.rb +0 -121
- data/spec/unpack_spec.rb +0 -57
- data/spec/unpacker_spec.rb +0 -819
@@ -33,35 +33,59 @@ 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;
|
54
|
+
msgpack_buffer_mark(uk);
|
55
55
|
msgpack_unpacker_mark(uk);
|
56
|
-
msgpack_unpacker_ext_registry_mark(
|
56
|
+
msgpack_unpacker_ext_registry_mark(uk->ext_registry);
|
57
57
|
}
|
58
58
|
|
59
|
+
static size_t Unpacker_memsize(const void *ptr)
|
60
|
+
{
|
61
|
+
size_t total_size = sizeof(msgpack_unpacker_t);
|
62
|
+
|
63
|
+
const msgpack_unpacker_t* uk = ptr;
|
64
|
+
if (uk->ext_registry) {
|
65
|
+
total_size += sizeof(msgpack_unpacker_ext_registry_t) / (uk->ext_registry->borrow_count + 1);
|
66
|
+
}
|
67
|
+
|
68
|
+
total_size += (uk->stack->depth + 1) * sizeof(msgpack_unpacker_stack_t);
|
69
|
+
|
70
|
+
return total_size + msgpack_buffer_memsize(&uk->buffer);
|
71
|
+
}
|
72
|
+
|
73
|
+
const rb_data_type_t unpacker_data_type = {
|
74
|
+
.wrap_struct_name = "msgpack:unpacker",
|
75
|
+
.function = {
|
76
|
+
.dmark = Unpacker_mark,
|
77
|
+
.dfree = Unpacker_free,
|
78
|
+
.dsize = Unpacker_memsize,
|
79
|
+
},
|
80
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
81
|
+
};
|
82
|
+
|
59
83
|
VALUE MessagePack_Unpacker_alloc(VALUE klass)
|
60
84
|
{
|
61
|
-
msgpack_unpacker_t* uk
|
85
|
+
msgpack_unpacker_t* uk;
|
86
|
+
VALUE self = TypedData_Make_Struct(klass, msgpack_unpacker_t, &unpacker_data_type, uk);
|
62
87
|
_msgpack_unpacker_init(uk);
|
63
|
-
|
64
|
-
VALUE self = Data_Wrap_Struct(klass, Unpacker_mark, Unpacker_free, uk);
|
88
|
+
uk->self = self;
|
65
89
|
return self;
|
66
90
|
}
|
67
91
|
|
@@ -84,7 +108,7 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
84
108
|
} else if(argc == 2) {
|
85
109
|
io = argv[0];
|
86
110
|
options = argv[1];
|
87
|
-
if(rb_type(options) != T_HASH) {
|
111
|
+
if(options != Qnil && rb_type(options) != T_HASH) {
|
88
112
|
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
|
89
113
|
}
|
90
114
|
|
@@ -92,23 +116,22 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
92
116
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
|
93
117
|
}
|
94
118
|
|
95
|
-
|
119
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
96
120
|
|
97
|
-
|
98
|
-
uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
|
121
|
+
uk->buffer_ref = Qnil;
|
99
122
|
|
100
123
|
MessagePack_Buffer_set_options(UNPACKER_BUFFER_(uk), io, options);
|
101
124
|
|
102
125
|
if(options != Qnil) {
|
103
126
|
VALUE v;
|
104
127
|
|
105
|
-
v = rb_hash_aref(options,
|
128
|
+
v = rb_hash_aref(options, sym_symbolize_keys);
|
106
129
|
msgpack_unpacker_set_symbolized_keys(uk, RTEST(v));
|
107
130
|
|
108
|
-
v = rb_hash_aref(options,
|
131
|
+
v = rb_hash_aref(options, sym_freeze);
|
109
132
|
msgpack_unpacker_set_freeze(uk, RTEST(v));
|
110
133
|
|
111
|
-
v = rb_hash_aref(options,
|
134
|
+
v = rb_hash_aref(options, sym_allow_unknown_ext);
|
112
135
|
msgpack_unpacker_set_allow_unknown_ext(uk, RTEST(v));
|
113
136
|
}
|
114
137
|
|
@@ -117,23 +140,23 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
117
140
|
|
118
141
|
static VALUE Unpacker_symbolized_keys_p(VALUE self)
|
119
142
|
{
|
120
|
-
|
143
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
121
144
|
return uk->symbolize_keys ? Qtrue : Qfalse;
|
122
145
|
}
|
123
146
|
|
124
147
|
static VALUE Unpacker_freeze_p(VALUE self)
|
125
148
|
{
|
126
|
-
|
149
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
127
150
|
return uk->freeze ? Qtrue : Qfalse;
|
128
151
|
}
|
129
152
|
|
130
153
|
static VALUE Unpacker_allow_unknown_ext_p(VALUE self)
|
131
154
|
{
|
132
|
-
|
155
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
133
156
|
return uk->allow_unknown_ext ? Qtrue : Qfalse;
|
134
157
|
}
|
135
158
|
|
136
|
-
static void raise_unpacker_error(int r)
|
159
|
+
NORETURN(static void raise_unpacker_error(int r))
|
137
160
|
{
|
138
161
|
switch(r) {
|
139
162
|
case PRIMITIVE_EOF:
|
@@ -145,6 +168,7 @@ static void raise_unpacker_error(int r)
|
|
145
168
|
case PRIMITIVE_UNEXPECTED_TYPE:
|
146
169
|
rb_raise(eUnexpectedTypeError, "unexpected type");
|
147
170
|
case PRIMITIVE_UNEXPECTED_EXT_TYPE:
|
171
|
+
// rb_bug("unexpected extension type");
|
148
172
|
rb_raise(eUnknownExtTypeError, "unexpected extension type");
|
149
173
|
default:
|
150
174
|
rb_raise(eUnpackError, "logically unknown error %d", r);
|
@@ -153,13 +177,16 @@ static void raise_unpacker_error(int r)
|
|
153
177
|
|
154
178
|
static VALUE Unpacker_buffer(VALUE self)
|
155
179
|
{
|
156
|
-
|
180
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
181
|
+
if (!RTEST(uk->buffer_ref)) {
|
182
|
+
uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
|
183
|
+
}
|
157
184
|
return uk->buffer_ref;
|
158
185
|
}
|
159
186
|
|
160
187
|
static VALUE Unpacker_read(VALUE self)
|
161
188
|
{
|
162
|
-
|
189
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
163
190
|
|
164
191
|
int r = msgpack_unpacker_read(uk, 0);
|
165
192
|
if(r < 0) {
|
@@ -171,7 +198,7 @@ static VALUE Unpacker_read(VALUE self)
|
|
171
198
|
|
172
199
|
static VALUE Unpacker_skip(VALUE self)
|
173
200
|
{
|
174
|
-
|
201
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
175
202
|
|
176
203
|
int r = msgpack_unpacker_skip(uk, 0);
|
177
204
|
if(r < 0) {
|
@@ -183,7 +210,7 @@ static VALUE Unpacker_skip(VALUE self)
|
|
183
210
|
|
184
211
|
static VALUE Unpacker_skip_nil(VALUE self)
|
185
212
|
{
|
186
|
-
|
213
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
187
214
|
|
188
215
|
int r = msgpack_unpacker_skip_nil(uk);
|
189
216
|
if(r < 0) {
|
@@ -198,7 +225,7 @@ static VALUE Unpacker_skip_nil(VALUE self)
|
|
198
225
|
|
199
226
|
static VALUE Unpacker_read_array_header(VALUE self)
|
200
227
|
{
|
201
|
-
|
228
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
202
229
|
|
203
230
|
uint32_t size;
|
204
231
|
int r = msgpack_unpacker_read_array_header(uk, &size);
|
@@ -206,12 +233,12 @@ static VALUE Unpacker_read_array_header(VALUE self)
|
|
206
233
|
raise_unpacker_error(r);
|
207
234
|
}
|
208
235
|
|
209
|
-
return ULONG2NUM(size);
|
236
|
+
return ULONG2NUM(size); // long at least 32 bits
|
210
237
|
}
|
211
238
|
|
212
239
|
static VALUE Unpacker_read_map_header(VALUE self)
|
213
240
|
{
|
214
|
-
|
241
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
215
242
|
|
216
243
|
uint32_t size;
|
217
244
|
int r = msgpack_unpacker_read_map_header(uk, &size);
|
@@ -219,52 +246,12 @@ static VALUE Unpacker_read_map_header(VALUE self)
|
|
219
246
|
raise_unpacker_error((int)r);
|
220
247
|
}
|
221
248
|
|
222
|
-
return ULONG2NUM(size);
|
223
|
-
}
|
224
|
-
|
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
|
-
|
254
|
-
static VALUE Unpacker_feed(VALUE self, VALUE data)
|
255
|
-
{
|
256
|
-
UNPACKER(self, uk);
|
257
|
-
|
258
|
-
StringValue(data);
|
259
|
-
|
260
|
-
msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), data);
|
261
|
-
|
262
|
-
return self;
|
249
|
+
return ULONG2NUM(size); // long at least 32 bits
|
263
250
|
}
|
264
251
|
|
265
252
|
static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
|
266
253
|
{
|
267
|
-
|
254
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
268
255
|
|
269
256
|
StringValue(data);
|
270
257
|
|
@@ -275,7 +262,7 @@ static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
|
|
275
262
|
|
276
263
|
static VALUE Unpacker_each_impl(VALUE self)
|
277
264
|
{
|
278
|
-
|
265
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
279
266
|
|
280
267
|
while(true) {
|
281
268
|
int r = msgpack_unpacker_read(uk, 0);
|
@@ -296,15 +283,16 @@ static VALUE Unpacker_each_impl(VALUE self)
|
|
296
283
|
}
|
297
284
|
}
|
298
285
|
|
299
|
-
static VALUE Unpacker_rescue_EOFError(VALUE
|
286
|
+
static VALUE Unpacker_rescue_EOFError(VALUE args, VALUE error)
|
300
287
|
{
|
301
|
-
UNUSED(
|
288
|
+
UNUSED(args);
|
289
|
+
UNUSED(error);
|
302
290
|
return Qnil;
|
303
291
|
}
|
304
292
|
|
305
293
|
static VALUE Unpacker_each(VALUE self)
|
306
294
|
{
|
307
|
-
|
295
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
308
296
|
|
309
297
|
#ifdef RETURN_ENUMERATOR
|
310
298
|
RETURN_ENUMERATOR(self, 0, 0);
|
@@ -335,7 +323,7 @@ static VALUE Unpacker_feed_each(VALUE self, VALUE data)
|
|
335
323
|
|
336
324
|
static VALUE Unpacker_reset(VALUE self)
|
337
325
|
{
|
338
|
-
|
326
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
339
327
|
|
340
328
|
_msgpack_unpacker_reset(uk);
|
341
329
|
|
@@ -344,63 +332,40 @@ static VALUE Unpacker_reset(VALUE self)
|
|
344
332
|
|
345
333
|
static VALUE Unpacker_registered_types_internal(VALUE self)
|
346
334
|
{
|
347
|
-
|
335
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
348
336
|
|
349
337
|
VALUE mapping = rb_hash_new();
|
350
|
-
|
351
|
-
|
352
|
-
|
338
|
+
if (uk->ext_registry) {
|
339
|
+
for(int i=0; i < 256; i++) {
|
340
|
+
if(uk->ext_registry->array[i] != Qnil) {
|
341
|
+
rb_hash_aset(mapping, INT2FIX(i - 128), uk->ext_registry->array[i]);
|
342
|
+
}
|
353
343
|
}
|
354
344
|
}
|
355
345
|
|
356
346
|
return mapping;
|
357
347
|
}
|
358
348
|
|
359
|
-
static VALUE
|
349
|
+
static VALUE Unpacker_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
|
360
350
|
{
|
361
|
-
|
362
|
-
|
363
|
-
int ext_type;
|
364
|
-
VALUE proc;
|
365
|
-
VALUE arg;
|
366
|
-
VALUE ext_module;
|
367
|
-
|
368
|
-
switch (argc) {
|
369
|
-
case 1:
|
370
|
-
/* register_type(0x7f) {|data| block... } */
|
371
|
-
rb_need_block();
|
372
|
-
#ifdef HAVE_RB_BLOCK_LAMBDA
|
373
|
-
proc = rb_block_lambda();
|
374
|
-
#else
|
375
|
-
/* MRI 1.8 */
|
376
|
-
proc = rb_block_proc();
|
377
|
-
#endif
|
378
|
-
arg = proc;
|
379
|
-
ext_module = Qnil;
|
380
|
-
break;
|
381
|
-
case 3:
|
382
|
-
/* register_type(0x7f, Time, :from_msgpack_ext) */
|
383
|
-
ext_module = argv[1];
|
384
|
-
arg = argv[2];
|
385
|
-
proc = rb_obj_method(ext_module, arg);
|
386
|
-
break;
|
387
|
-
default:
|
388
|
-
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 3)", argc);
|
351
|
+
if (OBJ_FROZEN(self)) {
|
352
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Unpacker");
|
389
353
|
}
|
390
354
|
|
391
|
-
ext_type = NUM2INT(
|
355
|
+
int ext_type = NUM2INT(rb_ext_type);
|
392
356
|
if(ext_type < -128 || ext_type > 127) {
|
393
357
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
394
358
|
}
|
395
359
|
|
396
|
-
|
360
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
361
|
+
msgpack_unpacker_ext_registry_put(self, &uk->ext_registry, ext_module, ext_type, 0, proc);
|
397
362
|
|
398
363
|
return Qnil;
|
399
364
|
}
|
400
365
|
|
401
366
|
static VALUE Unpacker_full_unpack(VALUE self)
|
402
367
|
{
|
403
|
-
|
368
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
404
369
|
|
405
370
|
int r = msgpack_unpacker_read(uk, 0);
|
406
371
|
if(r < 0) {
|
@@ -426,7 +391,6 @@ VALUE MessagePack_Unpacker_new(int argc, VALUE* argv)
|
|
426
391
|
void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
427
392
|
{
|
428
393
|
msgpack_unpacker_static_init();
|
429
|
-
msgpack_unpacker_ext_registry_static_init();
|
430
394
|
|
431
395
|
mTypeError = rb_define_module_under(mMessagePack, "TypeError");
|
432
396
|
|
@@ -443,6 +407,10 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
443
407
|
|
444
408
|
eUnknownExtTypeError = rb_define_class_under(mMessagePack, "UnknownExtTypeError", eUnpackError);
|
445
409
|
|
410
|
+
sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
|
411
|
+
sym_freeze = ID2SYM(rb_intern("freeze"));
|
412
|
+
sym_allow_unknown_ext = ID2SYM(rb_intern("allow_unknown_ext"));
|
413
|
+
|
446
414
|
rb_define_alloc_func(cMessagePack_Unpacker, MessagePack_Unpacker_alloc);
|
447
415
|
|
448
416
|
rb_define_method(cMessagePack_Unpacker, "initialize", MessagePack_Unpacker_initialize, -1);
|
@@ -456,22 +424,14 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
456
424
|
rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
|
457
425
|
rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
|
458
426
|
rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
|
459
|
-
|
460
|
-
|
461
|
-
rb_define_method(cMessagePack_Unpacker, "feed_reference", Unpacker_feed_reference, 1);
|
427
|
+
rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed_reference, 1);
|
428
|
+
rb_define_alias(cMessagePack_Unpacker, "feed_reference", "feed");
|
462
429
|
rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
|
463
430
|
rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1);
|
464
431
|
rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
|
465
432
|
|
466
433
|
rb_define_private_method(cMessagePack_Unpacker, "registered_types_internal", Unpacker_registered_types_internal, 0);
|
467
|
-
|
468
|
-
|
469
|
-
//s_unpacker_value = MessagePack_Unpacker_alloc(cMessagePack_Unpacker);
|
470
|
-
//rb_gc_register_address(&s_unpacker_value);
|
471
|
-
//Data_Get_Struct(s_unpacker_value, msgpack_unpacker_t, s_unpacker);
|
472
|
-
/* prefer reference than copying */
|
473
|
-
//msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(s_unpacker), 0);
|
434
|
+
rb_define_private_method(cMessagePack_Unpacker, "register_type_internal", Unpacker_register_type_internal, 3);
|
474
435
|
|
475
436
|
rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
|
476
437
|
}
|
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);
|
@@ -18,45 +18,57 @@
|
|
18
18
|
|
19
19
|
#include "unpacker_ext_registry.h"
|
20
20
|
|
21
|
-
|
22
|
-
static ID s_dup;
|
23
|
-
|
24
|
-
void msgpack_unpacker_ext_registry_static_init()
|
25
|
-
{
|
26
|
-
s_call = rb_intern("call");
|
27
|
-
s_dup = rb_intern("dup");
|
28
|
-
}
|
29
|
-
|
30
|
-
void msgpack_unpacker_ext_registry_static_destroy()
|
31
|
-
{ }
|
32
|
-
|
33
|
-
void msgpack_unpacker_ext_registry_init(msgpack_unpacker_ext_registry_t* ukrg)
|
21
|
+
void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg)
|
34
22
|
{
|
35
|
-
|
36
|
-
|
23
|
+
if (ukrg) {
|
24
|
+
for(int i=0; i < 256; i++) {
|
25
|
+
if (ukrg->array[i] != Qnil) {
|
26
|
+
rb_gc_mark(ukrg->array[i]);
|
27
|
+
}
|
28
|
+
}
|
37
29
|
}
|
38
30
|
}
|
39
31
|
|
40
|
-
|
32
|
+
msgpack_unpacker_ext_registry_t* msgpack_unpacker_ext_registry_cow(msgpack_unpacker_ext_registry_t* src)
|
41
33
|
{
|
42
|
-
|
43
|
-
|
34
|
+
msgpack_unpacker_ext_registry_t* dst;
|
35
|
+
if (src) {
|
36
|
+
if (src->borrow_count) {
|
37
|
+
dst = ALLOC(msgpack_unpacker_ext_registry_t);
|
38
|
+
dst->borrow_count = 0;
|
39
|
+
MEMCPY(dst->array, src->array, VALUE, 256);
|
40
|
+
msgpack_unpacker_ext_registry_release(src);
|
41
|
+
return dst;
|
42
|
+
} else {
|
43
|
+
return src;
|
44
|
+
}
|
45
|
+
} else {
|
46
|
+
dst = ALLOC(msgpack_unpacker_ext_registry_t);
|
47
|
+
dst->borrow_count = 0;
|
48
|
+
for(int i=0; i < 256; i++) {
|
49
|
+
dst->array[i] = Qnil;
|
50
|
+
}
|
51
|
+
return dst;
|
44
52
|
}
|
45
53
|
}
|
46
54
|
|
47
|
-
void
|
48
|
-
msgpack_unpacker_ext_registry_t* dst)
|
55
|
+
void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg)
|
49
56
|
{
|
50
|
-
|
51
|
-
|
57
|
+
if (ukrg) {
|
58
|
+
if (ukrg->borrow_count) {
|
59
|
+
ukrg->borrow_count--;
|
60
|
+
} else {
|
61
|
+
xfree(ukrg);
|
62
|
+
}
|
52
63
|
}
|
53
64
|
}
|
54
65
|
|
55
|
-
|
56
|
-
VALUE ext_module, int ext_type,
|
66
|
+
void msgpack_unpacker_ext_registry_put(VALUE owner, msgpack_unpacker_ext_registry_t** ukrg,
|
67
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc)
|
57
68
|
{
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
69
|
+
msgpack_unpacker_ext_registry_t* ext_registry = msgpack_unpacker_ext_registry_cow(*ukrg);
|
70
|
+
|
71
|
+
VALUE entry = rb_ary_new3(3, ext_module, proc, INT2FIX(flags));
|
72
|
+
RB_OBJ_WRITE(owner, &ext_registry->array[ext_type + 128], entry);
|
73
|
+
*ukrg = ext_registry;
|
62
74
|
}
|
@@ -21,39 +21,42 @@
|
|
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
|
33
|
-
|
34
|
-
void msgpack_unpacker_ext_registry_static_destroy();
|
34
|
+
void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg);
|
35
35
|
|
36
|
-
void
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_registry_t* src, msgpack_unpacker_ext_registry_t** dst)
|
37
|
+
{
|
38
|
+
if (src) {
|
39
|
+
src->borrow_count++;
|
40
|
+
*dst = src;
|
41
|
+
}
|
42
|
+
}
|
40
43
|
|
41
44
|
void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg);
|
42
45
|
|
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);
|
46
|
+
void msgpack_unpacker_ext_registry_put(VALUE owner, msgpack_unpacker_ext_registry_t** ukrg,
|
47
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc);
|
48
48
|
|
49
49
|
static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_registry_t* ukrg,
|
50
|
-
int ext_type)
|
50
|
+
int ext_type, int* ext_flags_result)
|
51
51
|
{
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
if (ukrg) {
|
53
|
+
VALUE entry = ukrg->array[ext_type + 128];
|
54
|
+
if (entry != Qnil) {
|
55
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(entry, 2));
|
56
|
+
return rb_ary_entry(entry, 1);
|
57
|
+
}
|
55
58
|
}
|
56
|
-
return
|
59
|
+
return Qnil;
|
57
60
|
}
|
58
61
|
|
59
62
|
#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
|