msgpack 1.4.2 → 1.6.0
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/.github/workflows/ci.yaml +57 -0
- data/ChangeLog +60 -0
- data/README.md +25 -1
- data/Rakefile +1 -2
- data/bench/bench.rb +78 -0
- data/bin/console +8 -0
- data/doclib/msgpack/factory.rb +47 -3
- data/doclib/msgpack/packer.rb +5 -4
- data/doclib/msgpack/unpacker.rb +2 -2
- data/ext/java/org/msgpack/jruby/Buffer.java +23 -16
- 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 +37 -49
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +5 -8
- data/ext/java/org/msgpack/jruby/Factory.java +47 -7
- data/ext/java/org/msgpack/jruby/Packer.java +29 -17
- data/ext/java/org/msgpack/jruby/Unpacker.java +66 -42
- data/ext/msgpack/buffer.c +38 -57
- data/ext/msgpack/buffer.h +19 -10
- data/ext/msgpack/buffer_class.c +90 -52
- data/ext/msgpack/compat.h +0 -99
- data/ext/msgpack/extconf.rb +9 -22
- data/ext/msgpack/factory_class.c +133 -43
- data/ext/msgpack/packer.c +60 -36
- data/ext/msgpack/packer.h +27 -18
- data/ext/msgpack/packer_class.c +84 -77
- data/ext/msgpack/packer_class.h +11 -0
- data/ext/msgpack/packer_ext_registry.c +24 -32
- data/ext/msgpack/packer_ext_registry.h +40 -33
- data/ext/msgpack/sysdep.h +5 -2
- data/ext/msgpack/unpacker.c +128 -97
- data/ext/msgpack/unpacker.h +17 -10
- data/ext/msgpack/unpacker_class.c +75 -80
- data/ext/msgpack/unpacker_class.h +11 -0
- data/ext/msgpack/unpacker_ext_registry.c +42 -18
- data/ext/msgpack/unpacker_ext_registry.h +23 -16
- data/lib/msgpack/bigint.rb +69 -0
- data/lib/msgpack/factory.rb +103 -0
- data/lib/msgpack/symbol.rb +21 -4
- data/lib/msgpack/time.rb +1 -1
- data/lib/msgpack/version.rb +1 -1
- data/lib/msgpack.rb +5 -7
- data/msgpack.gemspec +2 -2
- data/spec/bigint_spec.rb +26 -0
- data/spec/cruby/buffer_spec.rb +17 -0
- data/spec/factory_spec.rb +351 -12
- data/spec/msgpack_spec.rb +1 -1
- data/spec/packer_spec.rb +18 -0
- data/spec/spec_helper.rb +20 -3
- data/spec/timestamp_spec.rb +38 -0
- data/spec/unpacker_spec.rb +54 -4
- metadata +25 -41
- data/.travis.yml +0 -39
- 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/ext/msgpack/unpacker.c
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
#include "rmem.h"
|
21
21
|
#include "extension_value_class.h"
|
22
22
|
|
23
|
-
#if !defined(
|
23
|
+
#if !defined(DISABLE_UNPACKER_STACK_RMEM) && \
|
24
24
|
MSGPACK_UNPACKER_STACK_CAPACITY * MSGPACK_UNPACKER_STACK_SIZE <= MSGPACK_RMEM_PAGE_SIZE
|
25
25
|
#define UNPACKER_STACK_RMEM
|
26
26
|
#endif
|
@@ -34,7 +34,14 @@ static ID s_call;
|
|
34
34
|
static msgpack_rmem_t s_stack_rmem;
|
35
35
|
#endif
|
36
36
|
|
37
|
-
|
37
|
+
#if !defined(HAVE_RB_HASH_NEW_CAPA)
|
38
|
+
static inline VALUE rb_hash_new_capa(long capa)
|
39
|
+
{
|
40
|
+
return rb_hash_new();
|
41
|
+
}
|
42
|
+
#endif
|
43
|
+
|
44
|
+
void msgpack_unpacker_static_init(void)
|
38
45
|
{
|
39
46
|
#ifdef UNPACKER_STACK_RMEM
|
40
47
|
msgpack_rmem_init(&s_stack_rmem);
|
@@ -43,7 +50,7 @@ void msgpack_unpacker_static_init()
|
|
43
50
|
s_call = rb_intern("call");
|
44
51
|
}
|
45
52
|
|
46
|
-
void msgpack_unpacker_static_destroy()
|
53
|
+
void msgpack_unpacker_static_destroy(void)
|
47
54
|
{
|
48
55
|
#ifdef UNPACKER_STACK_RMEM
|
49
56
|
msgpack_rmem_destroy(&s_stack_rmem);
|
@@ -52,10 +59,21 @@ void msgpack_unpacker_static_destroy()
|
|
52
59
|
|
53
60
|
#define HEAD_BYTE_REQUIRED 0xc1
|
54
61
|
|
62
|
+
static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
|
63
|
+
msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
|
64
|
+
stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
65
|
+
#ifdef UNPACKER_STACK_RMEM
|
66
|
+
stack->data = msgpack_rmem_alloc(&s_stack_rmem);
|
67
|
+
/*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
|
68
|
+
#else
|
69
|
+
/*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_entry_t));*/
|
70
|
+
stack->data = xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_entry_t));
|
71
|
+
#endif
|
72
|
+
return stack;
|
73
|
+
}
|
74
|
+
|
55
75
|
void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
56
76
|
{
|
57
|
-
memset(uk, 0, sizeof(msgpack_unpacker_t));
|
58
|
-
|
59
77
|
msgpack_buffer_init(UNPACKER_BUFFER_(uk));
|
60
78
|
|
61
79
|
uk->head_byte = HEAD_BYTE_REQUIRED;
|
@@ -63,39 +81,42 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
|
63
81
|
uk->last_object = Qnil;
|
64
82
|
uk->reading_raw = Qnil;
|
65
83
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
#
|
73
|
-
|
84
|
+
uk->stack = _msgpack_unpacker_new_stack();
|
85
|
+
}
|
86
|
+
|
87
|
+
static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
|
88
|
+
#ifdef UNPACKER_STACK_RMEM
|
89
|
+
msgpack_rmem_free(&s_stack_rmem, stack->data);
|
90
|
+
#else
|
91
|
+
xfree(stack->data);
|
92
|
+
#endif
|
93
|
+
xfree(stack);
|
74
94
|
}
|
75
95
|
|
76
96
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
|
77
97
|
{
|
78
|
-
|
79
|
-
msgpack_rmem_free(&s_stack_rmem, uk->stack);
|
80
|
-
#else
|
81
|
-
xfree(uk->stack);
|
82
|
-
#endif
|
83
|
-
|
98
|
+
_msgpack_unpacker_free_stack(uk->stack);
|
84
99
|
msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
|
85
100
|
}
|
86
101
|
|
102
|
+
void msgpack_unpacker_mark_stack(msgpack_unpacker_stack_t* stack)
|
103
|
+
{
|
104
|
+
while (stack) {
|
105
|
+
msgpack_unpacker_stack_entry_t* s = stack->data;
|
106
|
+
msgpack_unpacker_stack_entry_t* send = stack->data + stack->depth;
|
107
|
+
for(; s < send; s++) {
|
108
|
+
rb_gc_mark(s->object);
|
109
|
+
rb_gc_mark(s->key);
|
110
|
+
}
|
111
|
+
stack = stack->parent;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
87
115
|
void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
|
88
116
|
{
|
89
117
|
rb_gc_mark(uk->last_object);
|
90
118
|
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
|
-
|
119
|
+
msgpack_unpacker_mark_stack(uk->stack);
|
99
120
|
/* See MessagePack_Buffer_wrap */
|
100
121
|
/* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
|
101
122
|
rb_gc_mark(uk->buffer_ref);
|
@@ -107,9 +128,8 @@ void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
|
|
107
128
|
|
108
129
|
uk->head_byte = HEAD_BYTE_REQUIRED;
|
109
130
|
|
110
|
-
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->
|
111
|
-
uk->
|
112
|
-
|
131
|
+
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack->depth);*/
|
132
|
+
uk->stack->depth = 0;
|
113
133
|
uk->last_object = Qnil;
|
114
134
|
uk->reading_raw = Qnil;
|
115
135
|
uk->reading_raw_remaining = 0;
|
@@ -151,16 +171,33 @@ static inline int object_complete(msgpack_unpacker_t* uk, VALUE object)
|
|
151
171
|
return PRIMITIVE_OBJECT_COMPLETE;
|
152
172
|
}
|
153
173
|
|
174
|
+
static inline int object_complete_symbol(msgpack_unpacker_t* uk, VALUE object)
|
175
|
+
{
|
176
|
+
uk->last_object = object;
|
177
|
+
reset_head_byte(uk);
|
178
|
+
return PRIMITIVE_OBJECT_COMPLETE;
|
179
|
+
}
|
180
|
+
|
154
181
|
static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALUE str)
|
155
182
|
{
|
156
|
-
|
183
|
+
if (uk->optimized_symbol_ext_type && ext_type == uk->symbol_ext_type) {
|
184
|
+
if (RB_UNLIKELY(NIL_P(str))) { // empty extension is returned as Qnil
|
185
|
+
return object_complete_symbol(uk, ID2SYM(rb_intern3("", 0, rb_utf8_encoding())));
|
186
|
+
}
|
187
|
+
return object_complete_symbol(uk, rb_str_intern(str));
|
188
|
+
}
|
189
|
+
|
190
|
+
int ext_flags;
|
191
|
+
VALUE proc = msgpack_unpacker_ext_registry_lookup(uk->ext_registry, ext_type, &ext_flags);
|
192
|
+
|
157
193
|
if(proc != Qnil) {
|
158
|
-
VALUE obj
|
194
|
+
VALUE obj;
|
195
|
+
obj = rb_funcall(proc, s_call, 1, str == Qnil ? rb_str_buf_new(0) : str);
|
159
196
|
return object_complete(uk, obj);
|
160
197
|
}
|
161
198
|
|
162
199
|
if(uk->allow_unknown_ext) {
|
163
|
-
VALUE obj = MessagePack_ExtensionValue_new(ext_type, str);
|
200
|
+
VALUE obj = MessagePack_ExtensionValue_new(ext_type, str == Qnil ? rb_str_buf_new(0) : str);
|
164
201
|
return object_complete(uk, obj);
|
165
202
|
}
|
166
203
|
|
@@ -168,37 +205,37 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
168
205
|
}
|
169
206
|
|
170
207
|
/* stack funcs */
|
171
|
-
static inline
|
208
|
+
static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
|
172
209
|
{
|
173
|
-
return &uk->stack[uk->
|
210
|
+
return &uk->stack->data[uk->stack->depth-1];
|
174
211
|
}
|
175
212
|
|
176
213
|
static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
|
177
214
|
{
|
178
215
|
reset_head_byte(uk);
|
179
216
|
|
180
|
-
if(uk->
|
217
|
+
if(uk->stack->capacity - uk->stack->depth <= 0) {
|
181
218
|
return PRIMITIVE_STACK_TOO_DEEP;
|
182
219
|
}
|
183
220
|
|
184
|
-
|
221
|
+
msgpack_unpacker_stack_entry_t* next = &uk->stack->data[uk->stack->depth];
|
185
222
|
next->count = count;
|
186
223
|
next->type = type;
|
187
224
|
next->object = object;
|
188
225
|
next->key = Qnil;
|
189
226
|
|
190
|
-
uk->
|
227
|
+
uk->stack->depth++;
|
191
228
|
return PRIMITIVE_CONTAINER_START;
|
192
229
|
}
|
193
230
|
|
194
231
|
static inline VALUE msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
|
195
232
|
{
|
196
|
-
return --uk->
|
233
|
+
return --uk->stack->depth;
|
197
234
|
}
|
198
235
|
|
199
236
|
static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
200
237
|
{
|
201
|
-
return uk->
|
238
|
+
return uk->stack->depth == 0;
|
202
239
|
}
|
203
240
|
|
204
241
|
#ifdef USE_CASE_RANGE
|
@@ -226,8 +263,8 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
|
226
263
|
|
227
264
|
static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
|
228
265
|
{
|
229
|
-
if(uk->
|
230
|
-
|
266
|
+
if(uk->stack->depth > 0) {
|
267
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
231
268
|
if(top->type == STACK_TYPE_MAP_KEY) {
|
232
269
|
return true;
|
233
270
|
}
|
@@ -270,25 +307,50 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
270
307
|
{
|
271
308
|
/* assuming uk->reading_raw == Qnil */
|
272
309
|
|
310
|
+
int ext_flags;
|
311
|
+
VALUE proc;
|
312
|
+
|
313
|
+
if(!(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY)) {
|
314
|
+
proc = msgpack_unpacker_ext_registry_lookup(uk->ext_registry, raw_type, &ext_flags);
|
315
|
+
if(proc != Qnil && ext_flags & MSGPACK_EXT_RECURSIVE) {
|
316
|
+
VALUE obj;
|
317
|
+
uk->last_object = Qnil;
|
318
|
+
reset_head_byte(uk);
|
319
|
+
uk->reading_raw_remaining = 0;
|
320
|
+
|
321
|
+
msgpack_unpacker_stack_t* child_stack = _msgpack_unpacker_new_stack();
|
322
|
+
child_stack->parent = uk->stack;
|
323
|
+
uk->stack = child_stack;
|
324
|
+
|
325
|
+
obj = rb_funcall(proc, s_call, 1, uk->self);
|
326
|
+
|
327
|
+
uk->stack = child_stack->parent;
|
328
|
+
_msgpack_unpacker_free_stack(child_stack);
|
329
|
+
|
330
|
+
return object_complete(uk, obj);
|
331
|
+
}
|
332
|
+
}
|
333
|
+
|
273
334
|
/* try optimized read */
|
274
335
|
size_t length = uk->reading_raw_remaining;
|
275
336
|
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
337
|
int ret;
|
281
|
-
if(
|
282
|
-
|
338
|
+
if ((uk->optimized_symbol_ext_type && uk->symbol_ext_type == raw_type) || (uk->symbolize_keys && is_reading_map_key(uk))) {
|
339
|
+
VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, raw_type != RAW_TYPE_BINARY);
|
340
|
+
ret = object_complete_symbol(uk, symbol);
|
283
341
|
} else {
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
342
|
+
bool will_freeze = uk->freeze;
|
343
|
+
if(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY) {
|
344
|
+
/* don't use zerocopy for hash keys but get a frozen string directly
|
345
|
+
* because rb_hash_aset freezes keys and it causes copying */
|
346
|
+
will_freeze = will_freeze || is_reading_map_key(uk);
|
347
|
+
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
|
348
|
+
ret = object_complete(uk, string);
|
349
|
+
} else {
|
350
|
+
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, false, false);
|
351
|
+
ret = object_complete_ext(uk, raw_type, string);
|
352
|
+
}
|
290
353
|
}
|
291
|
-
# endif
|
292
354
|
uk->reading_raw_remaining = 0;
|
293
355
|
return ret;
|
294
356
|
}
|
@@ -317,9 +379,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
317
379
|
|
318
380
|
SWITCH_RANGE(b, 0xa0, 0xbf) // FixRaw / fixstr
|
319
381
|
int count = b & 0x1f;
|
320
|
-
if(count == 0) {
|
321
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
322
|
-
}
|
323
382
|
/* read_raw_body_begin sets uk->reading_raw */
|
324
383
|
uk->reading_raw_remaining = count;
|
325
384
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -336,7 +395,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
336
395
|
if(count == 0) {
|
337
396
|
return object_complete(uk, rb_hash_new());
|
338
397
|
}
|
339
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
398
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
340
399
|
|
341
400
|
SWITCH_RANGE(b, 0xc0, 0xdf) // Variable
|
342
401
|
switch(b) {
|
@@ -357,7 +416,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
357
416
|
uint8_t length = cb->u8;
|
358
417
|
int ext_type = (signed char) cb->buffer[1];
|
359
418
|
if(length == 0) {
|
360
|
-
return object_complete_ext(uk, ext_type,
|
419
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
361
420
|
}
|
362
421
|
uk->reading_raw_remaining = length;
|
363
422
|
return read_raw_body_begin(uk, ext_type);
|
@@ -369,7 +428,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
369
428
|
uint16_t length = _msgpack_be16(cb->u16);
|
370
429
|
int ext_type = (signed char) cb->buffer[2];
|
371
430
|
if(length == 0) {
|
372
|
-
return object_complete_ext(uk, ext_type,
|
431
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
373
432
|
}
|
374
433
|
uk->reading_raw_remaining = length;
|
375
434
|
return read_raw_body_begin(uk, ext_type);
|
@@ -381,7 +440,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
381
440
|
uint32_t length = _msgpack_be32(cb->u32);
|
382
441
|
int ext_type = (signed char) cb->buffer[4];
|
383
442
|
if(length == 0) {
|
384
|
-
return object_complete_ext(uk, ext_type,
|
443
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
385
444
|
}
|
386
445
|
uk->reading_raw_remaining = length;
|
387
446
|
return read_raw_body_begin(uk, ext_type);
|
@@ -419,7 +478,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
419
478
|
{
|
420
479
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
421
480
|
uint32_t u32 = _msgpack_be32(cb->u32);
|
422
|
-
return object_complete(uk, ULONG2NUM(
|
481
|
+
return object_complete(uk, ULONG2NUM(u32)); // long at least 32 bits
|
423
482
|
}
|
424
483
|
|
425
484
|
case 0xcf: // unsigned int 64
|
@@ -447,7 +506,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
447
506
|
{
|
448
507
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
449
508
|
int32_t i32 = _msgpack_be32(cb->i32);
|
450
|
-
return object_complete(uk, LONG2NUM(
|
509
|
+
return object_complete(uk, LONG2NUM(i32)); // long at least 32 bits
|
451
510
|
}
|
452
511
|
|
453
512
|
case 0xd3: // signed int 64
|
@@ -502,9 +561,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
502
561
|
{
|
503
562
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
504
563
|
uint8_t count = cb->u8;
|
505
|
-
if(count == 0) {
|
506
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
507
|
-
}
|
508
564
|
/* read_raw_body_begin sets uk->reading_raw */
|
509
565
|
uk->reading_raw_remaining = count;
|
510
566
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -514,9 +570,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
514
570
|
{
|
515
571
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
516
572
|
uint16_t count = _msgpack_be16(cb->u16);
|
517
|
-
if(count == 0) {
|
518
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
519
|
-
}
|
520
573
|
/* read_raw_body_begin sets uk->reading_raw */
|
521
574
|
uk->reading_raw_remaining = count;
|
522
575
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -526,9 +579,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
526
579
|
{
|
527
580
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
528
581
|
uint32_t count = _msgpack_be32(cb->u32);
|
529
|
-
if(count == 0) {
|
530
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
531
|
-
}
|
532
582
|
/* read_raw_body_begin sets uk->reading_raw */
|
533
583
|
uk->reading_raw_remaining = count;
|
534
584
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -538,9 +588,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
538
588
|
{
|
539
589
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
540
590
|
uint8_t count = cb->u8;
|
541
|
-
if(count == 0) {
|
542
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
543
|
-
}
|
544
591
|
/* read_raw_body_begin sets uk->reading_raw */
|
545
592
|
uk->reading_raw_remaining = count;
|
546
593
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -550,9 +597,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
550
597
|
{
|
551
598
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
552
599
|
uint16_t count = _msgpack_be16(cb->u16);
|
553
|
-
if(count == 0) {
|
554
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
555
|
-
}
|
556
600
|
/* read_raw_body_begin sets uk->reading_raw */
|
557
601
|
uk->reading_raw_remaining = count;
|
558
602
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -562,9 +606,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
562
606
|
{
|
563
607
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
564
608
|
uint32_t count = _msgpack_be32(cb->u32);
|
565
|
-
if(count == 0) {
|
566
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
567
|
-
}
|
568
609
|
/* read_raw_body_begin sets uk->reading_raw */
|
569
610
|
uk->reading_raw_remaining = count;
|
570
611
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -597,7 +638,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
597
638
|
if(count == 0) {
|
598
639
|
return object_complete(uk, rb_hash_new());
|
599
640
|
}
|
600
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
641
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
601
642
|
}
|
602
643
|
|
603
644
|
case 0xdf: // map 32
|
@@ -607,7 +648,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
607
648
|
if(count == 0) {
|
608
649
|
return object_complete(uk, rb_hash_new());
|
609
650
|
}
|
610
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
651
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
611
652
|
}
|
612
653
|
|
613
654
|
default:
|
@@ -694,7 +735,7 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
694
735
|
|
695
736
|
container_completed:
|
696
737
|
{
|
697
|
-
|
738
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
698
739
|
switch(top->type) {
|
699
740
|
case STACK_TYPE_ARRAY:
|
700
741
|
rb_ary_push(top->object, uk->last_object);
|
@@ -705,18 +746,8 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
705
746
|
break;
|
706
747
|
case STACK_TYPE_MAP_VALUE:
|
707
748
|
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 */
|
749
|
+
/* here uses rb_str_intern instead of rb_intern so that Ruby VM can GC unused symbols */
|
711
750
|
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
751
|
} else {
|
721
752
|
rb_hash_aset(top->object, top->key, uk->last_object);
|
722
753
|
}
|
@@ -754,7 +785,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
754
785
|
|
755
786
|
container_completed:
|
756
787
|
{
|
757
|
-
|
788
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
758
789
|
|
759
790
|
/* this section optimized out */
|
760
791
|
// TODO object_complete still creates objects which should be optimized out
|
data/ext/msgpack/unpacker.h
CHANGED
@@ -27,6 +27,7 @@
|
|
27
27
|
|
28
28
|
struct msgpack_unpacker_t;
|
29
29
|
typedef struct msgpack_unpacker_t msgpack_unpacker_t;
|
30
|
+
typedef struct msgpack_unpacker_stack_t msgpack_unpacker_stack_t;
|
30
31
|
|
31
32
|
enum stack_type_t {
|
32
33
|
STACK_TYPE_ARRAY,
|
@@ -39,19 +40,23 @@ typedef struct {
|
|
39
40
|
enum stack_type_t type;
|
40
41
|
VALUE object;
|
41
42
|
VALUE key;
|
42
|
-
}
|
43
|
+
} msgpack_unpacker_stack_entry_t;
|
44
|
+
|
45
|
+
struct msgpack_unpacker_stack_t {
|
46
|
+
size_t depth;
|
47
|
+
size_t capacity;
|
48
|
+
msgpack_unpacker_stack_entry_t *data;
|
49
|
+
msgpack_unpacker_stack_t *parent;
|
50
|
+
};
|
43
51
|
|
44
52
|
#define MSGPACK_UNPACKER_STACK_SIZE (8+4+8+8) /* assumes size_t <= 64bit, enum <= 32bit, VALUE <= 64bit */
|
45
53
|
|
46
54
|
struct msgpack_unpacker_t {
|
47
55
|
msgpack_buffer_t buffer;
|
48
|
-
|
56
|
+
msgpack_unpacker_stack_t *stack;
|
49
57
|
unsigned int head_byte;
|
50
58
|
|
51
|
-
|
52
|
-
size_t stack_depth;
|
53
|
-
size_t stack_capacity;
|
54
|
-
|
59
|
+
VALUE self;
|
55
60
|
VALUE last_object;
|
56
61
|
|
57
62
|
VALUE reading_raw;
|
@@ -60,12 +65,14 @@ struct msgpack_unpacker_t {
|
|
60
65
|
|
61
66
|
VALUE buffer_ref;
|
62
67
|
|
63
|
-
msgpack_unpacker_ext_registry_t ext_registry;
|
68
|
+
msgpack_unpacker_ext_registry_t *ext_registry;
|
64
69
|
|
65
70
|
/* options */
|
66
71
|
bool symbolize_keys;
|
67
72
|
bool freeze;
|
68
73
|
bool allow_unknown_ext;
|
74
|
+
bool optimized_symbol_ext_type;
|
75
|
+
int symbol_ext_type;
|
69
76
|
};
|
70
77
|
|
71
78
|
#define UNPACKER_BUFFER_(uk) (&(uk)->buffer)
|
@@ -80,11 +87,11 @@ enum msgpack_unpacker_object_type {
|
|
80
87
|
TYPE_MAP,
|
81
88
|
};
|
82
89
|
|
83
|
-
void msgpack_unpacker_static_init();
|
90
|
+
void msgpack_unpacker_static_init(void);
|
84
91
|
|
85
|
-
void msgpack_unpacker_static_destroy();
|
92
|
+
void msgpack_unpacker_static_destroy(void);
|
86
93
|
|
87
|
-
void _msgpack_unpacker_init(msgpack_unpacker_t*
|
94
|
+
void _msgpack_unpacker_init(msgpack_unpacker_t*);
|
88
95
|
|
89
96
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk);
|
90
97
|
|