msgpack 1.3.0 → 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/.gitignore +3 -1
- data/.rubocop.yml +2 -2
- data/ChangeLog +86 -0
- data/Gemfile +3 -0
- 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/time.rb +1 -1
- 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 -81
- 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/timestamp.rb +1 -1
- data/lib/msgpack/version.rb +4 -7
- data/lib/msgpack.rb +6 -12
- data/msgpack.gemspec +4 -7
- 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 +42 -0
- data/spec/unpacker_spec.rb +157 -4
- metadata +32 -62
- 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
|
|
@@ -77,9 +100,6 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
77
100
|
VALUE v = argv[0];
|
78
101
|
if(rb_type(v) == T_HASH) {
|
79
102
|
options = v;
|
80
|
-
if(rb_type(options) != T_HASH) {
|
81
|
-
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
|
82
|
-
}
|
83
103
|
} else {
|
84
104
|
io = v;
|
85
105
|
}
|
@@ -87,7 +107,7 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
87
107
|
} else if(argc == 2) {
|
88
108
|
io = argv[0];
|
89
109
|
options = argv[1];
|
90
|
-
if(rb_type(options) != T_HASH) {
|
110
|
+
if(options != Qnil && rb_type(options) != T_HASH) {
|
91
111
|
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
|
92
112
|
}
|
93
113
|
|
@@ -95,9 +115,8 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
95
115
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
|
96
116
|
}
|
97
117
|
|
98
|
-
|
118
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
99
119
|
|
100
|
-
msgpack_unpacker_ext_registry_init(&uk->ext_registry);
|
101
120
|
uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
|
102
121
|
|
103
122
|
MessagePack_Buffer_set_options(UNPACKER_BUFFER_(uk), io, options);
|
@@ -105,10 +124,13 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
105
124
|
if(options != Qnil) {
|
106
125
|
VALUE v;
|
107
126
|
|
108
|
-
v = rb_hash_aref(options,
|
127
|
+
v = rb_hash_aref(options, sym_symbolize_keys);
|
109
128
|
msgpack_unpacker_set_symbolized_keys(uk, RTEST(v));
|
110
129
|
|
111
|
-
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);
|
112
134
|
msgpack_unpacker_set_allow_unknown_ext(uk, RTEST(v));
|
113
135
|
}
|
114
136
|
|
@@ -117,17 +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
|
|
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
|
+
|
124
152
|
static VALUE Unpacker_allow_unknown_ext_p(VALUE self)
|
125
153
|
{
|
126
|
-
|
154
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
127
155
|
return uk->allow_unknown_ext ? Qtrue : Qfalse;
|
128
156
|
}
|
129
157
|
|
130
|
-
static void raise_unpacker_error(int r)
|
158
|
+
NORETURN(static void raise_unpacker_error(int r))
|
131
159
|
{
|
132
160
|
switch(r) {
|
133
161
|
case PRIMITIVE_EOF:
|
@@ -139,6 +167,7 @@ static void raise_unpacker_error(int r)
|
|
139
167
|
case PRIMITIVE_UNEXPECTED_TYPE:
|
140
168
|
rb_raise(eUnexpectedTypeError, "unexpected type");
|
141
169
|
case PRIMITIVE_UNEXPECTED_EXT_TYPE:
|
170
|
+
// rb_bug("unexpected extension type");
|
142
171
|
rb_raise(eUnknownExtTypeError, "unexpected extension type");
|
143
172
|
default:
|
144
173
|
rb_raise(eUnpackError, "logically unknown error %d", r);
|
@@ -147,13 +176,13 @@ static void raise_unpacker_error(int r)
|
|
147
176
|
|
148
177
|
static VALUE Unpacker_buffer(VALUE self)
|
149
178
|
{
|
150
|
-
|
179
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
151
180
|
return uk->buffer_ref;
|
152
181
|
}
|
153
182
|
|
154
183
|
static VALUE Unpacker_read(VALUE self)
|
155
184
|
{
|
156
|
-
|
185
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
157
186
|
|
158
187
|
int r = msgpack_unpacker_read(uk, 0);
|
159
188
|
if(r < 0) {
|
@@ -165,7 +194,7 @@ static VALUE Unpacker_read(VALUE self)
|
|
165
194
|
|
166
195
|
static VALUE Unpacker_skip(VALUE self)
|
167
196
|
{
|
168
|
-
|
197
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
169
198
|
|
170
199
|
int r = msgpack_unpacker_skip(uk, 0);
|
171
200
|
if(r < 0) {
|
@@ -177,7 +206,7 @@ static VALUE Unpacker_skip(VALUE self)
|
|
177
206
|
|
178
207
|
static VALUE Unpacker_skip_nil(VALUE self)
|
179
208
|
{
|
180
|
-
|
209
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
181
210
|
|
182
211
|
int r = msgpack_unpacker_skip_nil(uk);
|
183
212
|
if(r < 0) {
|
@@ -192,7 +221,7 @@ static VALUE Unpacker_skip_nil(VALUE self)
|
|
192
221
|
|
193
222
|
static VALUE Unpacker_read_array_header(VALUE self)
|
194
223
|
{
|
195
|
-
|
224
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
196
225
|
|
197
226
|
uint32_t size;
|
198
227
|
int r = msgpack_unpacker_read_array_header(uk, &size);
|
@@ -200,12 +229,12 @@ static VALUE Unpacker_read_array_header(VALUE self)
|
|
200
229
|
raise_unpacker_error(r);
|
201
230
|
}
|
202
231
|
|
203
|
-
return ULONG2NUM(size);
|
232
|
+
return ULONG2NUM(size); // long at least 32 bits
|
204
233
|
}
|
205
234
|
|
206
235
|
static VALUE Unpacker_read_map_header(VALUE self)
|
207
236
|
{
|
208
|
-
|
237
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
209
238
|
|
210
239
|
uint32_t size;
|
211
240
|
int r = msgpack_unpacker_read_map_header(uk, &size);
|
@@ -213,41 +242,13 @@ static VALUE Unpacker_read_map_header(VALUE self)
|
|
213
242
|
raise_unpacker_error((int)r);
|
214
243
|
}
|
215
244
|
|
216
|
-
return ULONG2NUM(size);
|
245
|
+
return ULONG2NUM(size); // long at least 32 bits
|
217
246
|
}
|
218
247
|
|
219
|
-
static VALUE Unpacker_peek_next_type(VALUE self)
|
220
|
-
{
|
221
|
-
UNPACKER(self, uk);
|
222
|
-
|
223
|
-
int r = msgpack_unpacker_peek_next_object_type(uk);
|
224
|
-
if(r < 0) {
|
225
|
-
raise_unpacker_error(r);
|
226
|
-
}
|
227
|
-
|
228
|
-
switch((enum msgpack_unpacker_object_type) r) {
|
229
|
-
case TYPE_NIL:
|
230
|
-
return rb_intern("nil");
|
231
|
-
case TYPE_BOOLEAN:
|
232
|
-
return rb_intern("boolean");
|
233
|
-
case TYPE_INTEGER:
|
234
|
-
return rb_intern("integer");
|
235
|
-
case TYPE_FLOAT:
|
236
|
-
return rb_intern("float");
|
237
|
-
case TYPE_RAW:
|
238
|
-
return rb_intern("raw");
|
239
|
-
case TYPE_ARRAY:
|
240
|
-
return rb_intern("array");
|
241
|
-
case TYPE_MAP:
|
242
|
-
return rb_intern("map");
|
243
|
-
default:
|
244
|
-
rb_raise(eUnpackError, "logically unknown type %d", r);
|
245
|
-
}
|
246
|
-
}
|
247
248
|
|
248
249
|
static VALUE Unpacker_feed(VALUE self, VALUE data)
|
249
250
|
{
|
250
|
-
|
251
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
251
252
|
|
252
253
|
StringValue(data);
|
253
254
|
|
@@ -258,7 +259,7 @@ static VALUE Unpacker_feed(VALUE self, VALUE data)
|
|
258
259
|
|
259
260
|
static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
|
260
261
|
{
|
261
|
-
|
262
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
262
263
|
|
263
264
|
StringValue(data);
|
264
265
|
|
@@ -269,7 +270,7 @@ static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
|
|
269
270
|
|
270
271
|
static VALUE Unpacker_each_impl(VALUE self)
|
271
272
|
{
|
272
|
-
|
273
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
273
274
|
|
274
275
|
while(true) {
|
275
276
|
int r = msgpack_unpacker_read(uk, 0);
|
@@ -290,15 +291,16 @@ static VALUE Unpacker_each_impl(VALUE self)
|
|
290
291
|
}
|
291
292
|
}
|
292
293
|
|
293
|
-
static VALUE Unpacker_rescue_EOFError(VALUE
|
294
|
+
static VALUE Unpacker_rescue_EOFError(VALUE args, VALUE error)
|
294
295
|
{
|
295
|
-
UNUSED(
|
296
|
+
UNUSED(args);
|
297
|
+
UNUSED(error);
|
296
298
|
return Qnil;
|
297
299
|
}
|
298
300
|
|
299
301
|
static VALUE Unpacker_each(VALUE self)
|
300
302
|
{
|
301
|
-
|
303
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
302
304
|
|
303
305
|
#ifdef RETURN_ENUMERATOR
|
304
306
|
RETURN_ENUMERATOR(self, 0, 0);
|
@@ -329,7 +331,7 @@ static VALUE Unpacker_feed_each(VALUE self, VALUE data)
|
|
329
331
|
|
330
332
|
static VALUE Unpacker_reset(VALUE self)
|
331
333
|
{
|
332
|
-
|
334
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
333
335
|
|
334
336
|
_msgpack_unpacker_reset(uk);
|
335
337
|
|
@@ -338,12 +340,14 @@ static VALUE Unpacker_reset(VALUE self)
|
|
338
340
|
|
339
341
|
static VALUE Unpacker_registered_types_internal(VALUE self)
|
340
342
|
{
|
341
|
-
|
343
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
342
344
|
|
343
345
|
VALUE mapping = rb_hash_new();
|
344
|
-
|
345
|
-
|
346
|
-
|
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
|
+
}
|
347
351
|
}
|
348
352
|
}
|
349
353
|
|
@@ -352,7 +356,7 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
|
|
352
356
|
|
353
357
|
static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
354
358
|
{
|
355
|
-
|
359
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
356
360
|
|
357
361
|
int ext_type;
|
358
362
|
VALUE proc;
|
@@ -363,12 +367,7 @@ static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
|
363
367
|
case 1:
|
364
368
|
/* register_type(0x7f) {|data| block... } */
|
365
369
|
rb_need_block();
|
366
|
-
#ifdef HAVE_RB_BLOCK_LAMBDA
|
367
370
|
proc = rb_block_lambda();
|
368
|
-
#else
|
369
|
-
/* MRI 1.8 */
|
370
|
-
proc = rb_block_proc();
|
371
|
-
#endif
|
372
371
|
arg = proc;
|
373
372
|
ext_module = Qnil;
|
374
373
|
break;
|
@@ -387,14 +386,14 @@ static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
|
387
386
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
388
387
|
}
|
389
388
|
|
390
|
-
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);
|
391
390
|
|
392
391
|
return Qnil;
|
393
392
|
}
|
394
393
|
|
395
394
|
static VALUE Unpacker_full_unpack(VALUE self)
|
396
395
|
{
|
397
|
-
|
396
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
398
397
|
|
399
398
|
int r = msgpack_unpacker_read(uk, 0);
|
400
399
|
if(r < 0) {
|
@@ -437,10 +436,15 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
437
436
|
|
438
437
|
eUnknownExtTypeError = rb_define_class_under(mMessagePack, "UnknownExtTypeError", eUnpackError);
|
439
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
|
+
|
440
443
|
rb_define_alloc_func(cMessagePack_Unpacker, MessagePack_Unpacker_alloc);
|
441
444
|
|
442
445
|
rb_define_method(cMessagePack_Unpacker, "initialize", MessagePack_Unpacker_initialize, -1);
|
443
446
|
rb_define_method(cMessagePack_Unpacker, "symbolize_keys?", Unpacker_symbolized_keys_p, 0);
|
447
|
+
rb_define_method(cMessagePack_Unpacker, "freeze?", Unpacker_freeze_p, 0);
|
444
448
|
rb_define_method(cMessagePack_Unpacker, "allow_unknown_ext?", Unpacker_allow_unknown_ext_p, 0);
|
445
449
|
rb_define_method(cMessagePack_Unpacker, "buffer", Unpacker_buffer, 0);
|
446
450
|
rb_define_method(cMessagePack_Unpacker, "read", Unpacker_read, 0);
|
@@ -449,7 +453,6 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
449
453
|
rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
|
450
454
|
rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
|
451
455
|
rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
|
452
|
-
//rb_define_method(cMessagePack_Unpacker, "peek_next_type", Unpacker_peek_next_type, 0); // TODO
|
453
456
|
rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1);
|
454
457
|
rb_define_method(cMessagePack_Unpacker, "feed_reference", Unpacker_feed_reference, 1);
|
455
458
|
rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
|
@@ -467,4 +470,3 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
467
470
|
|
468
471
|
rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
|
469
472
|
}
|
470
|
-
|
@@ -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
|