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