msgpack 1.3.3 → 1.7.2
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 +99 -0
- data/README.md +293 -0
- data/ext/java/org/msgpack/jruby/Buffer.java +26 -19
- data/ext/java/org/msgpack/jruby/Decoder.java +46 -23
- data/ext/java/org/msgpack/jruby/Encoder.java +68 -30
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +43 -64
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +6 -9
- data/ext/java/org/msgpack/jruby/Factory.java +43 -42
- data/ext/java/org/msgpack/jruby/Packer.java +37 -40
- data/ext/java/org/msgpack/jruby/Unpacker.java +86 -68
- data/ext/msgpack/buffer.c +58 -85
- data/ext/msgpack/buffer.h +59 -20
- data/ext/msgpack/buffer_class.c +161 -52
- data/ext/msgpack/buffer_class.h +1 -0
- data/ext/msgpack/compat.h +1 -111
- data/ext/msgpack/extconf.rb +41 -23
- data/ext/msgpack/factory_class.c +143 -87
- data/ext/msgpack/packer.c +66 -43
- data/ext/msgpack/packer.h +25 -27
- data/ext/msgpack/packer_class.c +102 -130
- data/ext/msgpack/packer_class.h +11 -0
- data/ext/msgpack/packer_ext_registry.c +35 -40
- data/ext/msgpack/packer_ext_registry.h +41 -38
- 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 +130 -126
- data/ext/msgpack/unpacker.h +22 -13
- data/ext/msgpack/unpacker_class.c +94 -124
- data/ext/msgpack/unpacker_class.h +11 -0
- data/ext/msgpack/unpacker_ext_registry.c +40 -28
- data/ext/msgpack/unpacker_ext_registry.h +21 -18
- data/lib/msgpack/bigint.rb +69 -0
- data/lib/msgpack/buffer.rb +9 -0
- data/lib/msgpack/factory.rb +140 -10
- data/lib/msgpack/packer.rb +10 -1
- data/lib/msgpack/symbol.rb +21 -4
- data/lib/msgpack/time.rb +1 -1
- data/lib/msgpack/unpacker.rb +14 -1
- data/lib/msgpack/version.rb +4 -8
- data/lib/msgpack.rb +7 -12
- data/msgpack.gemspec +9 -8
- metadata +37 -96
- data/.gitignore +0 -23
- data/.rubocop.yml +0 -36
- data/.travis.yml +0 -43
- data/Gemfile +0 -9
- data/README.rdoc +0 -225
- data/Rakefile +0 -78
- data/appveyor.yml +0 -18
- data/bench/pack.rb +0 -23
- data/bench/pack_log.rb +0 -33
- data/bench/pack_log_long.rb +0 -65
- data/bench/pack_symbols.rb +0 -28
- data/bench/run.sh +0 -14
- data/bench/run_long.sh +0 -35
- data/bench/run_symbols.sh +0 -26
- data/bench/unpack.rb +0 -21
- data/bench/unpack_log.rb +0 -34
- data/bench/unpack_log_long.rb +0 -67
- 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 -101
- data/doclib/msgpack/packer.rb +0 -208
- 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/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 -367
- 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 -557
- data/spec/random_compat.rb +0 -24
- data/spec/spec_helper.rb +0 -38
- data/spec/timestamp_spec.rb +0 -121
- data/spec/unpack_spec.rb +0 -57
- data/spec/unpacker_spec.rb +0 -716
data/ext/msgpack/unpacker.c
CHANGED
@@ -19,43 +19,48 @@
|
|
19
19
|
#include "unpacker.h"
|
20
20
|
#include "rmem.h"
|
21
21
|
#include "extension_value_class.h"
|
22
|
+
#include <assert.h>
|
22
23
|
|
23
|
-
#if !defined(
|
24
|
-
|
25
|
-
#define UNPACKER_STACK_RMEM
|
24
|
+
#if !defined(HAVE_RB_PROC_CALL_WITH_BLOCK)
|
25
|
+
#define rb_proc_call_with_block(recv, argc, argv, block) rb_funcallv(recv, rb_intern("call"), argc, argv)
|
26
26
|
#endif
|
27
27
|
|
28
28
|
static int RAW_TYPE_STRING = 256;
|
29
29
|
static int RAW_TYPE_BINARY = 257;
|
30
30
|
|
31
|
-
static ID s_call;
|
32
|
-
|
33
|
-
#ifdef UNPACKER_STACK_RMEM
|
34
31
|
static msgpack_rmem_t s_stack_rmem;
|
35
|
-
#endif
|
36
32
|
|
37
|
-
|
33
|
+
#if !defined(HAVE_RB_HASH_NEW_CAPA)
|
34
|
+
static inline VALUE rb_hash_new_capa(long capa)
|
38
35
|
{
|
39
|
-
|
40
|
-
|
36
|
+
return rb_hash_new();
|
37
|
+
}
|
41
38
|
#endif
|
42
39
|
|
43
|
-
|
40
|
+
void msgpack_unpacker_static_init(void)
|
41
|
+
{
|
42
|
+
assert(sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE);
|
43
|
+
|
44
|
+
msgpack_rmem_init(&s_stack_rmem);
|
44
45
|
}
|
45
46
|
|
46
|
-
void msgpack_unpacker_static_destroy()
|
47
|
+
void msgpack_unpacker_static_destroy(void)
|
47
48
|
{
|
48
|
-
#ifdef UNPACKER_STACK_RMEM
|
49
49
|
msgpack_rmem_destroy(&s_stack_rmem);
|
50
|
-
#endif
|
51
50
|
}
|
52
51
|
|
53
52
|
#define HEAD_BYTE_REQUIRED 0xc1
|
54
53
|
|
54
|
+
static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
|
55
|
+
msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
|
56
|
+
stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
57
|
+
stack->data = msgpack_rmem_alloc(&s_stack_rmem);
|
58
|
+
/*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
|
59
|
+
return stack;
|
60
|
+
}
|
61
|
+
|
55
62
|
void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
56
63
|
{
|
57
|
-
memset(uk, 0, sizeof(msgpack_unpacker_t));
|
58
|
-
|
59
64
|
msgpack_buffer_init(UNPACKER_BUFFER_(uk));
|
60
65
|
|
61
66
|
uk->head_byte = HEAD_BYTE_REQUIRED;
|
@@ -63,42 +68,44 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
|
63
68
|
uk->last_object = Qnil;
|
64
69
|
uk->reading_raw = Qnil;
|
65
70
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
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);
|
74
79
|
}
|
75
80
|
|
76
81
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
|
77
82
|
{
|
78
|
-
|
79
|
-
msgpack_rmem_free(&s_stack_rmem, uk->stack);
|
80
|
-
#else
|
81
|
-
xfree(uk->stack);
|
82
|
-
#endif
|
83
|
-
|
83
|
+
_msgpack_unpacker_free_stack(uk->stack);
|
84
84
|
msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
|
85
85
|
}
|
86
86
|
|
87
|
+
void msgpack_unpacker_mark_stack(msgpack_unpacker_stack_t* stack)
|
88
|
+
{
|
89
|
+
while (stack) {
|
90
|
+
msgpack_unpacker_stack_entry_t* s = stack->data;
|
91
|
+
msgpack_unpacker_stack_entry_t* send = stack->data + stack->depth;
|
92
|
+
for(; s < send; s++) {
|
93
|
+
rb_gc_mark(s->object);
|
94
|
+
rb_gc_mark(s->key);
|
95
|
+
}
|
96
|
+
stack = stack->parent;
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
87
100
|
void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
|
88
101
|
{
|
89
102
|
rb_gc_mark(uk->last_object);
|
90
103
|
rb_gc_mark(uk->reading_raw);
|
91
|
-
|
92
|
-
msgpack_unpacker_stack_t* s = uk->stack;
|
93
|
-
msgpack_unpacker_stack_t* send = uk->stack + uk->stack_depth;
|
94
|
-
for(; s < send; s++) {
|
95
|
-
rb_gc_mark(s->object);
|
96
|
-
rb_gc_mark(s->key);
|
97
|
-
}
|
98
|
-
|
104
|
+
msgpack_unpacker_mark_stack(uk->stack);
|
99
105
|
/* See MessagePack_Buffer_wrap */
|
100
106
|
/* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
|
101
107
|
rb_gc_mark(uk->buffer_ref);
|
108
|
+
rb_gc_mark(uk->self);
|
102
109
|
}
|
103
110
|
|
104
111
|
void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
|
@@ -107,9 +114,8 @@ void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
|
|
107
114
|
|
108
115
|
uk->head_byte = HEAD_BYTE_REQUIRED;
|
109
116
|
|
110
|
-
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->
|
111
|
-
uk->
|
112
|
-
|
117
|
+
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack->depth);*/
|
118
|
+
uk->stack->depth = 0;
|
113
119
|
uk->last_object = Qnil;
|
114
120
|
uk->reading_raw = Qnil;
|
115
121
|
uk->reading_raw_remaining = 0;
|
@@ -142,41 +148,43 @@ static inline void reset_head_byte(msgpack_unpacker_t* uk)
|
|
142
148
|
|
143
149
|
static inline int object_complete(msgpack_unpacker_t* uk, VALUE object)
|
144
150
|
{
|
151
|
+
if(uk->freeze) {
|
152
|
+
rb_obj_freeze(object);
|
153
|
+
}
|
154
|
+
|
145
155
|
uk->last_object = object;
|
146
156
|
reset_head_byte(uk);
|
147
157
|
return PRIMITIVE_OBJECT_COMPLETE;
|
148
158
|
}
|
149
159
|
|
150
|
-
static inline int
|
151
|
-
{
|
152
|
-
#ifdef COMPAT_HAVE_ENCODING
|
153
|
-
ENCODING_SET(str, msgpack_rb_encindex_utf8);
|
154
|
-
#endif
|
155
|
-
return object_complete(uk, str);
|
156
|
-
}
|
157
|
-
|
158
|
-
static inline int object_complete_binary(msgpack_unpacker_t* uk, VALUE str)
|
160
|
+
static inline int object_complete_symbol(msgpack_unpacker_t* uk, VALUE object)
|
159
161
|
{
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
return object_complete(uk, str);
|
162
|
+
uk->last_object = object;
|
163
|
+
reset_head_byte(uk);
|
164
|
+
return PRIMITIVE_OBJECT_COMPLETE;
|
164
165
|
}
|
165
166
|
|
166
167
|
static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALUE str)
|
167
168
|
{
|
168
|
-
|
169
|
-
|
170
|
-
|
169
|
+
if (uk->optimized_symbol_ext_type && ext_type == uk->symbol_ext_type) {
|
170
|
+
if (RB_UNLIKELY(NIL_P(str))) { // empty extension is returned as Qnil
|
171
|
+
return object_complete_symbol(uk, ID2SYM(rb_intern3("", 0, rb_utf8_encoding())));
|
172
|
+
}
|
173
|
+
return object_complete_symbol(uk, rb_str_intern(str));
|
174
|
+
}
|
175
|
+
|
176
|
+
int ext_flags;
|
177
|
+
VALUE proc = msgpack_unpacker_ext_registry_lookup(uk->ext_registry, ext_type, &ext_flags);
|
171
178
|
|
172
|
-
VALUE proc = msgpack_unpacker_ext_registry_lookup(&uk->ext_registry, ext_type);
|
173
179
|
if(proc != Qnil) {
|
174
|
-
VALUE obj
|
180
|
+
VALUE obj;
|
181
|
+
VALUE arg = (str == Qnil ? rb_str_buf_new(0) : str);
|
182
|
+
obj = rb_proc_call_with_block(proc, 1, &arg, Qnil);
|
175
183
|
return object_complete(uk, obj);
|
176
184
|
}
|
177
185
|
|
178
186
|
if(uk->allow_unknown_ext) {
|
179
|
-
VALUE obj = MessagePack_ExtensionValue_new(ext_type, str);
|
187
|
+
VALUE obj = MessagePack_ExtensionValue_new(ext_type, str == Qnil ? rb_str_buf_new(0) : str);
|
180
188
|
return object_complete(uk, obj);
|
181
189
|
}
|
182
190
|
|
@@ -184,37 +192,37 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
184
192
|
}
|
185
193
|
|
186
194
|
/* stack funcs */
|
187
|
-
static inline
|
195
|
+
static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
|
188
196
|
{
|
189
|
-
return &uk->stack[uk->
|
197
|
+
return &uk->stack->data[uk->stack->depth-1];
|
190
198
|
}
|
191
199
|
|
192
200
|
static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
|
193
201
|
{
|
194
202
|
reset_head_byte(uk);
|
195
203
|
|
196
|
-
if(uk->
|
204
|
+
if(uk->stack->capacity - uk->stack->depth <= 0) {
|
197
205
|
return PRIMITIVE_STACK_TOO_DEEP;
|
198
206
|
}
|
199
207
|
|
200
|
-
|
208
|
+
msgpack_unpacker_stack_entry_t* next = &uk->stack->data[uk->stack->depth];
|
201
209
|
next->count = count;
|
202
210
|
next->type = type;
|
203
211
|
next->object = object;
|
204
212
|
next->key = Qnil;
|
205
213
|
|
206
|
-
uk->
|
214
|
+
uk->stack->depth++;
|
207
215
|
return PRIMITIVE_CONTAINER_START;
|
208
216
|
}
|
209
217
|
|
210
218
|
static inline VALUE msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
|
211
219
|
{
|
212
|
-
return --uk->
|
220
|
+
return --uk->stack->depth;
|
213
221
|
}
|
214
222
|
|
215
223
|
static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
216
224
|
{
|
217
|
-
return uk->
|
225
|
+
return uk->stack->depth == 0;
|
218
226
|
}
|
219
227
|
|
220
228
|
#ifdef USE_CASE_RANGE
|
@@ -242,8 +250,8 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
|
242
250
|
|
243
251
|
static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
|
244
252
|
{
|
245
|
-
if(uk->
|
246
|
-
|
253
|
+
if(uk->stack->depth > 0) {
|
254
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
247
255
|
if(top->type == STACK_TYPE_MAP_KEY) {
|
248
256
|
return true;
|
249
257
|
}
|
@@ -271,9 +279,10 @@ static int read_raw_body_cont(msgpack_unpacker_t* uk)
|
|
271
279
|
|
272
280
|
int ret;
|
273
281
|
if(uk->reading_raw_type == RAW_TYPE_STRING) {
|
274
|
-
|
275
|
-
|
276
|
-
|
282
|
+
ENCODING_SET(uk->reading_raw, msgpack_rb_encindex_utf8);
|
283
|
+
ret = object_complete(uk, uk->reading_raw);
|
284
|
+
} else if (uk->reading_raw_type == RAW_TYPE_BINARY) {
|
285
|
+
ret = object_complete(uk, uk->reading_raw);
|
277
286
|
} else {
|
278
287
|
ret = object_complete_ext(uk, uk->reading_raw_type, uk->reading_raw);
|
279
288
|
}
|
@@ -285,23 +294,49 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
285
294
|
{
|
286
295
|
/* assuming uk->reading_raw == Qnil */
|
287
296
|
|
297
|
+
int ext_flags;
|
298
|
+
VALUE proc;
|
299
|
+
|
300
|
+
if(!(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY)) {
|
301
|
+
proc = msgpack_unpacker_ext_registry_lookup(uk->ext_registry, raw_type, &ext_flags);
|
302
|
+
if(proc != Qnil && ext_flags & MSGPACK_EXT_RECURSIVE) {
|
303
|
+
VALUE obj;
|
304
|
+
uk->last_object = Qnil;
|
305
|
+
reset_head_byte(uk);
|
306
|
+
uk->reading_raw_remaining = 0;
|
307
|
+
|
308
|
+
msgpack_unpacker_stack_t* child_stack = _msgpack_unpacker_new_stack();
|
309
|
+
child_stack->parent = uk->stack;
|
310
|
+
uk->stack = child_stack;
|
311
|
+
|
312
|
+
obj = rb_proc_call_with_block(proc, 1, &uk->self, Qnil);
|
313
|
+
|
314
|
+
uk->stack = child_stack->parent;
|
315
|
+
_msgpack_unpacker_free_stack(child_stack);
|
316
|
+
|
317
|
+
return object_complete(uk, obj);
|
318
|
+
}
|
319
|
+
}
|
320
|
+
|
288
321
|
/* try optimized read */
|
289
322
|
size_t length = uk->reading_raw_remaining;
|
290
323
|
if(length <= msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk))) {
|
291
|
-
/* don't use zerocopy for hash keys but get a frozen string directly
|
292
|
-
* because rb_hash_aset freezes keys and it causes copying */
|
293
|
-
bool will_freeze = is_reading_map_key(uk);
|
294
|
-
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze);
|
295
324
|
int ret;
|
296
|
-
if(
|
297
|
-
|
298
|
-
|
299
|
-
ret = object_complete_binary(uk, string);
|
325
|
+
if ((uk->optimized_symbol_ext_type && uk->symbol_ext_type == raw_type) || (uk->symbolize_keys && is_reading_map_key(uk))) {
|
326
|
+
VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, raw_type != RAW_TYPE_BINARY);
|
327
|
+
ret = object_complete_symbol(uk, symbol);
|
300
328
|
} else {
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
329
|
+
bool will_freeze = uk->freeze;
|
330
|
+
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
|
+
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
|
335
|
+
ret = object_complete(uk, string);
|
336
|
+
} else {
|
337
|
+
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, false, false);
|
338
|
+
ret = object_complete_ext(uk, raw_type, string);
|
339
|
+
}
|
305
340
|
}
|
306
341
|
uk->reading_raw_remaining = 0;
|
307
342
|
return ret;
|
@@ -331,9 +366,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
331
366
|
|
332
367
|
SWITCH_RANGE(b, 0xa0, 0xbf) // FixRaw / fixstr
|
333
368
|
int count = b & 0x1f;
|
334
|
-
if(count == 0) {
|
335
|
-
return object_complete_string(uk, rb_str_buf_new(0));
|
336
|
-
}
|
337
369
|
/* read_raw_body_begin sets uk->reading_raw */
|
338
370
|
uk->reading_raw_remaining = count;
|
339
371
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -350,7 +382,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
350
382
|
if(count == 0) {
|
351
383
|
return object_complete(uk, rb_hash_new());
|
352
384
|
}
|
353
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
385
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
354
386
|
|
355
387
|
SWITCH_RANGE(b, 0xc0, 0xdf) // Variable
|
356
388
|
switch(b) {
|
@@ -371,7 +403,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
371
403
|
uint8_t length = cb->u8;
|
372
404
|
int ext_type = (signed char) cb->buffer[1];
|
373
405
|
if(length == 0) {
|
374
|
-
return object_complete_ext(uk, ext_type,
|
406
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
375
407
|
}
|
376
408
|
uk->reading_raw_remaining = length;
|
377
409
|
return read_raw_body_begin(uk, ext_type);
|
@@ -383,7 +415,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
383
415
|
uint16_t length = _msgpack_be16(cb->u16);
|
384
416
|
int ext_type = (signed char) cb->buffer[2];
|
385
417
|
if(length == 0) {
|
386
|
-
return object_complete_ext(uk, ext_type,
|
418
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
387
419
|
}
|
388
420
|
uk->reading_raw_remaining = length;
|
389
421
|
return read_raw_body_begin(uk, ext_type);
|
@@ -395,7 +427,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
395
427
|
uint32_t length = _msgpack_be32(cb->u32);
|
396
428
|
int ext_type = (signed char) cb->buffer[4];
|
397
429
|
if(length == 0) {
|
398
|
-
return object_complete_ext(uk, ext_type,
|
430
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
399
431
|
}
|
400
432
|
uk->reading_raw_remaining = length;
|
401
433
|
return read_raw_body_begin(uk, ext_type);
|
@@ -433,7 +465,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
433
465
|
{
|
434
466
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
435
467
|
uint32_t u32 = _msgpack_be32(cb->u32);
|
436
|
-
return object_complete(uk, ULONG2NUM(
|
468
|
+
return object_complete(uk, ULONG2NUM(u32)); // long at least 32 bits
|
437
469
|
}
|
438
470
|
|
439
471
|
case 0xcf: // unsigned int 64
|
@@ -461,7 +493,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
461
493
|
{
|
462
494
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
463
495
|
int32_t i32 = _msgpack_be32(cb->i32);
|
464
|
-
return object_complete(uk, LONG2NUM(
|
496
|
+
return object_complete(uk, LONG2NUM(i32)); // long at least 32 bits
|
465
497
|
}
|
466
498
|
|
467
499
|
case 0xd3: // signed int 64
|
@@ -516,9 +548,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
516
548
|
{
|
517
549
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
518
550
|
uint8_t count = cb->u8;
|
519
|
-
if(count == 0) {
|
520
|
-
return object_complete_string(uk, rb_str_buf_new(0));
|
521
|
-
}
|
522
551
|
/* read_raw_body_begin sets uk->reading_raw */
|
523
552
|
uk->reading_raw_remaining = count;
|
524
553
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -528,9 +557,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
528
557
|
{
|
529
558
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
530
559
|
uint16_t count = _msgpack_be16(cb->u16);
|
531
|
-
if(count == 0) {
|
532
|
-
return object_complete_string(uk, rb_str_buf_new(0));
|
533
|
-
}
|
534
560
|
/* read_raw_body_begin sets uk->reading_raw */
|
535
561
|
uk->reading_raw_remaining = count;
|
536
562
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -540,9 +566,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
540
566
|
{
|
541
567
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
542
568
|
uint32_t count = _msgpack_be32(cb->u32);
|
543
|
-
if(count == 0) {
|
544
|
-
return object_complete_string(uk, rb_str_buf_new(0));
|
545
|
-
}
|
546
569
|
/* read_raw_body_begin sets uk->reading_raw */
|
547
570
|
uk->reading_raw_remaining = count;
|
548
571
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -552,9 +575,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
552
575
|
{
|
553
576
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
554
577
|
uint8_t count = cb->u8;
|
555
|
-
if(count == 0) {
|
556
|
-
return object_complete_binary(uk, rb_str_buf_new(0));
|
557
|
-
}
|
558
578
|
/* read_raw_body_begin sets uk->reading_raw */
|
559
579
|
uk->reading_raw_remaining = count;
|
560
580
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -564,9 +584,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
564
584
|
{
|
565
585
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
566
586
|
uint16_t count = _msgpack_be16(cb->u16);
|
567
|
-
if(count == 0) {
|
568
|
-
return object_complete_binary(uk, rb_str_buf_new(0));
|
569
|
-
}
|
570
587
|
/* read_raw_body_begin sets uk->reading_raw */
|
571
588
|
uk->reading_raw_remaining = count;
|
572
589
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -576,9 +593,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
576
593
|
{
|
577
594
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
578
595
|
uint32_t count = _msgpack_be32(cb->u32);
|
579
|
-
if(count == 0) {
|
580
|
-
return object_complete_binary(uk, rb_str_buf_new(0));
|
581
|
-
}
|
582
596
|
/* read_raw_body_begin sets uk->reading_raw */
|
583
597
|
uk->reading_raw_remaining = count;
|
584
598
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -611,7 +625,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
611
625
|
if(count == 0) {
|
612
626
|
return object_complete(uk, rb_hash_new());
|
613
627
|
}
|
614
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
628
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
615
629
|
}
|
616
630
|
|
617
631
|
case 0xdf: // map 32
|
@@ -621,7 +635,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
621
635
|
if(count == 0) {
|
622
636
|
return object_complete(uk, rb_hash_new());
|
623
637
|
}
|
624
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
638
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
625
639
|
}
|
626
640
|
|
627
641
|
default:
|
@@ -708,7 +722,7 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
708
722
|
|
709
723
|
container_completed:
|
710
724
|
{
|
711
|
-
|
725
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
712
726
|
switch(top->type) {
|
713
727
|
case STACK_TYPE_ARRAY:
|
714
728
|
rb_ary_push(top->object, uk->last_object);
|
@@ -719,18 +733,8 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
719
733
|
break;
|
720
734
|
case STACK_TYPE_MAP_VALUE:
|
721
735
|
if(uk->symbolize_keys && rb_type(top->key) == T_STRING) {
|
722
|
-
/* here uses
|
723
|
-
#ifdef HAVE_RB_STR_INTERN
|
724
|
-
/* rb_str_intern is added since MRI 2.2.0 */
|
736
|
+
/* here uses rb_str_intern instead of rb_intern so that Ruby VM can GC unused symbols */
|
725
737
|
rb_hash_aset(top->object, rb_str_intern(top->key), uk->last_object);
|
726
|
-
#else
|
727
|
-
#ifndef HAVE_RB_INTERN_STR
|
728
|
-
/* MRI 1.8 doesn't have rb_intern_str or rb_intern2 */
|
729
|
-
rb_hash_aset(top->object, ID2SYM(rb_intern(RSTRING_PTR(top->key))), uk->last_object);
|
730
|
-
#else
|
731
|
-
rb_hash_aset(top->object, ID2SYM(rb_intern_str(top->key)), uk->last_object);
|
732
|
-
#endif
|
733
|
-
#endif
|
734
738
|
} else {
|
735
739
|
rb_hash_aset(top->object, top->key, uk->last_object);
|
736
740
|
}
|
@@ -768,7 +772,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
768
772
|
|
769
773
|
container_completed:
|
770
774
|
{
|
771
|
-
|
775
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
772
776
|
|
773
777
|
/* this section optimized out */
|
774
778
|
// TODO object_complete still creates objects which should be optimized out
|
data/ext/msgpack/unpacker.h
CHANGED
@@ -21,12 +21,11 @@
|
|
21
21
|
#include "buffer.h"
|
22
22
|
#include "unpacker_ext_registry.h"
|
23
23
|
|
24
|
-
#ifndef MSGPACK_UNPACKER_STACK_CAPACITY
|
25
24
|
#define MSGPACK_UNPACKER_STACK_CAPACITY 128
|
26
|
-
#endif
|
27
25
|
|
28
26
|
struct msgpack_unpacker_t;
|
29
27
|
typedef struct msgpack_unpacker_t msgpack_unpacker_t;
|
28
|
+
typedef struct msgpack_unpacker_stack_t msgpack_unpacker_stack_t;
|
30
29
|
|
31
30
|
enum stack_type_t {
|
32
31
|
STACK_TYPE_ARRAY,
|
@@ -39,19 +38,21 @@ typedef struct {
|
|
39
38
|
enum stack_type_t type;
|
40
39
|
VALUE object;
|
41
40
|
VALUE key;
|
42
|
-
}
|
41
|
+
} msgpack_unpacker_stack_entry_t;
|
43
42
|
|
44
|
-
|
43
|
+
struct msgpack_unpacker_stack_t {
|
44
|
+
size_t depth;
|
45
|
+
size_t capacity;
|
46
|
+
msgpack_unpacker_stack_entry_t *data;
|
47
|
+
msgpack_unpacker_stack_t *parent;
|
48
|
+
};
|
45
49
|
|
46
50
|
struct msgpack_unpacker_t {
|
47
51
|
msgpack_buffer_t buffer;
|
48
|
-
|
52
|
+
msgpack_unpacker_stack_t *stack;
|
49
53
|
unsigned int head_byte;
|
50
54
|
|
51
|
-
|
52
|
-
size_t stack_depth;
|
53
|
-
size_t stack_capacity;
|
54
|
-
|
55
|
+
VALUE self;
|
55
56
|
VALUE last_object;
|
56
57
|
|
57
58
|
VALUE reading_raw;
|
@@ -60,11 +61,14 @@ struct msgpack_unpacker_t {
|
|
60
61
|
|
61
62
|
VALUE buffer_ref;
|
62
63
|
|
63
|
-
msgpack_unpacker_ext_registry_t ext_registry;
|
64
|
+
msgpack_unpacker_ext_registry_t *ext_registry;
|
64
65
|
|
65
66
|
/* options */
|
66
67
|
bool symbolize_keys;
|
68
|
+
bool freeze;
|
67
69
|
bool allow_unknown_ext;
|
70
|
+
bool optimized_symbol_ext_type;
|
71
|
+
int symbol_ext_type;
|
68
72
|
};
|
69
73
|
|
70
74
|
#define UNPACKER_BUFFER_(uk) (&(uk)->buffer)
|
@@ -79,11 +83,11 @@ enum msgpack_unpacker_object_type {
|
|
79
83
|
TYPE_MAP,
|
80
84
|
};
|
81
85
|
|
82
|
-
void msgpack_unpacker_static_init();
|
86
|
+
void msgpack_unpacker_static_init(void);
|
83
87
|
|
84
|
-
void msgpack_unpacker_static_destroy();
|
88
|
+
void msgpack_unpacker_static_destroy(void);
|
85
89
|
|
86
|
-
void _msgpack_unpacker_init(msgpack_unpacker_t*
|
90
|
+
void _msgpack_unpacker_init(msgpack_unpacker_t*);
|
87
91
|
|
88
92
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk);
|
89
93
|
|
@@ -96,6 +100,11 @@ static inline void msgpack_unpacker_set_symbolized_keys(msgpack_unpacker_t* uk,
|
|
96
100
|
uk->symbolize_keys = enable;
|
97
101
|
}
|
98
102
|
|
103
|
+
static inline void msgpack_unpacker_set_freeze(msgpack_unpacker_t* uk, bool enable)
|
104
|
+
{
|
105
|
+
uk->freeze = enable;
|
106
|
+
}
|
107
|
+
|
99
108
|
static inline void msgpack_unpacker_set_allow_unknown_ext(msgpack_unpacker_t* uk, bool enable)
|
100
109
|
{
|
101
110
|
uk->allow_unknown_ext = enable;
|