msgpack 1.4.2 → 1.7.3
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 +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
|
|