msgpack 1.7.1 → 1.8.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/ChangeLog +22 -0
- data/README.md +21 -12
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +5 -9
- data/ext/java/org/msgpack/jruby/Factory.java +7 -50
- data/ext/java/org/msgpack/jruby/Packer.java +3 -20
- data/ext/java/org/msgpack/jruby/Unpacker.java +8 -24
- data/ext/msgpack/buffer.c +12 -9
- data/ext/msgpack/buffer.h +134 -28
- data/ext/msgpack/buffer_class.c +72 -1
- data/ext/msgpack/buffer_class.h +1 -0
- data/ext/msgpack/extconf.rb +6 -5
- data/ext/msgpack/factory_class.c +23 -60
- data/ext/msgpack/packer.c +12 -14
- data/ext/msgpack/packer.h +24 -21
- data/ext/msgpack/packer_class.c +6 -36
- data/ext/msgpack/packer_ext_registry.c +31 -28
- data/ext/msgpack/packer_ext_registry.h +10 -14
- data/ext/msgpack/unpacker.c +196 -90
- data/ext/msgpack/unpacker.h +18 -8
- data/ext/msgpack/unpacker_class.c +32 -47
- data/ext/msgpack/unpacker_ext_registry.c +4 -16
- data/ext/msgpack/unpacker_ext_registry.h +3 -7
- data/lib/msgpack/factory.rb +49 -10
- data/lib/msgpack/packer.rb +6 -1
- data/lib/msgpack/unpacker.rb +10 -1
- data/lib/msgpack/version.rb +1 -1
- data/msgpack.gemspec +2 -0
- metadata +5 -7
data/ext/msgpack/unpacker.c
CHANGED
@@ -20,11 +20,49 @@
|
|
20
20
|
#include "rmem.h"
|
21
21
|
#include "extension_value_class.h"
|
22
22
|
#include <assert.h>
|
23
|
+
#include <limits.h>
|
24
|
+
|
25
|
+
#if !defined(HAVE_RB_PROC_CALL_WITH_BLOCK)
|
26
|
+
#define rb_proc_call_with_block(recv, argc, argv, block) rb_funcallv(recv, rb_intern("call"), argc, argv)
|
27
|
+
#endif
|
28
|
+
|
29
|
+
#ifndef HAVE_RB_GC_MARK_LOCATIONS
|
30
|
+
// For TruffleRuby
|
31
|
+
void rb_gc_mark_locations(const VALUE *start, const VALUE *end)
|
32
|
+
{
|
33
|
+
VALUE *value = start;
|
34
|
+
|
35
|
+
while (value < end) {
|
36
|
+
rb_gc_mark(*value);
|
37
|
+
value++;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
#endif
|
41
|
+
|
42
|
+
struct protected_proc_call_args {
|
43
|
+
VALUE proc;
|
44
|
+
int argc;
|
45
|
+
VALUE *argv;
|
46
|
+
};
|
47
|
+
|
48
|
+
static VALUE protected_proc_call_safe(VALUE _args) {
|
49
|
+
struct protected_proc_call_args *args = (struct protected_proc_call_args *)_args;
|
50
|
+
|
51
|
+
return rb_proc_call_with_block(args->proc, args->argc, args->argv, Qnil);
|
52
|
+
}
|
53
|
+
|
54
|
+
static VALUE protected_proc_call(VALUE proc, int argc, VALUE *argv, int *raised) {
|
55
|
+
struct protected_proc_call_args args = {
|
56
|
+
.proc = proc,
|
57
|
+
.argc = argc,
|
58
|
+
.argv = argv,
|
59
|
+
};
|
60
|
+
return rb_protect(protected_proc_call_safe, (VALUE)&args, raised);
|
61
|
+
}
|
23
62
|
|
24
63
|
static int RAW_TYPE_STRING = 256;
|
25
64
|
static int RAW_TYPE_BINARY = 257;
|
26
|
-
|
27
|
-
static ID s_call;
|
65
|
+
static int16_t INITIAL_BUFFER_CAPACITY_MAX = SHRT_MAX;
|
28
66
|
|
29
67
|
static msgpack_rmem_t s_stack_rmem;
|
30
68
|
|
@@ -35,13 +73,16 @@ static inline VALUE rb_hash_new_capa(long capa)
|
|
35
73
|
}
|
36
74
|
#endif
|
37
75
|
|
76
|
+
static inline int16_t initial_buffer_size(long size)
|
77
|
+
{
|
78
|
+
return (size > INITIAL_BUFFER_CAPACITY_MAX) ? INITIAL_BUFFER_CAPACITY_MAX : size;
|
79
|
+
}
|
80
|
+
|
38
81
|
void msgpack_unpacker_static_init(void)
|
39
82
|
{
|
40
83
|
assert(sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE);
|
41
84
|
|
42
85
|
msgpack_rmem_init(&s_stack_rmem);
|
43
|
-
|
44
|
-
s_call = rb_intern("call");
|
45
86
|
}
|
46
87
|
|
47
88
|
void msgpack_unpacker_static_destroy(void)
|
@@ -51,14 +92,29 @@ void msgpack_unpacker_static_destroy(void)
|
|
51
92
|
|
52
93
|
#define HEAD_BYTE_REQUIRED 0xc1
|
53
94
|
|
54
|
-
static inline msgpack_unpacker_stack_t*
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
95
|
+
static inline bool _msgpack_unpacker_stack_init(msgpack_unpacker_stack_t *stack) {
|
96
|
+
if (!stack->data) {
|
97
|
+
stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
98
|
+
stack->data = msgpack_rmem_alloc(&s_stack_rmem);
|
99
|
+
stack->depth = 0;
|
100
|
+
return true;
|
101
|
+
}
|
102
|
+
return false;
|
60
103
|
}
|
61
104
|
|
105
|
+
static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
|
106
|
+
if (stack->data) {
|
107
|
+
if (!msgpack_rmem_free(&s_stack_rmem, stack->data)) {
|
108
|
+
rb_bug("Failed to free an rmem pointer, memory leak?");
|
109
|
+
}
|
110
|
+
stack->data = NULL;
|
111
|
+
stack->depth = 0;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
#define STACK_INIT(uk) bool stack_allocated = _msgpack_unpacker_stack_init(&uk->stack);
|
116
|
+
#define STACK_FREE(uk) if (stack_allocated) { _msgpack_unpacker_free_stack(&uk->stack); }
|
117
|
+
|
62
118
|
void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
63
119
|
{
|
64
120
|
msgpack_buffer_init(UNPACKER_BUFFER_(uk));
|
@@ -67,41 +123,38 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
|
67
123
|
|
68
124
|
uk->last_object = Qnil;
|
69
125
|
uk->reading_raw = Qnil;
|
70
|
-
|
71
|
-
uk->stack = _msgpack_unpacker_new_stack();
|
72
|
-
}
|
73
|
-
|
74
|
-
static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
|
75
|
-
if (!msgpack_rmem_free(&s_stack_rmem, stack->data)) {
|
76
|
-
rb_bug("Failed to free an rmem pointer, memory leak?");
|
77
|
-
}
|
78
|
-
xfree(stack);
|
79
126
|
}
|
80
127
|
|
81
128
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
|
82
129
|
{
|
83
|
-
_msgpack_unpacker_free_stack(uk->stack);
|
130
|
+
_msgpack_unpacker_free_stack(&uk->stack);
|
84
131
|
msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
|
85
132
|
}
|
86
133
|
|
87
134
|
void msgpack_unpacker_mark_stack(msgpack_unpacker_stack_t* stack)
|
88
135
|
{
|
89
|
-
|
136
|
+
if (stack->data) {
|
90
137
|
msgpack_unpacker_stack_entry_t* s = stack->data;
|
91
138
|
msgpack_unpacker_stack_entry_t* send = stack->data + stack->depth;
|
92
139
|
for(; s < send; s++) {
|
93
140
|
rb_gc_mark(s->object);
|
94
141
|
rb_gc_mark(s->key);
|
95
142
|
}
|
96
|
-
stack = stack->parent;
|
97
143
|
}
|
98
144
|
}
|
99
145
|
|
146
|
+
void msgpack_unpacker_mark_key_cache(msgpack_key_cache_t *cache)
|
147
|
+
{
|
148
|
+
const VALUE *entries = &cache->entries[0];
|
149
|
+
rb_gc_mark_locations(entries, entries + cache->length);
|
150
|
+
}
|
151
|
+
|
100
152
|
void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
|
101
153
|
{
|
102
154
|
rb_gc_mark(uk->last_object);
|
103
155
|
rb_gc_mark(uk->reading_raw);
|
104
|
-
msgpack_unpacker_mark_stack(uk->stack);
|
156
|
+
msgpack_unpacker_mark_stack(&uk->stack);
|
157
|
+
msgpack_unpacker_mark_key_cache(&uk->key_cache);
|
105
158
|
/* See MessagePack_Buffer_wrap */
|
106
159
|
/* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
|
107
160
|
rb_gc_mark(uk->buffer_ref);
|
@@ -114,8 +167,8 @@ void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
|
|
114
167
|
|
115
168
|
uk->head_byte = HEAD_BYTE_REQUIRED;
|
116
169
|
|
117
|
-
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack
|
118
|
-
uk->stack
|
170
|
+
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack.depth);*/
|
171
|
+
uk->stack.depth = 0;
|
119
172
|
uk->last_object = Qnil;
|
120
173
|
uk->reading_raw = Qnil;
|
121
174
|
uk->reading_raw_remaining = 0;
|
@@ -178,7 +231,13 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
178
231
|
|
179
232
|
if(proc != Qnil) {
|
180
233
|
VALUE obj;
|
181
|
-
|
234
|
+
VALUE arg = (str == Qnil ? rb_str_buf_new(0) : str);
|
235
|
+
int raised;
|
236
|
+
obj = protected_proc_call(proc, 1, &arg, &raised);
|
237
|
+
if (raised) {
|
238
|
+
uk->last_object = rb_errinfo();
|
239
|
+
return PRIMITIVE_RECURSIVE_RAISED;
|
240
|
+
}
|
182
241
|
return object_complete(uk, obj);
|
183
242
|
}
|
184
243
|
|
@@ -193,35 +252,35 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
193
252
|
/* stack funcs */
|
194
253
|
static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
|
195
254
|
{
|
196
|
-
return &uk->stack
|
255
|
+
return &uk->stack.data[uk->stack.depth-1];
|
197
256
|
}
|
198
257
|
|
199
258
|
static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
|
200
259
|
{
|
201
260
|
reset_head_byte(uk);
|
202
261
|
|
203
|
-
if(uk->stack
|
262
|
+
if(uk->stack.capacity - uk->stack.depth <= 0) {
|
204
263
|
return PRIMITIVE_STACK_TOO_DEEP;
|
205
264
|
}
|
206
265
|
|
207
|
-
msgpack_unpacker_stack_entry_t* next = &uk->stack
|
266
|
+
msgpack_unpacker_stack_entry_t* next = &uk->stack.data[uk->stack.depth];
|
208
267
|
next->count = count;
|
209
268
|
next->type = type;
|
210
269
|
next->object = object;
|
211
270
|
next->key = Qnil;
|
212
271
|
|
213
|
-
uk->stack
|
272
|
+
uk->stack.depth++;
|
214
273
|
return PRIMITIVE_CONTAINER_START;
|
215
274
|
}
|
216
275
|
|
217
|
-
static inline
|
276
|
+
static inline size_t msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
|
218
277
|
{
|
219
|
-
return --uk->stack
|
278
|
+
return --uk->stack.depth;
|
220
279
|
}
|
221
280
|
|
222
281
|
static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
223
282
|
{
|
224
|
-
return uk->stack
|
283
|
+
return uk->stack.depth == 0;
|
225
284
|
}
|
226
285
|
|
227
286
|
#ifdef USE_CASE_RANGE
|
@@ -240,16 +299,29 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
|
240
299
|
|
241
300
|
#endif
|
242
301
|
|
302
|
+
union msgpack_buffer_cast_block_t {
|
303
|
+
char buffer[8];
|
304
|
+
uint8_t u8;
|
305
|
+
uint16_t u16;
|
306
|
+
uint32_t u32;
|
307
|
+
uint64_t u64;
|
308
|
+
int8_t i8;
|
309
|
+
int16_t i16;
|
310
|
+
int32_t i32;
|
311
|
+
int64_t i64;
|
312
|
+
float f;
|
313
|
+
double d;
|
314
|
+
};
|
243
315
|
|
244
316
|
#define READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, n) \
|
245
|
-
union msgpack_buffer_cast_block_t
|
246
|
-
if(
|
317
|
+
union msgpack_buffer_cast_block_t cb; \
|
318
|
+
if (!msgpack_buffer_read_all(UNPACKER_BUFFER_(uk), (char *)&cb.buffer, n)) { \
|
247
319
|
return PRIMITIVE_EOF; \
|
248
320
|
}
|
249
321
|
|
250
322
|
static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
|
251
323
|
{
|
252
|
-
if(uk->stack
|
324
|
+
if(uk->stack.depth > 0) {
|
253
325
|
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
254
326
|
if(top->type == STACK_TYPE_MAP_KEY) {
|
255
327
|
return true;
|
@@ -304,14 +376,15 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
304
376
|
reset_head_byte(uk);
|
305
377
|
uk->reading_raw_remaining = 0;
|
306
378
|
|
307
|
-
|
308
|
-
|
309
|
-
uk->
|
379
|
+
_msgpack_unpacker_stack_push(uk, STACK_TYPE_RECURSIVE, 1, Qnil);
|
380
|
+
int raised;
|
381
|
+
obj = protected_proc_call(proc, 1, &uk->self, &raised);
|
382
|
+
msgpack_unpacker_stack_pop(uk);
|
310
383
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
384
|
+
if (raised) {
|
385
|
+
uk->last_object = rb_errinfo();
|
386
|
+
return PRIMITIVE_RECURSIVE_RAISED;
|
387
|
+
}
|
315
388
|
|
316
389
|
return object_complete(uk, obj);
|
317
390
|
}
|
@@ -321,15 +394,32 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
321
394
|
size_t length = uk->reading_raw_remaining;
|
322
395
|
if(length <= msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk))) {
|
323
396
|
int ret;
|
324
|
-
if ((uk->optimized_symbol_ext_type && uk->symbol_ext_type == raw_type)
|
397
|
+
if ((uk->optimized_symbol_ext_type && uk->symbol_ext_type == raw_type)) {
|
325
398
|
VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, raw_type != RAW_TYPE_BINARY);
|
326
399
|
ret = object_complete_symbol(uk, symbol);
|
400
|
+
} else if (is_reading_map_key(uk) && raw_type == RAW_TYPE_STRING) {
|
401
|
+
/* don't use zerocopy for hash keys but get a frozen string directly
|
402
|
+
* because rb_hash_aset freezes keys and it causes copying */
|
403
|
+
VALUE key;
|
404
|
+
if (uk->symbolize_keys) {
|
405
|
+
if (uk->use_key_cache) {
|
406
|
+
key = msgpack_buffer_read_top_as_interned_symbol(UNPACKER_BUFFER_(uk), &uk->key_cache, length);
|
407
|
+
} else {
|
408
|
+
key = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, true);
|
409
|
+
}
|
410
|
+
ret = object_complete_symbol(uk, key);
|
411
|
+
} else {
|
412
|
+
if (uk->use_key_cache) {
|
413
|
+
key = msgpack_buffer_read_top_as_interned_string(UNPACKER_BUFFER_(uk), &uk->key_cache, length);
|
414
|
+
} else {
|
415
|
+
key = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, true, true);
|
416
|
+
}
|
417
|
+
|
418
|
+
ret = object_complete(uk, key);
|
419
|
+
}
|
327
420
|
} else {
|
328
421
|
bool will_freeze = uk->freeze;
|
329
422
|
if(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY) {
|
330
|
-
/* don't use zerocopy for hash keys but get a frozen string directly
|
331
|
-
* because rb_hash_aset freezes keys and it causes copying */
|
332
|
-
will_freeze = will_freeze || is_reading_map_key(uk);
|
333
423
|
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
|
334
424
|
ret = object_complete(uk, string);
|
335
425
|
} else {
|
@@ -374,14 +464,14 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
374
464
|
if(count == 0) {
|
375
465
|
return object_complete(uk, rb_ary_new());
|
376
466
|
}
|
377
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
|
467
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
|
378
468
|
|
379
469
|
SWITCH_RANGE(b, 0x80, 0x8f) // FixMap
|
380
470
|
int count = b & 0x0f;
|
381
471
|
if(count == 0) {
|
382
472
|
return object_complete(uk, rb_hash_new());
|
383
473
|
}
|
384
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
474
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
|
385
475
|
|
386
476
|
SWITCH_RANGE(b, 0xc0, 0xdf) // Variable
|
387
477
|
switch(b) {
|
@@ -399,8 +489,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
399
489
|
case 0xc7: // ext 8
|
400
490
|
{
|
401
491
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
402
|
-
uint8_t length = cb
|
403
|
-
int ext_type = (signed char) cb
|
492
|
+
uint8_t length = cb.u8;
|
493
|
+
int ext_type = (signed char) cb.buffer[1];
|
404
494
|
if(length == 0) {
|
405
495
|
return object_complete_ext(uk, ext_type, Qnil);
|
406
496
|
}
|
@@ -411,8 +501,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
411
501
|
case 0xc8: // ext 16
|
412
502
|
{
|
413
503
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 3);
|
414
|
-
uint16_t length = _msgpack_be16(cb
|
415
|
-
int ext_type = (signed char) cb
|
504
|
+
uint16_t length = _msgpack_be16(cb.u16);
|
505
|
+
int ext_type = (signed char) cb.buffer[2];
|
416
506
|
if(length == 0) {
|
417
507
|
return object_complete_ext(uk, ext_type, Qnil);
|
418
508
|
}
|
@@ -423,8 +513,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
423
513
|
case 0xc9: // ext 32
|
424
514
|
{
|
425
515
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 5);
|
426
|
-
uint32_t length = _msgpack_be32(cb
|
427
|
-
int ext_type = (signed char) cb
|
516
|
+
uint32_t length = _msgpack_be32(cb.u32);
|
517
|
+
int ext_type = (signed char) cb.buffer[4];
|
428
518
|
if(length == 0) {
|
429
519
|
return object_complete_ext(uk, ext_type, Qnil);
|
430
520
|
}
|
@@ -435,77 +525,77 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
435
525
|
case 0xca: // float
|
436
526
|
{
|
437
527
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
438
|
-
cb
|
439
|
-
return object_complete(uk, rb_float_new(cb
|
528
|
+
cb.u32 = _msgpack_be_float(cb.u32);
|
529
|
+
return object_complete(uk, rb_float_new(cb.f));
|
440
530
|
}
|
441
531
|
|
442
532
|
case 0xcb: // double
|
443
533
|
{
|
444
534
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
|
445
|
-
cb
|
446
|
-
return object_complete(uk, rb_float_new(cb
|
535
|
+
cb.u64 = _msgpack_be_double(cb.u64);
|
536
|
+
return object_complete(uk, rb_float_new(cb.d));
|
447
537
|
}
|
448
538
|
|
449
539
|
case 0xcc: // unsigned int 8
|
450
540
|
{
|
451
541
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
452
|
-
uint8_t u8 = cb
|
542
|
+
uint8_t u8 = cb.u8;
|
453
543
|
return object_complete(uk, INT2NUM((int)u8));
|
454
544
|
}
|
455
545
|
|
456
546
|
case 0xcd: // unsigned int 16
|
457
547
|
{
|
458
548
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
459
|
-
uint16_t u16 = _msgpack_be16(cb
|
549
|
+
uint16_t u16 = _msgpack_be16(cb.u16);
|
460
550
|
return object_complete(uk, INT2NUM((int)u16));
|
461
551
|
}
|
462
552
|
|
463
553
|
case 0xce: // unsigned int 32
|
464
554
|
{
|
465
555
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
466
|
-
uint32_t u32 = _msgpack_be32(cb
|
556
|
+
uint32_t u32 = _msgpack_be32(cb.u32);
|
467
557
|
return object_complete(uk, ULONG2NUM(u32)); // long at least 32 bits
|
468
558
|
}
|
469
559
|
|
470
560
|
case 0xcf: // unsigned int 64
|
471
561
|
{
|
472
562
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
|
473
|
-
uint64_t u64 = _msgpack_be64(cb
|
563
|
+
uint64_t u64 = _msgpack_be64(cb.u64);
|
474
564
|
return object_complete(uk, rb_ull2inum(u64));
|
475
565
|
}
|
476
566
|
|
477
567
|
case 0xd0: // signed int 8
|
478
568
|
{
|
479
569
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
480
|
-
int8_t i8 = cb
|
570
|
+
int8_t i8 = cb.i8;
|
481
571
|
return object_complete(uk, INT2NUM((int)i8));
|
482
572
|
}
|
483
573
|
|
484
574
|
case 0xd1: // signed int 16
|
485
575
|
{
|
486
576
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
487
|
-
int16_t i16 = _msgpack_be16(cb
|
577
|
+
int16_t i16 = _msgpack_be16(cb.i16);
|
488
578
|
return object_complete(uk, INT2NUM((int)i16));
|
489
579
|
}
|
490
580
|
|
491
581
|
case 0xd2: // signed int 32
|
492
582
|
{
|
493
583
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
494
|
-
int32_t i32 = _msgpack_be32(cb
|
584
|
+
int32_t i32 = _msgpack_be32(cb.i32);
|
495
585
|
return object_complete(uk, LONG2NUM(i32)); // long at least 32 bits
|
496
586
|
}
|
497
587
|
|
498
588
|
case 0xd3: // signed int 64
|
499
589
|
{
|
500
590
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
|
501
|
-
int64_t i64 = _msgpack_be64(cb
|
591
|
+
int64_t i64 = _msgpack_be64(cb.i64);
|
502
592
|
return object_complete(uk, rb_ll2inum(i64));
|
503
593
|
}
|
504
594
|
|
505
595
|
case 0xd4: // fixext 1
|
506
596
|
{
|
507
597
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
508
|
-
int ext_type = cb
|
598
|
+
int ext_type = cb.i8;
|
509
599
|
uk->reading_raw_remaining = 1;
|
510
600
|
return read_raw_body_begin(uk, ext_type);
|
511
601
|
}
|
@@ -513,7 +603,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
513
603
|
case 0xd5: // fixext 2
|
514
604
|
{
|
515
605
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
516
|
-
int ext_type = cb
|
606
|
+
int ext_type = cb.i8;
|
517
607
|
uk->reading_raw_remaining = 2;
|
518
608
|
return read_raw_body_begin(uk, ext_type);
|
519
609
|
}
|
@@ -521,7 +611,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
521
611
|
case 0xd6: // fixext 4
|
522
612
|
{
|
523
613
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
524
|
-
int ext_type = cb
|
614
|
+
int ext_type = cb.i8;
|
525
615
|
uk->reading_raw_remaining = 4;
|
526
616
|
return read_raw_body_begin(uk, ext_type);
|
527
617
|
}
|
@@ -529,7 +619,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
529
619
|
case 0xd7: // fixext 8
|
530
620
|
{
|
531
621
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
532
|
-
int ext_type = cb
|
622
|
+
int ext_type = cb.i8;
|
533
623
|
uk->reading_raw_remaining = 8;
|
534
624
|
return read_raw_body_begin(uk, ext_type);
|
535
625
|
}
|
@@ -537,7 +627,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
537
627
|
case 0xd8: // fixext 16
|
538
628
|
{
|
539
629
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
540
|
-
int ext_type = cb
|
630
|
+
int ext_type = cb.i8;
|
541
631
|
uk->reading_raw_remaining = 16;
|
542
632
|
return read_raw_body_begin(uk, ext_type);
|
543
633
|
}
|
@@ -546,7 +636,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
546
636
|
case 0xd9: // raw 8 / str 8
|
547
637
|
{
|
548
638
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
549
|
-
uint8_t count = cb
|
639
|
+
uint8_t count = cb.u8;
|
550
640
|
/* read_raw_body_begin sets uk->reading_raw */
|
551
641
|
uk->reading_raw_remaining = count;
|
552
642
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -555,7 +645,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
555
645
|
case 0xda: // raw 16 / str 16
|
556
646
|
{
|
557
647
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
558
|
-
uint16_t count = _msgpack_be16(cb
|
648
|
+
uint16_t count = _msgpack_be16(cb.u16);
|
559
649
|
/* read_raw_body_begin sets uk->reading_raw */
|
560
650
|
uk->reading_raw_remaining = count;
|
561
651
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -564,7 +654,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
564
654
|
case 0xdb: // raw 32 / str 32
|
565
655
|
{
|
566
656
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
567
|
-
uint32_t count = _msgpack_be32(cb
|
657
|
+
uint32_t count = _msgpack_be32(cb.u32);
|
568
658
|
/* read_raw_body_begin sets uk->reading_raw */
|
569
659
|
uk->reading_raw_remaining = count;
|
570
660
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -573,7 +663,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
573
663
|
case 0xc4: // bin 8
|
574
664
|
{
|
575
665
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
576
|
-
uint8_t count = cb
|
666
|
+
uint8_t count = cb.u8;
|
577
667
|
/* read_raw_body_begin sets uk->reading_raw */
|
578
668
|
uk->reading_raw_remaining = count;
|
579
669
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -582,7 +672,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
582
672
|
case 0xc5: // bin 16
|
583
673
|
{
|
584
674
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
585
|
-
uint16_t count = _msgpack_be16(cb
|
675
|
+
uint16_t count = _msgpack_be16(cb.u16);
|
586
676
|
/* read_raw_body_begin sets uk->reading_raw */
|
587
677
|
uk->reading_raw_remaining = count;
|
588
678
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -591,7 +681,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
591
681
|
case 0xc6: // bin 32
|
592
682
|
{
|
593
683
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
594
|
-
uint32_t count = _msgpack_be32(cb
|
684
|
+
uint32_t count = _msgpack_be32(cb.u32);
|
595
685
|
/* read_raw_body_begin sets uk->reading_raw */
|
596
686
|
uk->reading_raw_remaining = count;
|
597
687
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -600,41 +690,41 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
600
690
|
case 0xdc: // array 16
|
601
691
|
{
|
602
692
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
603
|
-
uint16_t count = _msgpack_be16(cb
|
693
|
+
uint16_t count = _msgpack_be16(cb.u16);
|
604
694
|
if(count == 0) {
|
605
695
|
return object_complete(uk, rb_ary_new());
|
606
696
|
}
|
607
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
|
697
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
|
608
698
|
}
|
609
699
|
|
610
700
|
case 0xdd: // array 32
|
611
701
|
{
|
612
702
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
613
|
-
uint32_t count = _msgpack_be32(cb
|
703
|
+
uint32_t count = _msgpack_be32(cb.u32);
|
614
704
|
if(count == 0) {
|
615
705
|
return object_complete(uk, rb_ary_new());
|
616
706
|
}
|
617
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
|
707
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
|
618
708
|
}
|
619
709
|
|
620
710
|
case 0xde: // map 16
|
621
711
|
{
|
622
712
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
623
|
-
uint16_t count = _msgpack_be16(cb
|
713
|
+
uint16_t count = _msgpack_be16(cb.u16);
|
624
714
|
if(count == 0) {
|
625
715
|
return object_complete(uk, rb_hash_new());
|
626
716
|
}
|
627
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
717
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
|
628
718
|
}
|
629
719
|
|
630
720
|
case 0xdf: // map 32
|
631
721
|
{
|
632
722
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
633
|
-
uint32_t count = _msgpack_be32(cb
|
723
|
+
uint32_t count = _msgpack_be32(cb.u32);
|
634
724
|
if(count == 0) {
|
635
725
|
return object_complete(uk, rb_hash_new());
|
636
726
|
}
|
637
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
727
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
|
638
728
|
}
|
639
729
|
|
640
730
|
default:
|
@@ -660,12 +750,12 @@ int msgpack_unpacker_read_array_header(msgpack_unpacker_t* uk, uint32_t* result_
|
|
660
750
|
} else if(b == 0xdc) {
|
661
751
|
/* array 16 */
|
662
752
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
663
|
-
*result_size = _msgpack_be16(cb
|
753
|
+
*result_size = _msgpack_be16(cb.u16);
|
664
754
|
|
665
755
|
} else if(b == 0xdd) {
|
666
756
|
/* array 32 */
|
667
757
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
668
|
-
*result_size = _msgpack_be32(cb
|
758
|
+
*result_size = _msgpack_be32(cb.u32);
|
669
759
|
|
670
760
|
} else {
|
671
761
|
return PRIMITIVE_UNEXPECTED_TYPE;
|
@@ -688,12 +778,12 @@ int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint32_t* result_si
|
|
688
778
|
} else if(b == 0xde) {
|
689
779
|
/* map 16 */
|
690
780
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
691
|
-
*result_size = _msgpack_be16(cb
|
781
|
+
*result_size = _msgpack_be16(cb.u16);
|
692
782
|
|
693
783
|
} else if(b == 0xdf) {
|
694
784
|
/* map 32 */
|
695
785
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
696
|
-
*result_size = _msgpack_be32(cb
|
786
|
+
*result_size = _msgpack_be32(cb.u32);
|
697
787
|
|
698
788
|
} else {
|
699
789
|
return PRIMITIVE_UNEXPECTED_TYPE;
|
@@ -705,9 +795,15 @@ int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint32_t* result_si
|
|
705
795
|
|
706
796
|
int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
707
797
|
{
|
798
|
+
STACK_INIT(uk);
|
799
|
+
|
708
800
|
while(true) {
|
709
801
|
int r = read_primitive(uk);
|
710
802
|
if(r < 0) {
|
803
|
+
if (r != PRIMITIVE_EOF) {
|
804
|
+
// We keep the stack on EOF as the parsing may be resumed.
|
805
|
+
STACK_FREE(uk);
|
806
|
+
}
|
711
807
|
return r;
|
712
808
|
}
|
713
809
|
if(r == PRIMITIVE_CONTAINER_START) {
|
@@ -716,6 +812,7 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
716
812
|
/* PRIMITIVE_OBJECT_COMPLETE */
|
717
813
|
|
718
814
|
if(msgpack_unpacker_stack_is_empty(uk)) {
|
815
|
+
STACK_FREE(uk);
|
719
816
|
return PRIMITIVE_OBJECT_COMPLETE;
|
720
817
|
}
|
721
818
|
|
@@ -739,12 +836,16 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
739
836
|
}
|
740
837
|
top->type = STACK_TYPE_MAP_KEY;
|
741
838
|
break;
|
839
|
+
case STACK_TYPE_RECURSIVE:
|
840
|
+
STACK_FREE(uk);
|
841
|
+
return PRIMITIVE_OBJECT_COMPLETE;
|
742
842
|
}
|
743
843
|
size_t count = --top->count;
|
744
844
|
|
745
845
|
if(count == 0) {
|
746
846
|
object_complete(uk, top->object);
|
747
847
|
if(msgpack_unpacker_stack_pop(uk) <= target_stack_depth) {
|
848
|
+
STACK_FREE(uk);
|
748
849
|
return PRIMITIVE_OBJECT_COMPLETE;
|
749
850
|
}
|
750
851
|
goto container_completed;
|
@@ -755,9 +856,12 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
755
856
|
|
756
857
|
int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
757
858
|
{
|
859
|
+
STACK_INIT(uk);
|
860
|
+
|
758
861
|
while(true) {
|
759
862
|
int r = read_primitive(uk);
|
760
863
|
if(r < 0) {
|
864
|
+
STACK_FREE(uk);
|
761
865
|
return r;
|
762
866
|
}
|
763
867
|
if(r == PRIMITIVE_CONTAINER_START) {
|
@@ -766,6 +870,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
766
870
|
/* PRIMITIVE_OBJECT_COMPLETE */
|
767
871
|
|
768
872
|
if(msgpack_unpacker_stack_is_empty(uk)) {
|
873
|
+
STACK_FREE(uk);
|
769
874
|
return PRIMITIVE_OBJECT_COMPLETE;
|
770
875
|
}
|
771
876
|
|
@@ -781,6 +886,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
781
886
|
if(count == 0) {
|
782
887
|
object_complete(uk, Qnil);
|
783
888
|
if(msgpack_unpacker_stack_pop(uk) <= target_stack_depth) {
|
889
|
+
STACK_FREE(uk);
|
784
890
|
return PRIMITIVE_OBJECT_COMPLETE;
|
785
891
|
}
|
786
892
|
goto container_completed;
|