msgpack 1.4.2 → 1.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +89 -0
- data/README.md +73 -13
- data/ext/java/org/msgpack/jruby/Buffer.java +26 -19
- data/ext/java/org/msgpack/jruby/Decoder.java +29 -21
- 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 +80 -73
- data/ext/msgpack/buffer.c +54 -74
- data/ext/msgpack/buffer.h +21 -18
- data/ext/msgpack/buffer_class.c +161 -52
- data/ext/msgpack/buffer_class.h +1 -0
- data/ext/msgpack/compat.h +0 -99
- data/ext/msgpack/extconf.rb +25 -46
- data/ext/msgpack/factory_class.c +143 -87
- data/ext/msgpack/packer.c +66 -43
- data/ext/msgpack/packer.h +25 -20
- 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 +136 -111
- data/ext/msgpack/unpacker.h +16 -13
- data/ext/msgpack/unpacker_class.c +86 -126
- 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 +1 -1
- data/lib/msgpack.rb +6 -7
- data/msgpack.gemspec +8 -5
- metadata +37 -82
- data/.gitignore +0 -23
- data/.rubocop.yml +0 -36
- data/.travis.yml +0 -39
- data/Gemfile +0 -9
- data/Rakefile +0 -71
- 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 -55
- data/spec/timestamp_spec.rb +0 -121
- data/spec/unpack_spec.rb +0 -57
- data/spec/unpacker_spec.rb +0 -819
data/ext/msgpack/unpacker.c
CHANGED
@@ -19,43 +19,55 @@
|
|
19
19
|
#include "unpacker.h"
|
20
20
|
#include "rmem.h"
|
21
21
|
#include "extension_value_class.h"
|
22
|
+
#include <assert.h>
|
23
|
+
#include <limits.h>
|
22
24
|
|
23
|
-
#if !defined(
|
24
|
-
|
25
|
-
#define UNPACKER_STACK_RMEM
|
25
|
+
#if !defined(HAVE_RB_PROC_CALL_WITH_BLOCK)
|
26
|
+
#define rb_proc_call_with_block(recv, argc, argv, block) rb_funcallv(recv, rb_intern("call"), argc, argv)
|
26
27
|
#endif
|
27
28
|
|
28
29
|
static int RAW_TYPE_STRING = 256;
|
29
30
|
static int RAW_TYPE_BINARY = 257;
|
31
|
+
static int16_t INITIAL_BUFFER_CAPACITY_MAX = SHRT_MAX;
|
30
32
|
|
31
|
-
static ID s_call;
|
32
|
-
|
33
|
-
#ifdef UNPACKER_STACK_RMEM
|
34
33
|
static msgpack_rmem_t s_stack_rmem;
|
35
|
-
#endif
|
36
34
|
|
37
|
-
|
35
|
+
#if !defined(HAVE_RB_HASH_NEW_CAPA)
|
36
|
+
static inline VALUE rb_hash_new_capa(long capa)
|
38
37
|
{
|
39
|
-
|
40
|
-
|
38
|
+
return rb_hash_new();
|
39
|
+
}
|
41
40
|
#endif
|
42
41
|
|
43
|
-
|
42
|
+
static inline int16_t initial_buffer_size(long size)
|
43
|
+
{
|
44
|
+
return (size > INITIAL_BUFFER_CAPACITY_MAX) ? INITIAL_BUFFER_CAPACITY_MAX : size;
|
45
|
+
}
|
46
|
+
|
47
|
+
void msgpack_unpacker_static_init(void)
|
48
|
+
{
|
49
|
+
assert(sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE);
|
50
|
+
|
51
|
+
msgpack_rmem_init(&s_stack_rmem);
|
44
52
|
}
|
45
53
|
|
46
|
-
void msgpack_unpacker_static_destroy()
|
54
|
+
void msgpack_unpacker_static_destroy(void)
|
47
55
|
{
|
48
|
-
#ifdef UNPACKER_STACK_RMEM
|
49
56
|
msgpack_rmem_destroy(&s_stack_rmem);
|
50
|
-
#endif
|
51
57
|
}
|
52
58
|
|
53
59
|
#define HEAD_BYTE_REQUIRED 0xc1
|
54
60
|
|
61
|
+
static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
|
62
|
+
msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
|
63
|
+
stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
64
|
+
stack->data = msgpack_rmem_alloc(&s_stack_rmem);
|
65
|
+
/*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
|
66
|
+
return stack;
|
67
|
+
}
|
68
|
+
|
55
69
|
void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
56
70
|
{
|
57
|
-
memset(uk, 0, sizeof(msgpack_unpacker_t));
|
58
|
-
|
59
71
|
msgpack_buffer_init(UNPACKER_BUFFER_(uk));
|
60
72
|
|
61
73
|
uk->head_byte = HEAD_BYTE_REQUIRED;
|
@@ -63,42 +75,44 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
|
63
75
|
uk->last_object = Qnil;
|
64
76
|
uk->reading_raw = Qnil;
|
65
77
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
78
|
+
uk->stack = _msgpack_unpacker_new_stack();
|
79
|
+
}
|
80
|
+
|
81
|
+
static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
|
82
|
+
if (!msgpack_rmem_free(&s_stack_rmem, stack->data)) {
|
83
|
+
rb_bug("Failed to free an rmem pointer, memory leak?");
|
84
|
+
}
|
85
|
+
xfree(stack);
|
74
86
|
}
|
75
87
|
|
76
88
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
|
77
89
|
{
|
78
|
-
|
79
|
-
msgpack_rmem_free(&s_stack_rmem, uk->stack);
|
80
|
-
#else
|
81
|
-
xfree(uk->stack);
|
82
|
-
#endif
|
83
|
-
|
90
|
+
_msgpack_unpacker_free_stack(uk->stack);
|
84
91
|
msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
|
85
92
|
}
|
86
93
|
|
94
|
+
void msgpack_unpacker_mark_stack(msgpack_unpacker_stack_t* stack)
|
95
|
+
{
|
96
|
+
while (stack) {
|
97
|
+
msgpack_unpacker_stack_entry_t* s = stack->data;
|
98
|
+
msgpack_unpacker_stack_entry_t* send = stack->data + stack->depth;
|
99
|
+
for(; s < send; s++) {
|
100
|
+
rb_gc_mark(s->object);
|
101
|
+
rb_gc_mark(s->key);
|
102
|
+
}
|
103
|
+
stack = stack->parent;
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
87
107
|
void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
|
88
108
|
{
|
89
109
|
rb_gc_mark(uk->last_object);
|
90
110
|
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
|
-
|
111
|
+
msgpack_unpacker_mark_stack(uk->stack);
|
99
112
|
/* See MessagePack_Buffer_wrap */
|
100
113
|
/* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
|
101
114
|
rb_gc_mark(uk->buffer_ref);
|
115
|
+
rb_gc_mark(uk->self);
|
102
116
|
}
|
103
117
|
|
104
118
|
void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
|
@@ -107,9 +121,8 @@ void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
|
|
107
121
|
|
108
122
|
uk->head_byte = HEAD_BYTE_REQUIRED;
|
109
123
|
|
110
|
-
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->
|
111
|
-
uk->
|
112
|
-
|
124
|
+
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack->depth);*/
|
125
|
+
uk->stack->depth = 0;
|
113
126
|
uk->last_object = Qnil;
|
114
127
|
uk->reading_raw = Qnil;
|
115
128
|
uk->reading_raw_remaining = 0;
|
@@ -151,16 +164,34 @@ static inline int object_complete(msgpack_unpacker_t* uk, VALUE object)
|
|
151
164
|
return PRIMITIVE_OBJECT_COMPLETE;
|
152
165
|
}
|
153
166
|
|
167
|
+
static inline int object_complete_symbol(msgpack_unpacker_t* uk, VALUE object)
|
168
|
+
{
|
169
|
+
uk->last_object = object;
|
170
|
+
reset_head_byte(uk);
|
171
|
+
return PRIMITIVE_OBJECT_COMPLETE;
|
172
|
+
}
|
173
|
+
|
154
174
|
static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALUE str)
|
155
175
|
{
|
156
|
-
|
176
|
+
if (uk->optimized_symbol_ext_type && ext_type == uk->symbol_ext_type) {
|
177
|
+
if (RB_UNLIKELY(NIL_P(str))) { // empty extension is returned as Qnil
|
178
|
+
return object_complete_symbol(uk, ID2SYM(rb_intern3("", 0, rb_utf8_encoding())));
|
179
|
+
}
|
180
|
+
return object_complete_symbol(uk, rb_str_intern(str));
|
181
|
+
}
|
182
|
+
|
183
|
+
int ext_flags;
|
184
|
+
VALUE proc = msgpack_unpacker_ext_registry_lookup(uk->ext_registry, ext_type, &ext_flags);
|
185
|
+
|
157
186
|
if(proc != Qnil) {
|
158
|
-
VALUE obj
|
187
|
+
VALUE obj;
|
188
|
+
VALUE arg = (str == Qnil ? rb_str_buf_new(0) : str);
|
189
|
+
obj = rb_proc_call_with_block(proc, 1, &arg, Qnil);
|
159
190
|
return object_complete(uk, obj);
|
160
191
|
}
|
161
192
|
|
162
193
|
if(uk->allow_unknown_ext) {
|
163
|
-
VALUE obj = MessagePack_ExtensionValue_new(ext_type, str);
|
194
|
+
VALUE obj = MessagePack_ExtensionValue_new(ext_type, str == Qnil ? rb_str_buf_new(0) : str);
|
164
195
|
return object_complete(uk, obj);
|
165
196
|
}
|
166
197
|
|
@@ -168,37 +199,37 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
168
199
|
}
|
169
200
|
|
170
201
|
/* stack funcs */
|
171
|
-
static inline
|
202
|
+
static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
|
172
203
|
{
|
173
|
-
return &uk->stack[uk->
|
204
|
+
return &uk->stack->data[uk->stack->depth-1];
|
174
205
|
}
|
175
206
|
|
176
207
|
static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
|
177
208
|
{
|
178
209
|
reset_head_byte(uk);
|
179
210
|
|
180
|
-
if(uk->
|
211
|
+
if(uk->stack->capacity - uk->stack->depth <= 0) {
|
181
212
|
return PRIMITIVE_STACK_TOO_DEEP;
|
182
213
|
}
|
183
214
|
|
184
|
-
|
215
|
+
msgpack_unpacker_stack_entry_t* next = &uk->stack->data[uk->stack->depth];
|
185
216
|
next->count = count;
|
186
217
|
next->type = type;
|
187
218
|
next->object = object;
|
188
219
|
next->key = Qnil;
|
189
220
|
|
190
|
-
uk->
|
221
|
+
uk->stack->depth++;
|
191
222
|
return PRIMITIVE_CONTAINER_START;
|
192
223
|
}
|
193
224
|
|
194
225
|
static inline VALUE msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
|
195
226
|
{
|
196
|
-
return --uk->
|
227
|
+
return --uk->stack->depth;
|
197
228
|
}
|
198
229
|
|
199
230
|
static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
200
231
|
{
|
201
|
-
return uk->
|
232
|
+
return uk->stack->depth == 0;
|
202
233
|
}
|
203
234
|
|
204
235
|
#ifdef USE_CASE_RANGE
|
@@ -226,8 +257,8 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
|
226
257
|
|
227
258
|
static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
|
228
259
|
{
|
229
|
-
if(uk->
|
230
|
-
|
260
|
+
if(uk->stack->depth > 0) {
|
261
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
231
262
|
if(top->type == STACK_TYPE_MAP_KEY) {
|
232
263
|
return true;
|
233
264
|
}
|
@@ -270,25 +301,50 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
270
301
|
{
|
271
302
|
/* assuming uk->reading_raw == Qnil */
|
272
303
|
|
304
|
+
int ext_flags;
|
305
|
+
VALUE proc;
|
306
|
+
|
307
|
+
if(!(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY)) {
|
308
|
+
proc = msgpack_unpacker_ext_registry_lookup(uk->ext_registry, raw_type, &ext_flags);
|
309
|
+
if(proc != Qnil && ext_flags & MSGPACK_EXT_RECURSIVE) {
|
310
|
+
VALUE obj;
|
311
|
+
uk->last_object = Qnil;
|
312
|
+
reset_head_byte(uk);
|
313
|
+
uk->reading_raw_remaining = 0;
|
314
|
+
|
315
|
+
msgpack_unpacker_stack_t* child_stack = _msgpack_unpacker_new_stack();
|
316
|
+
child_stack->parent = uk->stack;
|
317
|
+
uk->stack = child_stack;
|
318
|
+
|
319
|
+
obj = rb_proc_call_with_block(proc, 1, &uk->self, Qnil);
|
320
|
+
|
321
|
+
uk->stack = child_stack->parent;
|
322
|
+
_msgpack_unpacker_free_stack(child_stack);
|
323
|
+
|
324
|
+
return object_complete(uk, obj);
|
325
|
+
}
|
326
|
+
}
|
327
|
+
|
273
328
|
/* try optimized read */
|
274
329
|
size_t length = uk->reading_raw_remaining;
|
275
330
|
if(length <= msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk))) {
|
276
|
-
/* don't use zerocopy for hash keys but get a frozen string directly
|
277
|
-
* because rb_hash_aset freezes keys and it causes copying */
|
278
|
-
bool will_freeze = uk->freeze || is_reading_map_key(uk);
|
279
|
-
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
|
280
331
|
int ret;
|
281
|
-
if(
|
282
|
-
|
332
|
+
if ((uk->optimized_symbol_ext_type && uk->symbol_ext_type == raw_type) || (uk->symbolize_keys && is_reading_map_key(uk))) {
|
333
|
+
VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, raw_type != RAW_TYPE_BINARY);
|
334
|
+
ret = object_complete_symbol(uk, symbol);
|
283
335
|
} else {
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
336
|
+
bool will_freeze = uk->freeze;
|
337
|
+
if(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY) {
|
338
|
+
/* don't use zerocopy for hash keys but get a frozen string directly
|
339
|
+
* because rb_hash_aset freezes keys and it causes copying */
|
340
|
+
will_freeze = will_freeze || is_reading_map_key(uk);
|
341
|
+
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
|
342
|
+
ret = object_complete(uk, string);
|
343
|
+
} else {
|
344
|
+
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, false, false);
|
345
|
+
ret = object_complete_ext(uk, raw_type, string);
|
346
|
+
}
|
290
347
|
}
|
291
|
-
# endif
|
292
348
|
uk->reading_raw_remaining = 0;
|
293
349
|
return ret;
|
294
350
|
}
|
@@ -317,9 +373,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
317
373
|
|
318
374
|
SWITCH_RANGE(b, 0xa0, 0xbf) // FixRaw / fixstr
|
319
375
|
int count = b & 0x1f;
|
320
|
-
if(count == 0) {
|
321
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
322
|
-
}
|
323
376
|
/* read_raw_body_begin sets uk->reading_raw */
|
324
377
|
uk->reading_raw_remaining = count;
|
325
378
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -329,14 +382,14 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
329
382
|
if(count == 0) {
|
330
383
|
return object_complete(uk, rb_ary_new());
|
331
384
|
}
|
332
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
|
385
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
|
333
386
|
|
334
387
|
SWITCH_RANGE(b, 0x80, 0x8f) // FixMap
|
335
388
|
int count = b & 0x0f;
|
336
389
|
if(count == 0) {
|
337
390
|
return object_complete(uk, rb_hash_new());
|
338
391
|
}
|
339
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
392
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
|
340
393
|
|
341
394
|
SWITCH_RANGE(b, 0xc0, 0xdf) // Variable
|
342
395
|
switch(b) {
|
@@ -357,7 +410,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
357
410
|
uint8_t length = cb->u8;
|
358
411
|
int ext_type = (signed char) cb->buffer[1];
|
359
412
|
if(length == 0) {
|
360
|
-
return object_complete_ext(uk, ext_type,
|
413
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
361
414
|
}
|
362
415
|
uk->reading_raw_remaining = length;
|
363
416
|
return read_raw_body_begin(uk, ext_type);
|
@@ -369,7 +422,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
369
422
|
uint16_t length = _msgpack_be16(cb->u16);
|
370
423
|
int ext_type = (signed char) cb->buffer[2];
|
371
424
|
if(length == 0) {
|
372
|
-
return object_complete_ext(uk, ext_type,
|
425
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
373
426
|
}
|
374
427
|
uk->reading_raw_remaining = length;
|
375
428
|
return read_raw_body_begin(uk, ext_type);
|
@@ -381,7 +434,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
381
434
|
uint32_t length = _msgpack_be32(cb->u32);
|
382
435
|
int ext_type = (signed char) cb->buffer[4];
|
383
436
|
if(length == 0) {
|
384
|
-
return object_complete_ext(uk, ext_type,
|
437
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
385
438
|
}
|
386
439
|
uk->reading_raw_remaining = length;
|
387
440
|
return read_raw_body_begin(uk, ext_type);
|
@@ -419,7 +472,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
419
472
|
{
|
420
473
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
421
474
|
uint32_t u32 = _msgpack_be32(cb->u32);
|
422
|
-
return object_complete(uk, ULONG2NUM(
|
475
|
+
return object_complete(uk, ULONG2NUM(u32)); // long at least 32 bits
|
423
476
|
}
|
424
477
|
|
425
478
|
case 0xcf: // unsigned int 64
|
@@ -447,7 +500,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
447
500
|
{
|
448
501
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
449
502
|
int32_t i32 = _msgpack_be32(cb->i32);
|
450
|
-
return object_complete(uk, LONG2NUM(
|
503
|
+
return object_complete(uk, LONG2NUM(i32)); // long at least 32 bits
|
451
504
|
}
|
452
505
|
|
453
506
|
case 0xd3: // signed int 64
|
@@ -502,9 +555,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
502
555
|
{
|
503
556
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
504
557
|
uint8_t count = cb->u8;
|
505
|
-
if(count == 0) {
|
506
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
507
|
-
}
|
508
558
|
/* read_raw_body_begin sets uk->reading_raw */
|
509
559
|
uk->reading_raw_remaining = count;
|
510
560
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -514,9 +564,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
514
564
|
{
|
515
565
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
516
566
|
uint16_t count = _msgpack_be16(cb->u16);
|
517
|
-
if(count == 0) {
|
518
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
519
|
-
}
|
520
567
|
/* read_raw_body_begin sets uk->reading_raw */
|
521
568
|
uk->reading_raw_remaining = count;
|
522
569
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -526,9 +573,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
526
573
|
{
|
527
574
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
528
575
|
uint32_t count = _msgpack_be32(cb->u32);
|
529
|
-
if(count == 0) {
|
530
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
531
|
-
}
|
532
576
|
/* read_raw_body_begin sets uk->reading_raw */
|
533
577
|
uk->reading_raw_remaining = count;
|
534
578
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -538,9 +582,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
538
582
|
{
|
539
583
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
540
584
|
uint8_t count = cb->u8;
|
541
|
-
if(count == 0) {
|
542
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
543
|
-
}
|
544
585
|
/* read_raw_body_begin sets uk->reading_raw */
|
545
586
|
uk->reading_raw_remaining = count;
|
546
587
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -550,9 +591,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
550
591
|
{
|
551
592
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
552
593
|
uint16_t count = _msgpack_be16(cb->u16);
|
553
|
-
if(count == 0) {
|
554
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
555
|
-
}
|
556
594
|
/* read_raw_body_begin sets uk->reading_raw */
|
557
595
|
uk->reading_raw_remaining = count;
|
558
596
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -562,9 +600,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
562
600
|
{
|
563
601
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
564
602
|
uint32_t count = _msgpack_be32(cb->u32);
|
565
|
-
if(count == 0) {
|
566
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
567
|
-
}
|
568
603
|
/* read_raw_body_begin sets uk->reading_raw */
|
569
604
|
uk->reading_raw_remaining = count;
|
570
605
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -577,7 +612,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
577
612
|
if(count == 0) {
|
578
613
|
return object_complete(uk, rb_ary_new());
|
579
614
|
}
|
580
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
|
615
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
|
581
616
|
}
|
582
617
|
|
583
618
|
case 0xdd: // array 32
|
@@ -587,7 +622,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
587
622
|
if(count == 0) {
|
588
623
|
return object_complete(uk, rb_ary_new());
|
589
624
|
}
|
590
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
|
625
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
|
591
626
|
}
|
592
627
|
|
593
628
|
case 0xde: // map 16
|
@@ -597,7 +632,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
597
632
|
if(count == 0) {
|
598
633
|
return object_complete(uk, rb_hash_new());
|
599
634
|
}
|
600
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
635
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
|
601
636
|
}
|
602
637
|
|
603
638
|
case 0xdf: // map 32
|
@@ -607,7 +642,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
607
642
|
if(count == 0) {
|
608
643
|
return object_complete(uk, rb_hash_new());
|
609
644
|
}
|
610
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
645
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
|
611
646
|
}
|
612
647
|
|
613
648
|
default:
|
@@ -694,7 +729,7 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
694
729
|
|
695
730
|
container_completed:
|
696
731
|
{
|
697
|
-
|
732
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
698
733
|
switch(top->type) {
|
699
734
|
case STACK_TYPE_ARRAY:
|
700
735
|
rb_ary_push(top->object, uk->last_object);
|
@@ -705,18 +740,8 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
705
740
|
break;
|
706
741
|
case STACK_TYPE_MAP_VALUE:
|
707
742
|
if(uk->symbolize_keys && rb_type(top->key) == T_STRING) {
|
708
|
-
/* here uses
|
709
|
-
#ifdef HAVE_RB_STR_INTERN
|
710
|
-
/* rb_str_intern is added since MRI 2.2.0 */
|
743
|
+
/* here uses rb_str_intern instead of rb_intern so that Ruby VM can GC unused symbols */
|
711
744
|
rb_hash_aset(top->object, rb_str_intern(top->key), uk->last_object);
|
712
|
-
#else
|
713
|
-
#ifndef HAVE_RB_INTERN_STR
|
714
|
-
/* MRI 1.8 doesn't have rb_intern_str or rb_intern2 */
|
715
|
-
rb_hash_aset(top->object, ID2SYM(rb_intern(RSTRING_PTR(top->key))), uk->last_object);
|
716
|
-
#else
|
717
|
-
rb_hash_aset(top->object, ID2SYM(rb_intern_str(top->key)), uk->last_object);
|
718
|
-
#endif
|
719
|
-
#endif
|
720
745
|
} else {
|
721
746
|
rb_hash_aset(top->object, top->key, uk->last_object);
|
722
747
|
}
|
@@ -754,7 +779,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
754
779
|
|
755
780
|
container_completed:
|
756
781
|
{
|
757
|
-
|
782
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
758
783
|
|
759
784
|
/* this section optimized out */
|
760
785
|
// 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,12 +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;
|
67
68
|
bool freeze;
|
68
69
|
bool allow_unknown_ext;
|
70
|
+
bool optimized_symbol_ext_type;
|
71
|
+
int symbol_ext_type;
|
69
72
|
};
|
70
73
|
|
71
74
|
#define UNPACKER_BUFFER_(uk) (&(uk)->buffer)
|
@@ -80,11 +83,11 @@ enum msgpack_unpacker_object_type {
|
|
80
83
|
TYPE_MAP,
|
81
84
|
};
|
82
85
|
|
83
|
-
void msgpack_unpacker_static_init();
|
86
|
+
void msgpack_unpacker_static_init(void);
|
84
87
|
|
85
|
-
void msgpack_unpacker_static_destroy();
|
88
|
+
void msgpack_unpacker_static_destroy(void);
|
86
89
|
|
87
|
-
void _msgpack_unpacker_init(msgpack_unpacker_t*
|
90
|
+
void _msgpack_unpacker_init(msgpack_unpacker_t*);
|
88
91
|
|
89
92
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk);
|
90
93
|
|