msgpack 1.5.4 → 1.8.4
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 +80 -1
- data/README.md +49 -13
- data/ext/java/org/msgpack/jruby/Buffer.java +3 -3
- data/ext/java/org/msgpack/jruby/Decoder.java +15 -7
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +11 -20
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +1 -1
- data/ext/java/org/msgpack/jruby/Factory.java +11 -50
- data/ext/java/org/msgpack/jruby/Packer.java +9 -24
- data/ext/java/org/msgpack/jruby/Unpacker.java +15 -32
- data/ext/msgpack/buffer.c +101 -58
- data/ext/msgpack/buffer.h +138 -44
- data/ext/msgpack/buffer_class.c +132 -31
- data/ext/msgpack/buffer_class.h +1 -0
- data/ext/msgpack/extconf.rb +20 -30
- data/ext/msgpack/factory_class.c +75 -86
- data/ext/msgpack/packer.c +13 -16
- data/ext/msgpack/packer.h +18 -21
- data/ext/msgpack/packer_class.c +72 -98
- data/ext/msgpack/packer_class.h +11 -0
- data/ext/msgpack/packer_ext_registry.c +31 -28
- data/ext/msgpack/packer_ext_registry.h +10 -14
- data/ext/msgpack/rbinit.c +1 -1
- data/ext/msgpack/rmem.c +3 -4
- data/ext/msgpack/sysdep.h +5 -2
- data/ext/msgpack/unpacker.c +241 -218
- data/ext/msgpack/unpacker.h +29 -31
- data/ext/msgpack/unpacker_class.c +87 -92
- data/ext/msgpack/unpacker_class.h +11 -0
- data/ext/msgpack/unpacker_ext_registry.c +4 -16
- data/ext/msgpack/unpacker_ext_registry.h +3 -7
- data/lib/msgpack/buffer.rb +9 -0
- data/lib/msgpack/factory.rb +90 -63
- data/lib/msgpack/packer.rb +10 -1
- data/lib/msgpack/unpacker.rb +14 -1
- data/lib/msgpack/version.rb +1 -1
- data/lib/msgpack.rb +1 -0
- data/msgpack.gemspec +13 -12
- metadata +13 -152
- data/.github/workflows/ci.yaml +0 -57
- data/.gitignore +0 -23
- data/.rubocop.yml +0 -36
- data/Gemfile +0 -9
- data/Rakefile +0 -70
- data/appveyor.yml +0 -18
- data/bench/bench.rb +0 -78
- data/doclib/msgpack/buffer.rb +0 -193
- data/doclib/msgpack/core_ext.rb +0 -101
- data/doclib/msgpack/error.rb +0 -19
- data/doclib/msgpack/extension_value.rb +0 -9
- data/doclib/msgpack/factory.rb +0 -145
- data/doclib/msgpack/packer.rb +0 -209
- data/doclib/msgpack/time.rb +0 -22
- data/doclib/msgpack/timestamp.rb +0 -44
- data/doclib/msgpack/unpacker.rb +0 -183
- data/doclib/msgpack.rb +0 -87
- data/msgpack.org.md +0 -46
- data/spec/bigint_spec.rb +0 -26
- data/spec/cases.json +0 -1
- data/spec/cases.msg +0 -0
- data/spec/cases_compact.msg +0 -0
- data/spec/cases_spec.rb +0 -39
- data/spec/cruby/buffer_io_spec.rb +0 -255
- data/spec/cruby/buffer_packer.rb +0 -29
- data/spec/cruby/buffer_spec.rb +0 -575
- data/spec/cruby/buffer_unpacker.rb +0 -19
- data/spec/cruby/unpacker_spec.rb +0 -70
- data/spec/ext_value_spec.rb +0 -99
- data/spec/exttypes.rb +0 -51
- data/spec/factory_spec.rb +0 -664
- data/spec/format_spec.rb +0 -301
- data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
- data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
- data/spec/jruby/unpacker_spec.rb +0 -186
- data/spec/msgpack_spec.rb +0 -214
- data/spec/pack_spec.rb +0 -61
- data/spec/packer_spec.rb +0 -575
- data/spec/random_compat.rb +0 -24
- data/spec/spec_helper.rb +0 -71
- data/spec/timestamp_spec.rb +0 -159
- data/spec/unpack_spec.rb +0 -57
- data/spec/unpacker_spec.rb +0 -859
data/ext/msgpack/unpacker.c
CHANGED
|
@@ -19,102 +19,147 @@
|
|
|
19
19
|
#include "unpacker.h"
|
|
20
20
|
#include "rmem.h"
|
|
21
21
|
#include "extension_value_class.h"
|
|
22
|
+
#include <assert.h>
|
|
23
|
+
#include <limits.h>
|
|
22
24
|
|
|
23
|
-
#if !defined(
|
|
24
|
-
|
|
25
|
-
#define UNPACKER_STACK_RMEM
|
|
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)
|
|
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
|
-
static ID s_call;
|
|
32
|
-
|
|
33
|
-
#ifdef UNPACKER_STACK_RMEM
|
|
34
67
|
static msgpack_rmem_t s_stack_rmem;
|
|
35
|
-
#endif
|
|
36
68
|
|
|
37
69
|
#if !defined(HAVE_RB_HASH_NEW_CAPA)
|
|
38
|
-
static inline VALUE
|
|
70
|
+
static inline VALUE rb_hash_new_capa_inline(long capa)
|
|
39
71
|
{
|
|
40
72
|
return rb_hash_new();
|
|
41
73
|
}
|
|
74
|
+
#define rb_hash_new_capa rb_hash_new_capa_inline
|
|
42
75
|
#endif
|
|
43
76
|
|
|
44
|
-
|
|
77
|
+
static inline int16_t initial_buffer_size(long size)
|
|
45
78
|
{
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
79
|
+
return (size > INITIAL_BUFFER_CAPACITY_MAX) ? INITIAL_BUFFER_CAPACITY_MAX : size;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
void msgpack_unpacker_static_init(void)
|
|
83
|
+
{
|
|
84
|
+
assert(sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE);
|
|
49
85
|
|
|
50
|
-
|
|
86
|
+
msgpack_rmem_init(&s_stack_rmem);
|
|
51
87
|
}
|
|
52
88
|
|
|
53
|
-
void msgpack_unpacker_static_destroy()
|
|
89
|
+
void msgpack_unpacker_static_destroy(void)
|
|
54
90
|
{
|
|
55
|
-
#ifdef UNPACKER_STACK_RMEM
|
|
56
91
|
msgpack_rmem_destroy(&s_stack_rmem);
|
|
57
|
-
#endif
|
|
58
92
|
}
|
|
59
93
|
|
|
60
94
|
#define HEAD_BYTE_REQUIRED 0xc1
|
|
61
95
|
|
|
62
|
-
static inline msgpack_unpacker_stack_t*
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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;
|
|
70
104
|
}
|
|
71
105
|
|
|
72
|
-
|
|
73
|
-
{
|
|
74
|
-
|
|
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
|
+
}
|
|
114
|
+
}
|
|
75
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
|
+
|
|
119
|
+
void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
|
120
|
+
{
|
|
76
121
|
msgpack_buffer_init(UNPACKER_BUFFER_(uk));
|
|
77
122
|
|
|
78
123
|
uk->head_byte = HEAD_BYTE_REQUIRED;
|
|
79
124
|
|
|
80
125
|
uk->last_object = Qnil;
|
|
81
126
|
uk->reading_raw = Qnil;
|
|
127
|
+
}
|
|
82
128
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
129
|
+
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
|
|
130
|
+
{
|
|
131
|
+
_msgpack_unpacker_free_stack(&uk->stack);
|
|
132
|
+
msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
|
|
87
133
|
}
|
|
88
134
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
135
|
+
void msgpack_unpacker_mark_stack(msgpack_unpacker_stack_t* stack)
|
|
136
|
+
{
|
|
137
|
+
if (stack->data) {
|
|
138
|
+
msgpack_unpacker_stack_entry_t* s = stack->data;
|
|
139
|
+
msgpack_unpacker_stack_entry_t* send = stack->data + stack->depth;
|
|
140
|
+
for(; s < send; s++) {
|
|
141
|
+
rb_gc_mark(s->object);
|
|
142
|
+
rb_gc_mark(s->key);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
95
145
|
}
|
|
96
146
|
|
|
97
|
-
void
|
|
147
|
+
void msgpack_unpacker_mark_key_cache(msgpack_key_cache_t *cache)
|
|
98
148
|
{
|
|
99
|
-
|
|
100
|
-
|
|
149
|
+
const VALUE *entries = &cache->entries[0];
|
|
150
|
+
rb_gc_mark_locations(entries, entries + cache->length);
|
|
101
151
|
}
|
|
102
152
|
|
|
103
153
|
void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
|
|
104
154
|
{
|
|
105
155
|
rb_gc_mark(uk->last_object);
|
|
106
156
|
rb_gc_mark(uk->reading_raw);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
msgpack_unpacker_stack_t* send = uk->stack + uk->stack_depth;
|
|
110
|
-
for(; s < send; s++) {
|
|
111
|
-
rb_gc_mark(s->object);
|
|
112
|
-
rb_gc_mark(s->key);
|
|
113
|
-
}
|
|
114
|
-
|
|
157
|
+
msgpack_unpacker_mark_stack(&uk->stack);
|
|
158
|
+
msgpack_unpacker_mark_key_cache(&uk->key_cache);
|
|
115
159
|
/* See MessagePack_Buffer_wrap */
|
|
116
160
|
/* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
|
|
117
161
|
rb_gc_mark(uk->buffer_ref);
|
|
162
|
+
rb_gc_mark(uk->self);
|
|
118
163
|
}
|
|
119
164
|
|
|
120
165
|
void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
|
|
@@ -123,9 +168,8 @@ void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
|
|
|
123
168
|
|
|
124
169
|
uk->head_byte = HEAD_BYTE_REQUIRED;
|
|
125
170
|
|
|
126
|
-
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->
|
|
127
|
-
uk->
|
|
128
|
-
|
|
171
|
+
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack.depth);*/
|
|
172
|
+
uk->stack.depth = 0;
|
|
129
173
|
uk->last_object = Qnil;
|
|
130
174
|
uk->reading_raw = Qnil;
|
|
131
175
|
uk->reading_raw_remaining = 0;
|
|
@@ -167,7 +211,7 @@ static inline int object_complete(msgpack_unpacker_t* uk, VALUE object)
|
|
|
167
211
|
return PRIMITIVE_OBJECT_COMPLETE;
|
|
168
212
|
}
|
|
169
213
|
|
|
170
|
-
static inline int
|
|
214
|
+
static inline int object_complete_frozen(msgpack_unpacker_t* uk, VALUE object)
|
|
171
215
|
{
|
|
172
216
|
uk->last_object = object;
|
|
173
217
|
reset_head_byte(uk);
|
|
@@ -178,9 +222,9 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
|
178
222
|
{
|
|
179
223
|
if (uk->optimized_symbol_ext_type && ext_type == uk->symbol_ext_type) {
|
|
180
224
|
if (RB_UNLIKELY(NIL_P(str))) { // empty extension is returned as Qnil
|
|
181
|
-
return
|
|
225
|
+
return object_complete_frozen(uk, ID2SYM(rb_intern3("", 0, rb_utf8_encoding())));
|
|
182
226
|
}
|
|
183
|
-
return
|
|
227
|
+
return object_complete_frozen(uk, rb_str_intern(str));
|
|
184
228
|
}
|
|
185
229
|
|
|
186
230
|
int ext_flags;
|
|
@@ -188,7 +232,13 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
|
188
232
|
|
|
189
233
|
if(proc != Qnil) {
|
|
190
234
|
VALUE obj;
|
|
191
|
-
|
|
235
|
+
VALUE arg = (str == Qnil ? rb_str_buf_new(0) : str);
|
|
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
|
+
}
|
|
192
242
|
return object_complete(uk, obj);
|
|
193
243
|
}
|
|
194
244
|
|
|
@@ -201,37 +251,37 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
|
201
251
|
}
|
|
202
252
|
|
|
203
253
|
/* stack funcs */
|
|
204
|
-
static inline
|
|
254
|
+
static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
|
|
205
255
|
{
|
|
206
|
-
return &uk->stack[uk->
|
|
256
|
+
return &uk->stack.data[uk->stack.depth-1];
|
|
207
257
|
}
|
|
208
258
|
|
|
209
259
|
static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
|
|
210
260
|
{
|
|
211
261
|
reset_head_byte(uk);
|
|
212
262
|
|
|
213
|
-
if(uk->
|
|
263
|
+
if(uk->stack.capacity - uk->stack.depth <= 0) {
|
|
214
264
|
return PRIMITIVE_STACK_TOO_DEEP;
|
|
215
265
|
}
|
|
216
266
|
|
|
217
|
-
|
|
267
|
+
msgpack_unpacker_stack_entry_t* next = &uk->stack.data[uk->stack.depth];
|
|
218
268
|
next->count = count;
|
|
219
269
|
next->type = type;
|
|
220
270
|
next->object = object;
|
|
221
271
|
next->key = Qnil;
|
|
222
272
|
|
|
223
|
-
uk->
|
|
273
|
+
uk->stack.depth++;
|
|
224
274
|
return PRIMITIVE_CONTAINER_START;
|
|
225
275
|
}
|
|
226
276
|
|
|
227
|
-
static inline
|
|
277
|
+
static inline size_t msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
|
|
228
278
|
{
|
|
229
|
-
return --uk->
|
|
279
|
+
return --uk->stack.depth;
|
|
230
280
|
}
|
|
231
281
|
|
|
232
282
|
static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
|
233
283
|
{
|
|
234
|
-
return uk->
|
|
284
|
+
return uk->stack.depth == 0;
|
|
235
285
|
}
|
|
236
286
|
|
|
237
287
|
#ifdef USE_CASE_RANGE
|
|
@@ -250,17 +300,30 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
|
|
250
300
|
|
|
251
301
|
#endif
|
|
252
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
|
+
};
|
|
253
316
|
|
|
254
317
|
#define READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, n) \
|
|
255
|
-
union msgpack_buffer_cast_block_t
|
|
256
|
-
if(
|
|
318
|
+
union msgpack_buffer_cast_block_t cb; \
|
|
319
|
+
if (!msgpack_buffer_read_all(UNPACKER_BUFFER_(uk), (char *)&cb.buffer, n)) { \
|
|
257
320
|
return PRIMITIVE_EOF; \
|
|
258
321
|
}
|
|
259
322
|
|
|
260
323
|
static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
|
|
261
324
|
{
|
|
262
|
-
if(uk->
|
|
263
|
-
|
|
325
|
+
if(uk->stack.depth > 0) {
|
|
326
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
|
264
327
|
if(top->type == STACK_TYPE_MAP_KEY) {
|
|
265
328
|
return true;
|
|
266
329
|
}
|
|
@@ -273,7 +336,8 @@ static int read_raw_body_cont(msgpack_unpacker_t* uk)
|
|
|
273
336
|
size_t length = uk->reading_raw_remaining;
|
|
274
337
|
|
|
275
338
|
if(uk->reading_raw == Qnil) {
|
|
276
|
-
|
|
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);
|
|
277
341
|
}
|
|
278
342
|
|
|
279
343
|
do {
|
|
@@ -314,20 +378,22 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
|
314
378
|
reset_head_byte(uk);
|
|
315
379
|
uk->reading_raw_remaining = 0;
|
|
316
380
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
381
|
+
if(_msgpack_unpacker_stack_push(uk, STACK_TYPE_RECURSIVE, 1, Qnil) < 0) {
|
|
382
|
+
/* Recursive extensions re-enter msgpack_unpacker_read() through the
|
|
383
|
+
* user proc, consuming a full C stack frame per nesting level. If we
|
|
384
|
+
* ignore a failed push (stack already at MSGPACK_UNPACKER_STACK_CAPACITY)
|
|
385
|
+
* the recursion continues unbounded and exhausts the C stack (SIGSEGV)
|
|
386
|
+
* instead of raising StackError like every other container type. */
|
|
387
|
+
return PRIMITIVE_STACK_TOO_DEEP;
|
|
388
|
+
}
|
|
389
|
+
int raised;
|
|
390
|
+
obj = protected_proc_call(proc, 1, &uk->self, &raised);
|
|
391
|
+
msgpack_unpacker_stack_pop(uk);
|
|
326
392
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
393
|
+
if (raised) {
|
|
394
|
+
uk->last_object = rb_errinfo();
|
|
395
|
+
return PRIMITIVE_RECURSIVE_RAISED;
|
|
396
|
+
}
|
|
331
397
|
|
|
332
398
|
return object_complete(uk, obj);
|
|
333
399
|
}
|
|
@@ -337,15 +403,32 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
|
337
403
|
size_t length = uk->reading_raw_remaining;
|
|
338
404
|
if(length <= msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk))) {
|
|
339
405
|
int ret;
|
|
340
|
-
if ((uk->optimized_symbol_ext_type && uk->symbol_ext_type == raw_type)
|
|
406
|
+
if ((uk->optimized_symbol_ext_type && uk->symbol_ext_type == raw_type)) {
|
|
341
407
|
VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, raw_type != RAW_TYPE_BINARY);
|
|
342
|
-
ret =
|
|
408
|
+
ret = object_complete_frozen(uk, symbol);
|
|
409
|
+
} else if (is_reading_map_key(uk) && raw_type == RAW_TYPE_STRING) {
|
|
410
|
+
/* don't use zerocopy for hash keys but get a frozen string directly
|
|
411
|
+
* because rb_hash_aset freezes keys and it causes copying */
|
|
412
|
+
VALUE key;
|
|
413
|
+
if (uk->symbolize_keys) {
|
|
414
|
+
if (uk->use_key_cache) {
|
|
415
|
+
key = msgpack_buffer_read_top_as_interned_symbol(UNPACKER_BUFFER_(uk), &uk->key_cache, length);
|
|
416
|
+
} else {
|
|
417
|
+
key = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, true);
|
|
418
|
+
}
|
|
419
|
+
ret = object_complete_frozen(uk, key);
|
|
420
|
+
} else {
|
|
421
|
+
if (uk->use_key_cache) {
|
|
422
|
+
key = msgpack_buffer_read_top_as_interned_string(UNPACKER_BUFFER_(uk), &uk->key_cache, length);
|
|
423
|
+
} else {
|
|
424
|
+
key = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, true, true);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
ret = object_complete(uk, key);
|
|
428
|
+
}
|
|
343
429
|
} else {
|
|
344
430
|
bool will_freeze = uk->freeze;
|
|
345
431
|
if(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY) {
|
|
346
|
-
/* don't use zerocopy for hash keys but get a frozen string directly
|
|
347
|
-
* because rb_hash_aset freezes keys and it causes copying */
|
|
348
|
-
will_freeze = will_freeze || is_reading_map_key(uk);
|
|
349
432
|
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
|
|
350
433
|
ret = object_complete(uk, string);
|
|
351
434
|
} else {
|
|
@@ -374,49 +457,49 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
374
457
|
|
|
375
458
|
SWITCH_RANGE_BEGIN(b)
|
|
376
459
|
SWITCH_RANGE(b, 0x00, 0x7f) // Positive Fixnum
|
|
377
|
-
return
|
|
460
|
+
return object_complete_frozen(uk, INT2NUM(b));
|
|
378
461
|
|
|
379
462
|
SWITCH_RANGE(b, 0xe0, 0xff) // Negative Fixnum
|
|
380
|
-
return
|
|
463
|
+
return object_complete_frozen(uk, INT2NUM((int8_t)b));
|
|
381
464
|
|
|
382
465
|
SWITCH_RANGE(b, 0xa0, 0xbf) // FixRaw / fixstr
|
|
383
|
-
|
|
466
|
+
size_t count = b & 0x1f;
|
|
384
467
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
385
468
|
uk->reading_raw_remaining = count;
|
|
386
469
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
|
387
470
|
|
|
388
471
|
SWITCH_RANGE(b, 0x90, 0x9f) // FixArray
|
|
389
|
-
|
|
472
|
+
size_t count = b & 0x0f;
|
|
390
473
|
if(count == 0) {
|
|
391
474
|
return object_complete(uk, rb_ary_new());
|
|
392
475
|
}
|
|
393
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
|
|
476
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
|
|
394
477
|
|
|
395
478
|
SWITCH_RANGE(b, 0x80, 0x8f) // FixMap
|
|
396
479
|
int count = b & 0x0f;
|
|
397
480
|
if(count == 0) {
|
|
398
481
|
return object_complete(uk, rb_hash_new());
|
|
399
482
|
}
|
|
400
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
|
483
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
|
|
401
484
|
|
|
402
485
|
SWITCH_RANGE(b, 0xc0, 0xdf) // Variable
|
|
403
486
|
switch(b) {
|
|
404
487
|
case 0xc0: // nil
|
|
405
|
-
return
|
|
488
|
+
return object_complete_frozen(uk, Qnil);
|
|
406
489
|
|
|
407
490
|
//case 0xc1: // string
|
|
408
491
|
|
|
409
492
|
case 0xc2: // false
|
|
410
|
-
return
|
|
493
|
+
return object_complete_frozen(uk, Qfalse);
|
|
411
494
|
|
|
412
495
|
case 0xc3: // true
|
|
413
|
-
return
|
|
496
|
+
return object_complete_frozen(uk, Qtrue);
|
|
414
497
|
|
|
415
498
|
case 0xc7: // ext 8
|
|
416
499
|
{
|
|
417
500
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
|
418
|
-
uint8_t length = cb
|
|
419
|
-
int ext_type = (signed char) cb
|
|
501
|
+
uint8_t length = cb.u8;
|
|
502
|
+
int ext_type = (signed char) cb.buffer[1];
|
|
420
503
|
if(length == 0) {
|
|
421
504
|
return object_complete_ext(uk, ext_type, Qnil);
|
|
422
505
|
}
|
|
@@ -427,8 +510,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
427
510
|
case 0xc8: // ext 16
|
|
428
511
|
{
|
|
429
512
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 3);
|
|
430
|
-
uint16_t length = _msgpack_be16(cb
|
|
431
|
-
int ext_type = (signed char) cb
|
|
513
|
+
uint16_t length = _msgpack_be16(cb.u16);
|
|
514
|
+
int ext_type = (signed char) cb.buffer[2];
|
|
432
515
|
if(length == 0) {
|
|
433
516
|
return object_complete_ext(uk, ext_type, Qnil);
|
|
434
517
|
}
|
|
@@ -439,8 +522,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
439
522
|
case 0xc9: // ext 32
|
|
440
523
|
{
|
|
441
524
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 5);
|
|
442
|
-
uint32_t length = _msgpack_be32(cb
|
|
443
|
-
int ext_type = (signed char) cb
|
|
525
|
+
uint32_t length = _msgpack_be32(cb.u32);
|
|
526
|
+
int ext_type = (signed char) cb.buffer[4];
|
|
444
527
|
if(length == 0) {
|
|
445
528
|
return object_complete_ext(uk, ext_type, Qnil);
|
|
446
529
|
}
|
|
@@ -451,77 +534,77 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
451
534
|
case 0xca: // float
|
|
452
535
|
{
|
|
453
536
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
|
454
|
-
cb
|
|
455
|
-
return object_complete(uk, rb_float_new(cb
|
|
537
|
+
cb.u32 = _msgpack_be_float(cb.u32);
|
|
538
|
+
return object_complete(uk, rb_float_new(cb.f));
|
|
456
539
|
}
|
|
457
540
|
|
|
458
541
|
case 0xcb: // double
|
|
459
542
|
{
|
|
460
543
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
|
|
461
|
-
cb
|
|
462
|
-
return object_complete(uk, rb_float_new(cb
|
|
544
|
+
cb.u64 = _msgpack_be_double(cb.u64);
|
|
545
|
+
return object_complete(uk, rb_float_new(cb.d));
|
|
463
546
|
}
|
|
464
547
|
|
|
465
548
|
case 0xcc: // unsigned int 8
|
|
466
549
|
{
|
|
467
550
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
|
468
|
-
uint8_t u8 = cb
|
|
469
|
-
return
|
|
551
|
+
uint8_t u8 = cb.u8;
|
|
552
|
+
return object_complete_frozen(uk, INT2NUM((int)u8));
|
|
470
553
|
}
|
|
471
554
|
|
|
472
555
|
case 0xcd: // unsigned int 16
|
|
473
556
|
{
|
|
474
557
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
|
475
|
-
uint16_t u16 = _msgpack_be16(cb
|
|
476
|
-
return
|
|
558
|
+
uint16_t u16 = _msgpack_be16(cb.u16);
|
|
559
|
+
return object_complete_frozen(uk, INT2NUM((int)u16));
|
|
477
560
|
}
|
|
478
561
|
|
|
479
562
|
case 0xce: // unsigned int 32
|
|
480
563
|
{
|
|
481
564
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
|
482
|
-
uint32_t u32 = _msgpack_be32(cb
|
|
565
|
+
uint32_t u32 = _msgpack_be32(cb.u32);
|
|
483
566
|
return object_complete(uk, ULONG2NUM(u32)); // long at least 32 bits
|
|
484
567
|
}
|
|
485
568
|
|
|
486
569
|
case 0xcf: // unsigned int 64
|
|
487
570
|
{
|
|
488
571
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
|
|
489
|
-
uint64_t u64 = _msgpack_be64(cb
|
|
572
|
+
uint64_t u64 = _msgpack_be64(cb.u64);
|
|
490
573
|
return object_complete(uk, rb_ull2inum(u64));
|
|
491
574
|
}
|
|
492
575
|
|
|
493
576
|
case 0xd0: // signed int 8
|
|
494
577
|
{
|
|
495
578
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
|
496
|
-
int8_t i8 = cb
|
|
497
|
-
return
|
|
579
|
+
int8_t i8 = cb.i8;
|
|
580
|
+
return object_complete_frozen(uk, INT2NUM((int)i8));
|
|
498
581
|
}
|
|
499
582
|
|
|
500
583
|
case 0xd1: // signed int 16
|
|
501
584
|
{
|
|
502
585
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
|
503
|
-
int16_t i16 = _msgpack_be16(cb
|
|
504
|
-
return
|
|
586
|
+
int16_t i16 = _msgpack_be16(cb.i16);
|
|
587
|
+
return object_complete_frozen(uk, INT2NUM((int)i16));
|
|
505
588
|
}
|
|
506
589
|
|
|
507
590
|
case 0xd2: // signed int 32
|
|
508
591
|
{
|
|
509
592
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
|
510
|
-
int32_t i32 = _msgpack_be32(cb
|
|
593
|
+
int32_t i32 = _msgpack_be32(cb.i32);
|
|
511
594
|
return object_complete(uk, LONG2NUM(i32)); // long at least 32 bits
|
|
512
595
|
}
|
|
513
596
|
|
|
514
597
|
case 0xd3: // signed int 64
|
|
515
598
|
{
|
|
516
599
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
|
|
517
|
-
int64_t i64 = _msgpack_be64(cb
|
|
600
|
+
int64_t i64 = _msgpack_be64(cb.i64);
|
|
518
601
|
return object_complete(uk, rb_ll2inum(i64));
|
|
519
602
|
}
|
|
520
603
|
|
|
521
604
|
case 0xd4: // fixext 1
|
|
522
605
|
{
|
|
523
606
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
|
524
|
-
int ext_type = cb
|
|
607
|
+
int ext_type = cb.i8;
|
|
525
608
|
uk->reading_raw_remaining = 1;
|
|
526
609
|
return read_raw_body_begin(uk, ext_type);
|
|
527
610
|
}
|
|
@@ -529,7 +612,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
529
612
|
case 0xd5: // fixext 2
|
|
530
613
|
{
|
|
531
614
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
|
532
|
-
int ext_type = cb
|
|
615
|
+
int ext_type = cb.i8;
|
|
533
616
|
uk->reading_raw_remaining = 2;
|
|
534
617
|
return read_raw_body_begin(uk, ext_type);
|
|
535
618
|
}
|
|
@@ -537,7 +620,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
537
620
|
case 0xd6: // fixext 4
|
|
538
621
|
{
|
|
539
622
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
|
540
|
-
int ext_type = cb
|
|
623
|
+
int ext_type = cb.i8;
|
|
541
624
|
uk->reading_raw_remaining = 4;
|
|
542
625
|
return read_raw_body_begin(uk, ext_type);
|
|
543
626
|
}
|
|
@@ -545,7 +628,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
545
628
|
case 0xd7: // fixext 8
|
|
546
629
|
{
|
|
547
630
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
|
548
|
-
int ext_type = cb
|
|
631
|
+
int ext_type = cb.i8;
|
|
549
632
|
uk->reading_raw_remaining = 8;
|
|
550
633
|
return read_raw_body_begin(uk, ext_type);
|
|
551
634
|
}
|
|
@@ -553,7 +636,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
553
636
|
case 0xd8: // fixext 16
|
|
554
637
|
{
|
|
555
638
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
|
556
|
-
int ext_type = cb
|
|
639
|
+
int ext_type = cb.i8;
|
|
557
640
|
uk->reading_raw_remaining = 16;
|
|
558
641
|
return read_raw_body_begin(uk, ext_type);
|
|
559
642
|
}
|
|
@@ -562,7 +645,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
562
645
|
case 0xd9: // raw 8 / str 8
|
|
563
646
|
{
|
|
564
647
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
|
565
|
-
|
|
648
|
+
size_t count = cb.u8;
|
|
566
649
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
567
650
|
uk->reading_raw_remaining = count;
|
|
568
651
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
|
@@ -571,7 +654,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
571
654
|
case 0xda: // raw 16 / str 16
|
|
572
655
|
{
|
|
573
656
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
|
574
|
-
|
|
657
|
+
size_t count = _msgpack_be16(cb.u16);
|
|
575
658
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
576
659
|
uk->reading_raw_remaining = count;
|
|
577
660
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
|
@@ -580,7 +663,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
580
663
|
case 0xdb: // raw 32 / str 32
|
|
581
664
|
{
|
|
582
665
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
|
583
|
-
|
|
666
|
+
size_t count = _msgpack_be32(cb.u32);
|
|
584
667
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
585
668
|
uk->reading_raw_remaining = count;
|
|
586
669
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
|
@@ -589,7 +672,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
589
672
|
case 0xc4: // bin 8
|
|
590
673
|
{
|
|
591
674
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
|
592
|
-
|
|
675
|
+
size_t count = cb.u8;
|
|
593
676
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
594
677
|
uk->reading_raw_remaining = count;
|
|
595
678
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
|
@@ -598,7 +681,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
598
681
|
case 0xc5: // bin 16
|
|
599
682
|
{
|
|
600
683
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
|
601
|
-
|
|
684
|
+
size_t count = _msgpack_be16(cb.u16);
|
|
602
685
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
603
686
|
uk->reading_raw_remaining = count;
|
|
604
687
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
|
@@ -607,7 +690,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
607
690
|
case 0xc6: // bin 32
|
|
608
691
|
{
|
|
609
692
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
|
610
|
-
|
|
693
|
+
size_t count = _msgpack_be32(cb.u32);
|
|
611
694
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
612
695
|
uk->reading_raw_remaining = count;
|
|
613
696
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
|
@@ -616,41 +699,41 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
616
699
|
case 0xdc: // array 16
|
|
617
700
|
{
|
|
618
701
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
|
619
|
-
|
|
702
|
+
size_t count = _msgpack_be16(cb.u16);
|
|
620
703
|
if(count == 0) {
|
|
621
704
|
return object_complete(uk, rb_ary_new());
|
|
622
705
|
}
|
|
623
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
|
|
706
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
|
|
624
707
|
}
|
|
625
708
|
|
|
626
709
|
case 0xdd: // array 32
|
|
627
710
|
{
|
|
628
711
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
|
629
|
-
|
|
712
|
+
size_t count = _msgpack_be32(cb.u32);
|
|
630
713
|
if(count == 0) {
|
|
631
714
|
return object_complete(uk, rb_ary_new());
|
|
632
715
|
}
|
|
633
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
|
|
716
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
|
|
634
717
|
}
|
|
635
718
|
|
|
636
719
|
case 0xde: // map 16
|
|
637
720
|
{
|
|
638
721
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
|
639
|
-
|
|
722
|
+
size_t count = _msgpack_be16(cb.u16);
|
|
640
723
|
if(count == 0) {
|
|
641
724
|
return object_complete(uk, rb_hash_new());
|
|
642
725
|
}
|
|
643
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
|
726
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
|
|
644
727
|
}
|
|
645
728
|
|
|
646
729
|
case 0xdf: // map 32
|
|
647
730
|
{
|
|
648
731
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
|
649
|
-
|
|
732
|
+
size_t count = _msgpack_be32(cb.u32);
|
|
650
733
|
if(count == 0) {
|
|
651
734
|
return object_complete(uk, rb_hash_new());
|
|
652
735
|
}
|
|
653
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
|
736
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
|
|
654
737
|
}
|
|
655
738
|
|
|
656
739
|
default:
|
|
@@ -676,12 +759,12 @@ int msgpack_unpacker_read_array_header(msgpack_unpacker_t* uk, uint32_t* result_
|
|
|
676
759
|
} else if(b == 0xdc) {
|
|
677
760
|
/* array 16 */
|
|
678
761
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
|
679
|
-
*result_size = _msgpack_be16(cb
|
|
762
|
+
*result_size = _msgpack_be16(cb.u16);
|
|
680
763
|
|
|
681
764
|
} else if(b == 0xdd) {
|
|
682
765
|
/* array 32 */
|
|
683
766
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
|
684
|
-
*result_size = _msgpack_be32(cb
|
|
767
|
+
*result_size = _msgpack_be32(cb.u32);
|
|
685
768
|
|
|
686
769
|
} else {
|
|
687
770
|
return PRIMITIVE_UNEXPECTED_TYPE;
|
|
@@ -704,12 +787,12 @@ int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint32_t* result_si
|
|
|
704
787
|
} else if(b == 0xde) {
|
|
705
788
|
/* map 16 */
|
|
706
789
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
|
707
|
-
*result_size = _msgpack_be16(cb
|
|
790
|
+
*result_size = _msgpack_be16(cb.u16);
|
|
708
791
|
|
|
709
792
|
} else if(b == 0xdf) {
|
|
710
793
|
/* map 32 */
|
|
711
794
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
|
712
|
-
*result_size = _msgpack_be32(cb
|
|
795
|
+
*result_size = _msgpack_be32(cb.u32);
|
|
713
796
|
|
|
714
797
|
} else {
|
|
715
798
|
return PRIMITIVE_UNEXPECTED_TYPE;
|
|
@@ -721,9 +804,15 @@ int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint32_t* result_si
|
|
|
721
804
|
|
|
722
805
|
int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
723
806
|
{
|
|
807
|
+
STACK_INIT(uk);
|
|
808
|
+
|
|
724
809
|
while(true) {
|
|
725
810
|
int r = read_primitive(uk);
|
|
726
811
|
if(r < 0) {
|
|
812
|
+
if (r != PRIMITIVE_EOF) {
|
|
813
|
+
// We keep the stack on EOF as the parsing may be resumed.
|
|
814
|
+
STACK_FREE(uk);
|
|
815
|
+
}
|
|
727
816
|
return r;
|
|
728
817
|
}
|
|
729
818
|
if(r == PRIMITIVE_CONTAINER_START) {
|
|
@@ -732,12 +821,13 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
|
732
821
|
/* PRIMITIVE_OBJECT_COMPLETE */
|
|
733
822
|
|
|
734
823
|
if(msgpack_unpacker_stack_is_empty(uk)) {
|
|
824
|
+
STACK_FREE(uk);
|
|
735
825
|
return PRIMITIVE_OBJECT_COMPLETE;
|
|
736
826
|
}
|
|
737
827
|
|
|
738
828
|
container_completed:
|
|
739
829
|
{
|
|
740
|
-
|
|
830
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
|
741
831
|
switch(top->type) {
|
|
742
832
|
case STACK_TYPE_ARRAY:
|
|
743
833
|
rb_ary_push(top->object, uk->last_object);
|
|
@@ -755,12 +845,16 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
|
755
845
|
}
|
|
756
846
|
top->type = STACK_TYPE_MAP_KEY;
|
|
757
847
|
break;
|
|
848
|
+
case STACK_TYPE_RECURSIVE:
|
|
849
|
+
STACK_FREE(uk);
|
|
850
|
+
return PRIMITIVE_OBJECT_COMPLETE;
|
|
758
851
|
}
|
|
759
852
|
size_t count = --top->count;
|
|
760
853
|
|
|
761
854
|
if(count == 0) {
|
|
762
855
|
object_complete(uk, top->object);
|
|
763
856
|
if(msgpack_unpacker_stack_pop(uk) <= target_stack_depth) {
|
|
857
|
+
STACK_FREE(uk);
|
|
764
858
|
return PRIMITIVE_OBJECT_COMPLETE;
|
|
765
859
|
}
|
|
766
860
|
goto container_completed;
|
|
@@ -771,9 +865,12 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
|
771
865
|
|
|
772
866
|
int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
773
867
|
{
|
|
868
|
+
STACK_INIT(uk);
|
|
869
|
+
|
|
774
870
|
while(true) {
|
|
775
871
|
int r = read_primitive(uk);
|
|
776
872
|
if(r < 0) {
|
|
873
|
+
STACK_FREE(uk);
|
|
777
874
|
return r;
|
|
778
875
|
}
|
|
779
876
|
if(r == PRIMITIVE_CONTAINER_START) {
|
|
@@ -782,12 +879,13 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
|
782
879
|
/* PRIMITIVE_OBJECT_COMPLETE */
|
|
783
880
|
|
|
784
881
|
if(msgpack_unpacker_stack_is_empty(uk)) {
|
|
882
|
+
STACK_FREE(uk);
|
|
785
883
|
return PRIMITIVE_OBJECT_COMPLETE;
|
|
786
884
|
}
|
|
787
885
|
|
|
788
886
|
container_completed:
|
|
789
887
|
{
|
|
790
|
-
|
|
888
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
|
791
889
|
|
|
792
890
|
/* this section optimized out */
|
|
793
891
|
// TODO object_complete still creates objects which should be optimized out
|
|
@@ -797,6 +895,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
|
797
895
|
if(count == 0) {
|
|
798
896
|
object_complete(uk, Qnil);
|
|
799
897
|
if(msgpack_unpacker_stack_pop(uk) <= target_stack_depth) {
|
|
898
|
+
STACK_FREE(uk);
|
|
800
899
|
return PRIMITIVE_OBJECT_COMPLETE;
|
|
801
900
|
}
|
|
802
901
|
goto container_completed;
|
|
@@ -805,82 +904,6 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
|
805
904
|
}
|
|
806
905
|
}
|
|
807
906
|
|
|
808
|
-
int msgpack_unpacker_peek_next_object_type(msgpack_unpacker_t* uk)
|
|
809
|
-
{
|
|
810
|
-
int b = get_head_byte(uk);
|
|
811
|
-
if(b < 0) {
|
|
812
|
-
return b;
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
SWITCH_RANGE_BEGIN(b)
|
|
816
|
-
SWITCH_RANGE(b, 0x00, 0x7f) // Positive Fixnum
|
|
817
|
-
return TYPE_INTEGER;
|
|
818
|
-
|
|
819
|
-
SWITCH_RANGE(b, 0xe0, 0xff) // Negative Fixnum
|
|
820
|
-
return TYPE_INTEGER;
|
|
821
|
-
|
|
822
|
-
SWITCH_RANGE(b, 0xa0, 0xbf) // FixRaw
|
|
823
|
-
return TYPE_RAW;
|
|
824
|
-
|
|
825
|
-
SWITCH_RANGE(b, 0x90, 0x9f) // FixArray
|
|
826
|
-
return TYPE_ARRAY;
|
|
827
|
-
|
|
828
|
-
SWITCH_RANGE(b, 0x80, 0x8f) // FixMap
|
|
829
|
-
return TYPE_MAP;
|
|
830
|
-
|
|
831
|
-
SWITCH_RANGE(b, 0xc0, 0xdf) // Variable
|
|
832
|
-
switch(b) {
|
|
833
|
-
case 0xc0: // nil
|
|
834
|
-
return TYPE_NIL;
|
|
835
|
-
|
|
836
|
-
case 0xc2: // false
|
|
837
|
-
case 0xc3: // true
|
|
838
|
-
return TYPE_BOOLEAN;
|
|
839
|
-
|
|
840
|
-
case 0xca: // float
|
|
841
|
-
case 0xcb: // double
|
|
842
|
-
return TYPE_FLOAT;
|
|
843
|
-
|
|
844
|
-
case 0xcc: // unsigned int 8
|
|
845
|
-
case 0xcd: // unsigned int 16
|
|
846
|
-
case 0xce: // unsigned int 32
|
|
847
|
-
case 0xcf: // unsigned int 64
|
|
848
|
-
return TYPE_INTEGER;
|
|
849
|
-
|
|
850
|
-
case 0xd0: // signed int 8
|
|
851
|
-
case 0xd1: // signed int 16
|
|
852
|
-
case 0xd2: // signed int 32
|
|
853
|
-
case 0xd3: // signed int 64
|
|
854
|
-
return TYPE_INTEGER;
|
|
855
|
-
|
|
856
|
-
case 0xd9: // raw 8 / str 8
|
|
857
|
-
case 0xda: // raw 16 / str 16
|
|
858
|
-
case 0xdb: // raw 32 / str 32
|
|
859
|
-
return TYPE_RAW;
|
|
860
|
-
|
|
861
|
-
case 0xc4: // bin 8
|
|
862
|
-
case 0xc5: // bin 16
|
|
863
|
-
case 0xc6: // bin 32
|
|
864
|
-
return TYPE_RAW;
|
|
865
|
-
|
|
866
|
-
case 0xdc: // array 16
|
|
867
|
-
case 0xdd: // array 32
|
|
868
|
-
return TYPE_ARRAY;
|
|
869
|
-
|
|
870
|
-
case 0xde: // map 16
|
|
871
|
-
case 0xdf: // map 32
|
|
872
|
-
return TYPE_MAP;
|
|
873
|
-
|
|
874
|
-
default:
|
|
875
|
-
return PRIMITIVE_INVALID_BYTE;
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
SWITCH_RANGE_DEFAULT
|
|
879
|
-
return PRIMITIVE_INVALID_BYTE;
|
|
880
|
-
|
|
881
|
-
SWITCH_RANGE_END
|
|
882
|
-
}
|
|
883
|
-
|
|
884
907
|
int msgpack_unpacker_skip_nil(msgpack_unpacker_t* uk)
|
|
885
908
|
{
|
|
886
909
|
int b = get_head_byte(uk);
|