msgpack 1.3.3 → 1.7.2
Sign up to get free protection for your applications and to get access to all the features.
- 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;
|