msgpack 1.7.2 → 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 +17 -0
- data/README.md +21 -12
- data/ext/msgpack/buffer.c +5 -4
- data/ext/msgpack/buffer.h +131 -27
- data/ext/msgpack/extconf.rb +5 -3
- data/ext/msgpack/packer.h +24 -17
- data/ext/msgpack/unpacker.c +191 -86
- data/ext/msgpack/unpacker.h +18 -8
- data/ext/msgpack/unpacker_class.c +27 -17
- data/lib/msgpack/version.rb +1 -1
- data/msgpack.gemspec +2 -0
- metadata +5 -7
data/ext/msgpack/unpacker.c
CHANGED
@@ -20,13 +20,49 @@
|
|
20
20
|
#include "rmem.h"
|
21
21
|
#include "extension_value_class.h"
|
22
22
|
#include <assert.h>
|
23
|
+
#include <limits.h>
|
23
24
|
|
24
25
|
#if !defined(HAVE_RB_PROC_CALL_WITH_BLOCK)
|
25
26
|
#define rb_proc_call_with_block(recv, argc, argv, block) rb_funcallv(recv, rb_intern("call"), argc, argv)
|
26
27
|
#endif
|
27
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
|
+
}
|
62
|
+
|
28
63
|
static int RAW_TYPE_STRING = 256;
|
29
64
|
static int RAW_TYPE_BINARY = 257;
|
65
|
+
static int16_t INITIAL_BUFFER_CAPACITY_MAX = SHRT_MAX;
|
30
66
|
|
31
67
|
static msgpack_rmem_t s_stack_rmem;
|
32
68
|
|
@@ -37,6 +73,11 @@ static inline VALUE rb_hash_new_capa(long capa)
|
|
37
73
|
}
|
38
74
|
#endif
|
39
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
|
+
|
40
81
|
void msgpack_unpacker_static_init(void)
|
41
82
|
{
|
42
83
|
assert(sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE);
|
@@ -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;
|
103
|
+
}
|
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
|
+
}
|
60
113
|
}
|
61
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;
|
@@ -179,7 +232,12 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
179
232
|
if(proc != Qnil) {
|
180
233
|
VALUE obj;
|
181
234
|
VALUE arg = (str == Qnil ? rb_str_buf_new(0) : str);
|
182
|
-
|
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
|
+
}
|
183
241
|
return object_complete(uk, obj);
|
184
242
|
}
|
185
243
|
|
@@ -194,35 +252,35 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
194
252
|
/* stack funcs */
|
195
253
|
static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
|
196
254
|
{
|
197
|
-
return &uk->stack
|
255
|
+
return &uk->stack.data[uk->stack.depth-1];
|
198
256
|
}
|
199
257
|
|
200
258
|
static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
|
201
259
|
{
|
202
260
|
reset_head_byte(uk);
|
203
261
|
|
204
|
-
if(uk->stack
|
262
|
+
if(uk->stack.capacity - uk->stack.depth <= 0) {
|
205
263
|
return PRIMITIVE_STACK_TOO_DEEP;
|
206
264
|
}
|
207
265
|
|
208
|
-
msgpack_unpacker_stack_entry_t* next = &uk->stack
|
266
|
+
msgpack_unpacker_stack_entry_t* next = &uk->stack.data[uk->stack.depth];
|
209
267
|
next->count = count;
|
210
268
|
next->type = type;
|
211
269
|
next->object = object;
|
212
270
|
next->key = Qnil;
|
213
271
|
|
214
|
-
uk->stack
|
272
|
+
uk->stack.depth++;
|
215
273
|
return PRIMITIVE_CONTAINER_START;
|
216
274
|
}
|
217
275
|
|
218
|
-
static inline
|
276
|
+
static inline size_t msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
|
219
277
|
{
|
220
|
-
return --uk->stack
|
278
|
+
return --uk->stack.depth;
|
221
279
|
}
|
222
280
|
|
223
281
|
static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
224
282
|
{
|
225
|
-
return uk->stack
|
283
|
+
return uk->stack.depth == 0;
|
226
284
|
}
|
227
285
|
|
228
286
|
#ifdef USE_CASE_RANGE
|
@@ -241,16 +299,29 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
|
241
299
|
|
242
300
|
#endif
|
243
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
|
+
};
|
244
315
|
|
245
316
|
#define READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, n) \
|
246
|
-
union msgpack_buffer_cast_block_t
|
247
|
-
if(
|
317
|
+
union msgpack_buffer_cast_block_t cb; \
|
318
|
+
if (!msgpack_buffer_read_all(UNPACKER_BUFFER_(uk), (char *)&cb.buffer, n)) { \
|
248
319
|
return PRIMITIVE_EOF; \
|
249
320
|
}
|
250
321
|
|
251
322
|
static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
|
252
323
|
{
|
253
|
-
if(uk->stack
|
324
|
+
if(uk->stack.depth > 0) {
|
254
325
|
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
255
326
|
if(top->type == STACK_TYPE_MAP_KEY) {
|
256
327
|
return true;
|
@@ -305,14 +376,15 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
305
376
|
reset_head_byte(uk);
|
306
377
|
uk->reading_raw_remaining = 0;
|
307
378
|
|
308
|
-
|
309
|
-
|
310
|
-
uk->
|
311
|
-
|
312
|
-
obj = rb_proc_call_with_block(proc, 1, &uk->self, Qnil);
|
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);
|
313
383
|
|
314
|
-
|
315
|
-
|
384
|
+
if (raised) {
|
385
|
+
uk->last_object = rb_errinfo();
|
386
|
+
return PRIMITIVE_RECURSIVE_RAISED;
|
387
|
+
}
|
316
388
|
|
317
389
|
return object_complete(uk, obj);
|
318
390
|
}
|
@@ -322,15 +394,32 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
322
394
|
size_t length = uk->reading_raw_remaining;
|
323
395
|
if(length <= msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk))) {
|
324
396
|
int ret;
|
325
|
-
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)) {
|
326
398
|
VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, raw_type != RAW_TYPE_BINARY);
|
327
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
|
+
}
|
328
420
|
} else {
|
329
421
|
bool will_freeze = uk->freeze;
|
330
422
|
if(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY) {
|
331
|
-
/* don't use zerocopy for hash keys but get a frozen string directly
|
332
|
-
* because rb_hash_aset freezes keys and it causes copying */
|
333
|
-
will_freeze = will_freeze || is_reading_map_key(uk);
|
334
423
|
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
|
335
424
|
ret = object_complete(uk, string);
|
336
425
|
} else {
|
@@ -375,14 +464,14 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
375
464
|
if(count == 0) {
|
376
465
|
return object_complete(uk, rb_ary_new());
|
377
466
|
}
|
378
|
-
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)));
|
379
468
|
|
380
469
|
SWITCH_RANGE(b, 0x80, 0x8f) // FixMap
|
381
470
|
int count = b & 0x0f;
|
382
471
|
if(count == 0) {
|
383
472
|
return object_complete(uk, rb_hash_new());
|
384
473
|
}
|
385
|
-
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)));
|
386
475
|
|
387
476
|
SWITCH_RANGE(b, 0xc0, 0xdf) // Variable
|
388
477
|
switch(b) {
|
@@ -400,8 +489,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
400
489
|
case 0xc7: // ext 8
|
401
490
|
{
|
402
491
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
403
|
-
uint8_t length = cb
|
404
|
-
int ext_type = (signed char) cb
|
492
|
+
uint8_t length = cb.u8;
|
493
|
+
int ext_type = (signed char) cb.buffer[1];
|
405
494
|
if(length == 0) {
|
406
495
|
return object_complete_ext(uk, ext_type, Qnil);
|
407
496
|
}
|
@@ -412,8 +501,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
412
501
|
case 0xc8: // ext 16
|
413
502
|
{
|
414
503
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 3);
|
415
|
-
uint16_t length = _msgpack_be16(cb
|
416
|
-
int ext_type = (signed char) cb
|
504
|
+
uint16_t length = _msgpack_be16(cb.u16);
|
505
|
+
int ext_type = (signed char) cb.buffer[2];
|
417
506
|
if(length == 0) {
|
418
507
|
return object_complete_ext(uk, ext_type, Qnil);
|
419
508
|
}
|
@@ -424,8 +513,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
424
513
|
case 0xc9: // ext 32
|
425
514
|
{
|
426
515
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 5);
|
427
|
-
uint32_t length = _msgpack_be32(cb
|
428
|
-
int ext_type = (signed char) cb
|
516
|
+
uint32_t length = _msgpack_be32(cb.u32);
|
517
|
+
int ext_type = (signed char) cb.buffer[4];
|
429
518
|
if(length == 0) {
|
430
519
|
return object_complete_ext(uk, ext_type, Qnil);
|
431
520
|
}
|
@@ -436,77 +525,77 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
436
525
|
case 0xca: // float
|
437
526
|
{
|
438
527
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
439
|
-
cb
|
440
|
-
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));
|
441
530
|
}
|
442
531
|
|
443
532
|
case 0xcb: // double
|
444
533
|
{
|
445
534
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
|
446
|
-
cb
|
447
|
-
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));
|
448
537
|
}
|
449
538
|
|
450
539
|
case 0xcc: // unsigned int 8
|
451
540
|
{
|
452
541
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
453
|
-
uint8_t u8 = cb
|
542
|
+
uint8_t u8 = cb.u8;
|
454
543
|
return object_complete(uk, INT2NUM((int)u8));
|
455
544
|
}
|
456
545
|
|
457
546
|
case 0xcd: // unsigned int 16
|
458
547
|
{
|
459
548
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
460
|
-
uint16_t u16 = _msgpack_be16(cb
|
549
|
+
uint16_t u16 = _msgpack_be16(cb.u16);
|
461
550
|
return object_complete(uk, INT2NUM((int)u16));
|
462
551
|
}
|
463
552
|
|
464
553
|
case 0xce: // unsigned int 32
|
465
554
|
{
|
466
555
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
467
|
-
uint32_t u32 = _msgpack_be32(cb
|
556
|
+
uint32_t u32 = _msgpack_be32(cb.u32);
|
468
557
|
return object_complete(uk, ULONG2NUM(u32)); // long at least 32 bits
|
469
558
|
}
|
470
559
|
|
471
560
|
case 0xcf: // unsigned int 64
|
472
561
|
{
|
473
562
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
|
474
|
-
uint64_t u64 = _msgpack_be64(cb
|
563
|
+
uint64_t u64 = _msgpack_be64(cb.u64);
|
475
564
|
return object_complete(uk, rb_ull2inum(u64));
|
476
565
|
}
|
477
566
|
|
478
567
|
case 0xd0: // signed int 8
|
479
568
|
{
|
480
569
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
481
|
-
int8_t i8 = cb
|
570
|
+
int8_t i8 = cb.i8;
|
482
571
|
return object_complete(uk, INT2NUM((int)i8));
|
483
572
|
}
|
484
573
|
|
485
574
|
case 0xd1: // signed int 16
|
486
575
|
{
|
487
576
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
488
|
-
int16_t i16 = _msgpack_be16(cb
|
577
|
+
int16_t i16 = _msgpack_be16(cb.i16);
|
489
578
|
return object_complete(uk, INT2NUM((int)i16));
|
490
579
|
}
|
491
580
|
|
492
581
|
case 0xd2: // signed int 32
|
493
582
|
{
|
494
583
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
495
|
-
int32_t i32 = _msgpack_be32(cb
|
584
|
+
int32_t i32 = _msgpack_be32(cb.i32);
|
496
585
|
return object_complete(uk, LONG2NUM(i32)); // long at least 32 bits
|
497
586
|
}
|
498
587
|
|
499
588
|
case 0xd3: // signed int 64
|
500
589
|
{
|
501
590
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
|
502
|
-
int64_t i64 = _msgpack_be64(cb
|
591
|
+
int64_t i64 = _msgpack_be64(cb.i64);
|
503
592
|
return object_complete(uk, rb_ll2inum(i64));
|
504
593
|
}
|
505
594
|
|
506
595
|
case 0xd4: // fixext 1
|
507
596
|
{
|
508
597
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
509
|
-
int ext_type = cb
|
598
|
+
int ext_type = cb.i8;
|
510
599
|
uk->reading_raw_remaining = 1;
|
511
600
|
return read_raw_body_begin(uk, ext_type);
|
512
601
|
}
|
@@ -514,7 +603,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
514
603
|
case 0xd5: // fixext 2
|
515
604
|
{
|
516
605
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
517
|
-
int ext_type = cb
|
606
|
+
int ext_type = cb.i8;
|
518
607
|
uk->reading_raw_remaining = 2;
|
519
608
|
return read_raw_body_begin(uk, ext_type);
|
520
609
|
}
|
@@ -522,7 +611,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
522
611
|
case 0xd6: // fixext 4
|
523
612
|
{
|
524
613
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
525
|
-
int ext_type = cb
|
614
|
+
int ext_type = cb.i8;
|
526
615
|
uk->reading_raw_remaining = 4;
|
527
616
|
return read_raw_body_begin(uk, ext_type);
|
528
617
|
}
|
@@ -530,7 +619,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
530
619
|
case 0xd7: // fixext 8
|
531
620
|
{
|
532
621
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
533
|
-
int ext_type = cb
|
622
|
+
int ext_type = cb.i8;
|
534
623
|
uk->reading_raw_remaining = 8;
|
535
624
|
return read_raw_body_begin(uk, ext_type);
|
536
625
|
}
|
@@ -538,7 +627,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
538
627
|
case 0xd8: // fixext 16
|
539
628
|
{
|
540
629
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
541
|
-
int ext_type = cb
|
630
|
+
int ext_type = cb.i8;
|
542
631
|
uk->reading_raw_remaining = 16;
|
543
632
|
return read_raw_body_begin(uk, ext_type);
|
544
633
|
}
|
@@ -547,7 +636,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
547
636
|
case 0xd9: // raw 8 / str 8
|
548
637
|
{
|
549
638
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
550
|
-
uint8_t count = cb
|
639
|
+
uint8_t count = cb.u8;
|
551
640
|
/* read_raw_body_begin sets uk->reading_raw */
|
552
641
|
uk->reading_raw_remaining = count;
|
553
642
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -556,7 +645,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
556
645
|
case 0xda: // raw 16 / str 16
|
557
646
|
{
|
558
647
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
559
|
-
uint16_t count = _msgpack_be16(cb
|
648
|
+
uint16_t count = _msgpack_be16(cb.u16);
|
560
649
|
/* read_raw_body_begin sets uk->reading_raw */
|
561
650
|
uk->reading_raw_remaining = count;
|
562
651
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -565,7 +654,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
565
654
|
case 0xdb: // raw 32 / str 32
|
566
655
|
{
|
567
656
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
568
|
-
uint32_t count = _msgpack_be32(cb
|
657
|
+
uint32_t count = _msgpack_be32(cb.u32);
|
569
658
|
/* read_raw_body_begin sets uk->reading_raw */
|
570
659
|
uk->reading_raw_remaining = count;
|
571
660
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -574,7 +663,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
574
663
|
case 0xc4: // bin 8
|
575
664
|
{
|
576
665
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
577
|
-
uint8_t count = cb
|
666
|
+
uint8_t count = cb.u8;
|
578
667
|
/* read_raw_body_begin sets uk->reading_raw */
|
579
668
|
uk->reading_raw_remaining = count;
|
580
669
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -583,7 +672,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
583
672
|
case 0xc5: // bin 16
|
584
673
|
{
|
585
674
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
586
|
-
uint16_t count = _msgpack_be16(cb
|
675
|
+
uint16_t count = _msgpack_be16(cb.u16);
|
587
676
|
/* read_raw_body_begin sets uk->reading_raw */
|
588
677
|
uk->reading_raw_remaining = count;
|
589
678
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -592,7 +681,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
592
681
|
case 0xc6: // bin 32
|
593
682
|
{
|
594
683
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
595
|
-
uint32_t count = _msgpack_be32(cb
|
684
|
+
uint32_t count = _msgpack_be32(cb.u32);
|
596
685
|
/* read_raw_body_begin sets uk->reading_raw */
|
597
686
|
uk->reading_raw_remaining = count;
|
598
687
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -601,41 +690,41 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
601
690
|
case 0xdc: // array 16
|
602
691
|
{
|
603
692
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
604
|
-
uint16_t count = _msgpack_be16(cb
|
693
|
+
uint16_t count = _msgpack_be16(cb.u16);
|
605
694
|
if(count == 0) {
|
606
695
|
return object_complete(uk, rb_ary_new());
|
607
696
|
}
|
608
|
-
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)));
|
609
698
|
}
|
610
699
|
|
611
700
|
case 0xdd: // array 32
|
612
701
|
{
|
613
702
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
614
|
-
uint32_t count = _msgpack_be32(cb
|
703
|
+
uint32_t count = _msgpack_be32(cb.u32);
|
615
704
|
if(count == 0) {
|
616
705
|
return object_complete(uk, rb_ary_new());
|
617
706
|
}
|
618
|
-
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)));
|
619
708
|
}
|
620
709
|
|
621
710
|
case 0xde: // map 16
|
622
711
|
{
|
623
712
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
624
|
-
uint16_t count = _msgpack_be16(cb
|
713
|
+
uint16_t count = _msgpack_be16(cb.u16);
|
625
714
|
if(count == 0) {
|
626
715
|
return object_complete(uk, rb_hash_new());
|
627
716
|
}
|
628
|
-
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)));
|
629
718
|
}
|
630
719
|
|
631
720
|
case 0xdf: // map 32
|
632
721
|
{
|
633
722
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
634
|
-
uint32_t count = _msgpack_be32(cb
|
723
|
+
uint32_t count = _msgpack_be32(cb.u32);
|
635
724
|
if(count == 0) {
|
636
725
|
return object_complete(uk, rb_hash_new());
|
637
726
|
}
|
638
|
-
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)));
|
639
728
|
}
|
640
729
|
|
641
730
|
default:
|
@@ -661,12 +750,12 @@ int msgpack_unpacker_read_array_header(msgpack_unpacker_t* uk, uint32_t* result_
|
|
661
750
|
} else if(b == 0xdc) {
|
662
751
|
/* array 16 */
|
663
752
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
664
|
-
*result_size = _msgpack_be16(cb
|
753
|
+
*result_size = _msgpack_be16(cb.u16);
|
665
754
|
|
666
755
|
} else if(b == 0xdd) {
|
667
756
|
/* array 32 */
|
668
757
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
669
|
-
*result_size = _msgpack_be32(cb
|
758
|
+
*result_size = _msgpack_be32(cb.u32);
|
670
759
|
|
671
760
|
} else {
|
672
761
|
return PRIMITIVE_UNEXPECTED_TYPE;
|
@@ -689,12 +778,12 @@ int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint32_t* result_si
|
|
689
778
|
} else if(b == 0xde) {
|
690
779
|
/* map 16 */
|
691
780
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
692
|
-
*result_size = _msgpack_be16(cb
|
781
|
+
*result_size = _msgpack_be16(cb.u16);
|
693
782
|
|
694
783
|
} else if(b == 0xdf) {
|
695
784
|
/* map 32 */
|
696
785
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
697
|
-
*result_size = _msgpack_be32(cb
|
786
|
+
*result_size = _msgpack_be32(cb.u32);
|
698
787
|
|
699
788
|
} else {
|
700
789
|
return PRIMITIVE_UNEXPECTED_TYPE;
|
@@ -706,9 +795,15 @@ int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint32_t* result_si
|
|
706
795
|
|
707
796
|
int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
708
797
|
{
|
798
|
+
STACK_INIT(uk);
|
799
|
+
|
709
800
|
while(true) {
|
710
801
|
int r = read_primitive(uk);
|
711
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
|
+
}
|
712
807
|
return r;
|
713
808
|
}
|
714
809
|
if(r == PRIMITIVE_CONTAINER_START) {
|
@@ -717,6 +812,7 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
717
812
|
/* PRIMITIVE_OBJECT_COMPLETE */
|
718
813
|
|
719
814
|
if(msgpack_unpacker_stack_is_empty(uk)) {
|
815
|
+
STACK_FREE(uk);
|
720
816
|
return PRIMITIVE_OBJECT_COMPLETE;
|
721
817
|
}
|
722
818
|
|
@@ -740,12 +836,16 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
740
836
|
}
|
741
837
|
top->type = STACK_TYPE_MAP_KEY;
|
742
838
|
break;
|
839
|
+
case STACK_TYPE_RECURSIVE:
|
840
|
+
STACK_FREE(uk);
|
841
|
+
return PRIMITIVE_OBJECT_COMPLETE;
|
743
842
|
}
|
744
843
|
size_t count = --top->count;
|
745
844
|
|
746
845
|
if(count == 0) {
|
747
846
|
object_complete(uk, top->object);
|
748
847
|
if(msgpack_unpacker_stack_pop(uk) <= target_stack_depth) {
|
848
|
+
STACK_FREE(uk);
|
749
849
|
return PRIMITIVE_OBJECT_COMPLETE;
|
750
850
|
}
|
751
851
|
goto container_completed;
|
@@ -756,9 +856,12 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
756
856
|
|
757
857
|
int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
758
858
|
{
|
859
|
+
STACK_INIT(uk);
|
860
|
+
|
759
861
|
while(true) {
|
760
862
|
int r = read_primitive(uk);
|
761
863
|
if(r < 0) {
|
864
|
+
STACK_FREE(uk);
|
762
865
|
return r;
|
763
866
|
}
|
764
867
|
if(r == PRIMITIVE_CONTAINER_START) {
|
@@ -767,6 +870,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
767
870
|
/* PRIMITIVE_OBJECT_COMPLETE */
|
768
871
|
|
769
872
|
if(msgpack_unpacker_stack_is_empty(uk)) {
|
873
|
+
STACK_FREE(uk);
|
770
874
|
return PRIMITIVE_OBJECT_COMPLETE;
|
771
875
|
}
|
772
876
|
|
@@ -782,6 +886,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
782
886
|
if(count == 0) {
|
783
887
|
object_complete(uk, Qnil);
|
784
888
|
if(msgpack_unpacker_stack_pop(uk) <= target_stack_depth) {
|
889
|
+
STACK_FREE(uk);
|
785
890
|
return PRIMITIVE_OBJECT_COMPLETE;
|
786
891
|
}
|
787
892
|
goto container_completed;
|