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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +80 -1
  3. data/README.md +49 -13
  4. data/ext/java/org/msgpack/jruby/Buffer.java +3 -3
  5. data/ext/java/org/msgpack/jruby/Decoder.java +15 -7
  6. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +11 -20
  7. data/ext/java/org/msgpack/jruby/ExtensionValue.java +1 -1
  8. data/ext/java/org/msgpack/jruby/Factory.java +11 -50
  9. data/ext/java/org/msgpack/jruby/Packer.java +9 -24
  10. data/ext/java/org/msgpack/jruby/Unpacker.java +15 -32
  11. data/ext/msgpack/buffer.c +101 -58
  12. data/ext/msgpack/buffer.h +138 -44
  13. data/ext/msgpack/buffer_class.c +132 -31
  14. data/ext/msgpack/buffer_class.h +1 -0
  15. data/ext/msgpack/extconf.rb +20 -30
  16. data/ext/msgpack/factory_class.c +75 -86
  17. data/ext/msgpack/packer.c +13 -16
  18. data/ext/msgpack/packer.h +18 -21
  19. data/ext/msgpack/packer_class.c +72 -98
  20. data/ext/msgpack/packer_class.h +11 -0
  21. data/ext/msgpack/packer_ext_registry.c +31 -28
  22. data/ext/msgpack/packer_ext_registry.h +10 -14
  23. data/ext/msgpack/rbinit.c +1 -1
  24. data/ext/msgpack/rmem.c +3 -4
  25. data/ext/msgpack/sysdep.h +5 -2
  26. data/ext/msgpack/unpacker.c +241 -218
  27. data/ext/msgpack/unpacker.h +29 -31
  28. data/ext/msgpack/unpacker_class.c +87 -92
  29. data/ext/msgpack/unpacker_class.h +11 -0
  30. data/ext/msgpack/unpacker_ext_registry.c +4 -16
  31. data/ext/msgpack/unpacker_ext_registry.h +3 -7
  32. data/lib/msgpack/buffer.rb +9 -0
  33. data/lib/msgpack/factory.rb +90 -63
  34. data/lib/msgpack/packer.rb +10 -1
  35. data/lib/msgpack/unpacker.rb +14 -1
  36. data/lib/msgpack/version.rb +1 -1
  37. data/lib/msgpack.rb +1 -0
  38. data/msgpack.gemspec +13 -12
  39. metadata +13 -152
  40. data/.github/workflows/ci.yaml +0 -57
  41. data/.gitignore +0 -23
  42. data/.rubocop.yml +0 -36
  43. data/Gemfile +0 -9
  44. data/Rakefile +0 -70
  45. data/appveyor.yml +0 -18
  46. data/bench/bench.rb +0 -78
  47. data/doclib/msgpack/buffer.rb +0 -193
  48. data/doclib/msgpack/core_ext.rb +0 -101
  49. data/doclib/msgpack/error.rb +0 -19
  50. data/doclib/msgpack/extension_value.rb +0 -9
  51. data/doclib/msgpack/factory.rb +0 -145
  52. data/doclib/msgpack/packer.rb +0 -209
  53. data/doclib/msgpack/time.rb +0 -22
  54. data/doclib/msgpack/timestamp.rb +0 -44
  55. data/doclib/msgpack/unpacker.rb +0 -183
  56. data/doclib/msgpack.rb +0 -87
  57. data/msgpack.org.md +0 -46
  58. data/spec/bigint_spec.rb +0 -26
  59. data/spec/cases.json +0 -1
  60. data/spec/cases.msg +0 -0
  61. data/spec/cases_compact.msg +0 -0
  62. data/spec/cases_spec.rb +0 -39
  63. data/spec/cruby/buffer_io_spec.rb +0 -255
  64. data/spec/cruby/buffer_packer.rb +0 -29
  65. data/spec/cruby/buffer_spec.rb +0 -575
  66. data/spec/cruby/buffer_unpacker.rb +0 -19
  67. data/spec/cruby/unpacker_spec.rb +0 -70
  68. data/spec/ext_value_spec.rb +0 -99
  69. data/spec/exttypes.rb +0 -51
  70. data/spec/factory_spec.rb +0 -664
  71. data/spec/format_spec.rb +0 -301
  72. data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
  73. data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
  74. data/spec/jruby/unpacker_spec.rb +0 -186
  75. data/spec/msgpack_spec.rb +0 -214
  76. data/spec/pack_spec.rb +0 -61
  77. data/spec/packer_spec.rb +0 -575
  78. data/spec/random_compat.rb +0 -24
  79. data/spec/spec_helper.rb +0 -71
  80. data/spec/timestamp_spec.rb +0 -159
  81. data/spec/unpack_spec.rb +0 -57
  82. data/spec/unpacker_spec.rb +0 -859
@@ -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(DISABLE_RMEM) && !defined(DISABLE_UNPACKER_STACK_RMEM) && \
24
- MSGPACK_UNPACKER_STACK_CAPACITY * MSGPACK_UNPACKER_STACK_SIZE <= MSGPACK_RMEM_PAGE_SIZE
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 rb_hash_new_capa(long capa)
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
- void msgpack_unpacker_static_init()
77
+ static inline int16_t initial_buffer_size(long size)
45
78
  {
46
- #ifdef UNPACKER_STACK_RMEM
47
- msgpack_rmem_init(&s_stack_rmem);
48
- #endif
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
- s_call = rb_intern("call");
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* _msgpack_unpacker_new_stack(void) {
63
- #ifdef UNPACKER_STACK_RMEM
64
- return msgpack_rmem_alloc(&s_stack_rmem);
65
- /*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
66
- #else
67
- /*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_t));*/
68
- return xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_t));
69
- #endif
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
- msgpack_unpacker_t* _msgpack_unpacker_new(void)
73
- {
74
- msgpack_unpacker_t* uk = ZALLOC_N(msgpack_unpacker_t, 1);
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
- uk->stack = _msgpack_unpacker_new_stack();
84
- uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
85
-
86
- return uk;
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
- static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
90
- #ifdef UNPACKER_STACK_RMEM
91
- msgpack_rmem_free(&s_stack_rmem, stack);
92
- #else
93
- xfree(stack);
94
- #endif
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 _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
147
+ void msgpack_unpacker_mark_key_cache(msgpack_key_cache_t *cache)
98
148
  {
99
- _msgpack_unpacker_free_stack(uk->stack);
100
- msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
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
- msgpack_unpacker_stack_t* s = uk->stack;
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->stack_depth);*/
127
- uk->stack_depth = 0;
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 object_complete_symbol(msgpack_unpacker_t* uk, VALUE object)
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 object_complete_symbol(uk, ID2SYM(rb_intern3("", 0, rb_utf8_encoding())));
225
+ return object_complete_frozen(uk, ID2SYM(rb_intern3("", 0, rb_utf8_encoding())));
182
226
  }
183
- return object_complete_symbol(uk, rb_str_intern(str));
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
- obj = rb_funcall(proc, s_call, 1, str == Qnil ? rb_str_buf_new(0) : str);
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 msgpack_unpacker_stack_t* _msgpack_unpacker_stack_top(msgpack_unpacker_t* uk)
254
+ static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
205
255
  {
206
- return &uk->stack[uk->stack_depth-1];
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->stack_capacity - uk->stack_depth <= 0) {
263
+ if(uk->stack.capacity - uk->stack.depth <= 0) {
214
264
  return PRIMITIVE_STACK_TOO_DEEP;
215
265
  }
216
266
 
217
- msgpack_unpacker_stack_t* next = &uk->stack[uk->stack_depth];
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->stack_depth++;
273
+ uk->stack.depth++;
224
274
  return PRIMITIVE_CONTAINER_START;
225
275
  }
226
276
 
227
- static inline VALUE msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
277
+ static inline size_t msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
228
278
  {
229
- return --uk->stack_depth;
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->stack_depth == 0;
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* cb = msgpack_buffer_read_cast_block(UNPACKER_BUFFER_(uk), n); \
256
- if(cb == NULL) { \
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->stack_depth > 0) {
263
- msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk);
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
- uk->reading_raw = rb_str_buf_new(length);
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
- msgpack_unpacker_stack_t* stack = uk->stack;
318
- size_t stack_depth = uk->stack_depth;
319
- size_t stack_capacity = uk->stack_capacity;
320
-
321
- uk->stack = _msgpack_unpacker_new_stack();
322
- uk->stack_depth = 0;
323
- uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
324
-
325
- obj = rb_funcall(proc, s_call, 1, uk->buffer.owner);
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
- _msgpack_unpacker_free_stack(uk->stack);
328
- uk->stack = stack;
329
- uk->stack_depth = stack_depth;
330
- uk->stack_capacity = stack_capacity;
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) || (uk->symbolize_keys && is_reading_map_key(uk))) {
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 = object_complete_symbol(uk, symbol);
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 object_complete(uk, INT2NUM(b));
460
+ return object_complete_frozen(uk, INT2NUM(b));
378
461
 
379
462
  SWITCH_RANGE(b, 0xe0, 0xff) // Negative Fixnum
380
- return object_complete(uk, INT2NUM((int8_t)b));
463
+ return object_complete_frozen(uk, INT2NUM((int8_t)b));
381
464
 
382
465
  SWITCH_RANGE(b, 0xa0, 0xbf) // FixRaw / fixstr
383
- int count = b & 0x1f;
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
- int count = b & 0x0f;
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 object_complete(uk, Qnil);
488
+ return object_complete_frozen(uk, Qnil);
406
489
 
407
490
  //case 0xc1: // string
408
491
 
409
492
  case 0xc2: // false
410
- return object_complete(uk, Qfalse);
493
+ return object_complete_frozen(uk, Qfalse);
411
494
 
412
495
  case 0xc3: // true
413
- return object_complete(uk, Qtrue);
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->u8;
419
- int ext_type = (signed char) cb->buffer[1];
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->u16);
431
- int ext_type = (signed char) cb->buffer[2];
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->u32);
443
- int ext_type = (signed char) cb->buffer[4];
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->u32 = _msgpack_be_float(cb->u32);
455
- return object_complete(uk, rb_float_new(cb->f));
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->u64 = _msgpack_be_double(cb->u64);
462
- return object_complete(uk, rb_float_new(cb->d));
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->u8;
469
- return object_complete(uk, INT2NUM((int)u8));
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->u16);
476
- return object_complete(uk, INT2NUM((int)u16));
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->u32);
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->u64);
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->i8;
497
- return object_complete(uk, INT2NUM((int)i8));
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->i16);
504
- return object_complete(uk, INT2NUM((int)i16));
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->i32);
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->i64);
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->i8;
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->i8;
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->i8;
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->i8;
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->i8;
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
- uint8_t count = cb->u8;
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
- uint16_t count = _msgpack_be16(cb->u16);
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
- uint32_t count = _msgpack_be32(cb->u32);
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
- uint8_t count = cb->u8;
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
- uint16_t count = _msgpack_be16(cb->u16);
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
- uint32_t count = _msgpack_be32(cb->u32);
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
- uint16_t count = _msgpack_be16(cb->u16);
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
- uint32_t count = _msgpack_be32(cb->u32);
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
- uint16_t count = _msgpack_be16(cb->u16);
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
- uint32_t count = _msgpack_be32(cb->u32);
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->u16);
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->u32);
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->u16);
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->u32);
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
- msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk);
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
- msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk);
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);