msgpack 1.5.1 → 1.5.6
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 +5 -5
- data/ChangeLog +22 -0
- data/README.md +3 -1
- data/bench/bench.rb +78 -0
- data/ext/msgpack/buffer.c +9 -36
- data/ext/msgpack/buffer.h +9 -1
- data/ext/msgpack/buffer_class.c +6 -6
- data/ext/msgpack/compat.h +0 -99
- data/ext/msgpack/extconf.rb +9 -11
- data/ext/msgpack/packer.c +0 -24
- data/ext/msgpack/packer.h +1 -7
- data/ext/msgpack/packer_class.c +1 -1
- data/ext/msgpack/unpacker.c +56 -67
- data/ext/msgpack/unpacker.h +10 -6
- data/ext/msgpack/unpacker_class.c +2 -3
- data/lib/msgpack/version.rb +1 -1
- data/msgpack.gemspec +1 -0
- data/spec/factory_spec.rb +34 -0
- data/spec/spec_helper.rb +7 -1
- data/spec/timestamp_spec.rb +2 -2
- data/spec/unpacker_spec.rb +12 -0
- metadata +18 -13
- 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
|
@@ -34,6 +34,13 @@ static ID s_call;
|
|
|
34
34
|
static msgpack_rmem_t s_stack_rmem;
|
|
35
35
|
#endif
|
|
36
36
|
|
|
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
|
+
|
|
37
44
|
void msgpack_unpacker_static_init()
|
|
38
45
|
{
|
|
39
46
|
#ifdef UNPACKER_STACK_RMEM
|
|
@@ -53,13 +60,16 @@ void msgpack_unpacker_static_destroy()
|
|
|
53
60
|
#define HEAD_BYTE_REQUIRED 0xc1
|
|
54
61
|
|
|
55
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;
|
|
56
65
|
#ifdef UNPACKER_STACK_RMEM
|
|
57
|
-
|
|
66
|
+
stack->data = msgpack_rmem_alloc(&s_stack_rmem);
|
|
58
67
|
/*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
|
|
59
68
|
#else
|
|
60
|
-
/*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(
|
|
61
|
-
|
|
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));
|
|
62
71
|
#endif
|
|
72
|
+
return stack;
|
|
63
73
|
}
|
|
64
74
|
|
|
65
75
|
msgpack_unpacker_t* _msgpack_unpacker_new(void)
|
|
@@ -74,17 +84,17 @@ msgpack_unpacker_t* _msgpack_unpacker_new(void)
|
|
|
74
84
|
uk->reading_raw = Qnil;
|
|
75
85
|
|
|
76
86
|
uk->stack = _msgpack_unpacker_new_stack();
|
|
77
|
-
uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
|
78
87
|
|
|
79
88
|
return uk;
|
|
80
89
|
}
|
|
81
90
|
|
|
82
91
|
static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
|
|
83
92
|
#ifdef UNPACKER_STACK_RMEM
|
|
84
|
-
msgpack_rmem_free(&s_stack_rmem, stack);
|
|
93
|
+
msgpack_rmem_free(&s_stack_rmem, stack->data);
|
|
85
94
|
#else
|
|
86
|
-
xfree(stack);
|
|
95
|
+
xfree(stack->data);
|
|
87
96
|
#endif
|
|
97
|
+
xfree(stack);
|
|
88
98
|
}
|
|
89
99
|
|
|
90
100
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
|
|
@@ -93,18 +103,24 @@ void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
|
|
|
93
103
|
msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
|
|
94
104
|
}
|
|
95
105
|
|
|
106
|
+
void msgpack_unpacker_mark_stack(msgpack_unpacker_stack_t* stack)
|
|
107
|
+
{
|
|
108
|
+
while (stack) {
|
|
109
|
+
msgpack_unpacker_stack_entry_t* s = stack->data;
|
|
110
|
+
msgpack_unpacker_stack_entry_t* send = stack->data + stack->depth;
|
|
111
|
+
for(; s < send; s++) {
|
|
112
|
+
rb_gc_mark(s->object);
|
|
113
|
+
rb_gc_mark(s->key);
|
|
114
|
+
}
|
|
115
|
+
stack = stack->parent;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
96
119
|
void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
|
|
97
120
|
{
|
|
98
121
|
rb_gc_mark(uk->last_object);
|
|
99
122
|
rb_gc_mark(uk->reading_raw);
|
|
100
|
-
|
|
101
|
-
msgpack_unpacker_stack_t* s = uk->stack;
|
|
102
|
-
msgpack_unpacker_stack_t* send = uk->stack + uk->stack_depth;
|
|
103
|
-
for(; s < send; s++) {
|
|
104
|
-
rb_gc_mark(s->object);
|
|
105
|
-
rb_gc_mark(s->key);
|
|
106
|
-
}
|
|
107
|
-
|
|
123
|
+
msgpack_unpacker_mark_stack(uk->stack);
|
|
108
124
|
/* See MessagePack_Buffer_wrap */
|
|
109
125
|
/* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
|
|
110
126
|
rb_gc_mark(uk->buffer_ref);
|
|
@@ -116,9 +132,8 @@ void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
|
|
|
116
132
|
|
|
117
133
|
uk->head_byte = HEAD_BYTE_REQUIRED;
|
|
118
134
|
|
|
119
|
-
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->
|
|
120
|
-
uk->
|
|
121
|
-
|
|
135
|
+
/*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack->depth);*/
|
|
136
|
+
uk->stack->depth = 0;
|
|
122
137
|
uk->last_object = Qnil;
|
|
123
138
|
uk->reading_raw = Qnil;
|
|
124
139
|
uk->reading_raw_remaining = 0;
|
|
@@ -170,6 +185,9 @@ static inline int object_complete_symbol(msgpack_unpacker_t* uk, VALUE object)
|
|
|
170
185
|
static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALUE str)
|
|
171
186
|
{
|
|
172
187
|
if (uk->optimized_symbol_ext_type && ext_type == uk->symbol_ext_type) {
|
|
188
|
+
if (RB_UNLIKELY(NIL_P(str))) { // empty extension is returned as Qnil
|
|
189
|
+
return object_complete_symbol(uk, ID2SYM(rb_intern3("", 0, rb_utf8_encoding())));
|
|
190
|
+
}
|
|
173
191
|
return object_complete_symbol(uk, rb_str_intern(str));
|
|
174
192
|
}
|
|
175
193
|
|
|
@@ -191,37 +209,37 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
|
191
209
|
}
|
|
192
210
|
|
|
193
211
|
/* stack funcs */
|
|
194
|
-
static inline
|
|
212
|
+
static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
|
|
195
213
|
{
|
|
196
|
-
return &uk->stack[uk->
|
|
214
|
+
return &uk->stack->data[uk->stack->depth-1];
|
|
197
215
|
}
|
|
198
216
|
|
|
199
217
|
static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
|
|
200
218
|
{
|
|
201
219
|
reset_head_byte(uk);
|
|
202
220
|
|
|
203
|
-
if(uk->
|
|
221
|
+
if(uk->stack->capacity - uk->stack->depth <= 0) {
|
|
204
222
|
return PRIMITIVE_STACK_TOO_DEEP;
|
|
205
223
|
}
|
|
206
224
|
|
|
207
|
-
|
|
225
|
+
msgpack_unpacker_stack_entry_t* next = &uk->stack->data[uk->stack->depth];
|
|
208
226
|
next->count = count;
|
|
209
227
|
next->type = type;
|
|
210
228
|
next->object = object;
|
|
211
229
|
next->key = Qnil;
|
|
212
230
|
|
|
213
|
-
uk->
|
|
231
|
+
uk->stack->depth++;
|
|
214
232
|
return PRIMITIVE_CONTAINER_START;
|
|
215
233
|
}
|
|
216
234
|
|
|
217
235
|
static inline VALUE msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
|
|
218
236
|
{
|
|
219
|
-
return --uk->
|
|
237
|
+
return --uk->stack->depth;
|
|
220
238
|
}
|
|
221
239
|
|
|
222
240
|
static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
|
223
241
|
{
|
|
224
|
-
return uk->
|
|
242
|
+
return uk->stack->depth == 0;
|
|
225
243
|
}
|
|
226
244
|
|
|
227
245
|
#ifdef USE_CASE_RANGE
|
|
@@ -249,8 +267,8 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
|
|
|
249
267
|
|
|
250
268
|
static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
|
|
251
269
|
{
|
|
252
|
-
if(uk->
|
|
253
|
-
|
|
270
|
+
if(uk->stack->depth > 0) {
|
|
271
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
|
254
272
|
if(top->type == STACK_TYPE_MAP_KEY) {
|
|
255
273
|
return true;
|
|
256
274
|
}
|
|
@@ -302,25 +320,17 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
|
302
320
|
VALUE obj;
|
|
303
321
|
uk->last_object = Qnil;
|
|
304
322
|
reset_head_byte(uk);
|
|
305
|
-
size_t ext_size = uk->reading_raw_remaining;
|
|
306
323
|
uk->reading_raw_remaining = 0;
|
|
307
324
|
|
|
308
|
-
msgpack_unpacker_stack_t*
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
uk->stack = _msgpack_unpacker_new_stack();
|
|
313
|
-
uk->stack_depth = 0;
|
|
314
|
-
uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
|
325
|
+
msgpack_unpacker_stack_t* child_stack = _msgpack_unpacker_new_stack();
|
|
326
|
+
child_stack->parent = uk->stack;
|
|
327
|
+
uk->stack = child_stack;
|
|
315
328
|
|
|
316
329
|
obj = rb_funcall(proc, s_call, 1, uk->buffer.owner);
|
|
317
330
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
uk->stack_depth = stack_depth;
|
|
321
|
-
uk->stack_capacity = stack_capacity;
|
|
331
|
+
uk->stack = child_stack->parent;
|
|
332
|
+
_msgpack_unpacker_free_stack(child_stack);
|
|
322
333
|
|
|
323
|
-
msgpack_buffer_skip(UNPACKER_BUFFER_(uk), ext_size);
|
|
324
334
|
return object_complete(uk, obj);
|
|
325
335
|
}
|
|
326
336
|
}
|
|
@@ -373,9 +383,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
373
383
|
|
|
374
384
|
SWITCH_RANGE(b, 0xa0, 0xbf) // FixRaw / fixstr
|
|
375
385
|
int count = b & 0x1f;
|
|
376
|
-
if(count == 0) {
|
|
377
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
|
378
|
-
}
|
|
379
386
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
380
387
|
uk->reading_raw_remaining = count;
|
|
381
388
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
|
@@ -392,7 +399,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
392
399
|
if(count == 0) {
|
|
393
400
|
return object_complete(uk, rb_hash_new());
|
|
394
401
|
}
|
|
395
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
|
402
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
|
396
403
|
|
|
397
404
|
SWITCH_RANGE(b, 0xc0, 0xdf) // Variable
|
|
398
405
|
switch(b) {
|
|
@@ -475,7 +482,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
475
482
|
{
|
|
476
483
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
|
477
484
|
uint32_t u32 = _msgpack_be32(cb->u32);
|
|
478
|
-
return object_complete(uk, ULONG2NUM(
|
|
485
|
+
return object_complete(uk, ULONG2NUM(u32)); // long at least 32 bits
|
|
479
486
|
}
|
|
480
487
|
|
|
481
488
|
case 0xcf: // unsigned int 64
|
|
@@ -503,7 +510,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
503
510
|
{
|
|
504
511
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
|
505
512
|
int32_t i32 = _msgpack_be32(cb->i32);
|
|
506
|
-
return object_complete(uk, LONG2NUM(
|
|
513
|
+
return object_complete(uk, LONG2NUM(i32)); // long at least 32 bits
|
|
507
514
|
}
|
|
508
515
|
|
|
509
516
|
case 0xd3: // signed int 64
|
|
@@ -558,9 +565,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
558
565
|
{
|
|
559
566
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
|
560
567
|
uint8_t count = cb->u8;
|
|
561
|
-
if(count == 0) {
|
|
562
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
|
563
|
-
}
|
|
564
568
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
565
569
|
uk->reading_raw_remaining = count;
|
|
566
570
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
|
@@ -570,9 +574,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
570
574
|
{
|
|
571
575
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
|
572
576
|
uint16_t count = _msgpack_be16(cb->u16);
|
|
573
|
-
if(count == 0) {
|
|
574
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
|
575
|
-
}
|
|
576
577
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
577
578
|
uk->reading_raw_remaining = count;
|
|
578
579
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
|
@@ -582,9 +583,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
582
583
|
{
|
|
583
584
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
|
584
585
|
uint32_t count = _msgpack_be32(cb->u32);
|
|
585
|
-
if(count == 0) {
|
|
586
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
|
587
|
-
}
|
|
588
586
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
589
587
|
uk->reading_raw_remaining = count;
|
|
590
588
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
|
@@ -594,9 +592,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
594
592
|
{
|
|
595
593
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
|
596
594
|
uint8_t count = cb->u8;
|
|
597
|
-
if(count == 0) {
|
|
598
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
|
599
|
-
}
|
|
600
595
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
601
596
|
uk->reading_raw_remaining = count;
|
|
602
597
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
|
@@ -606,9 +601,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
606
601
|
{
|
|
607
602
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
|
608
603
|
uint16_t count = _msgpack_be16(cb->u16);
|
|
609
|
-
if(count == 0) {
|
|
610
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
|
611
|
-
}
|
|
612
604
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
613
605
|
uk->reading_raw_remaining = count;
|
|
614
606
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
|
@@ -618,9 +610,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
618
610
|
{
|
|
619
611
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
|
620
612
|
uint32_t count = _msgpack_be32(cb->u32);
|
|
621
|
-
if(count == 0) {
|
|
622
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
|
623
|
-
}
|
|
624
613
|
/* read_raw_body_begin sets uk->reading_raw */
|
|
625
614
|
uk->reading_raw_remaining = count;
|
|
626
615
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
|
@@ -653,7 +642,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
653
642
|
if(count == 0) {
|
|
654
643
|
return object_complete(uk, rb_hash_new());
|
|
655
644
|
}
|
|
656
|
-
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(count));
|
|
657
646
|
}
|
|
658
647
|
|
|
659
648
|
case 0xdf: // map 32
|
|
@@ -663,7 +652,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
|
663
652
|
if(count == 0) {
|
|
664
653
|
return object_complete(uk, rb_hash_new());
|
|
665
654
|
}
|
|
666
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
|
655
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
|
667
656
|
}
|
|
668
657
|
|
|
669
658
|
default:
|
|
@@ -750,7 +739,7 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
|
750
739
|
|
|
751
740
|
container_completed:
|
|
752
741
|
{
|
|
753
|
-
|
|
742
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
|
754
743
|
switch(top->type) {
|
|
755
744
|
case STACK_TYPE_ARRAY:
|
|
756
745
|
rb_ary_push(top->object, uk->last_object);
|
|
@@ -800,7 +789,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
|
800
789
|
|
|
801
790
|
container_completed:
|
|
802
791
|
{
|
|
803
|
-
|
|
792
|
+
msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
|
|
804
793
|
|
|
805
794
|
/* this section optimized out */
|
|
806
795
|
// 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,22 @@ 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
|
-
msgpack_unpacker_stack_t* stack;
|
|
52
|
-
size_t stack_depth;
|
|
53
|
-
size_t stack_capacity;
|
|
54
|
-
|
|
55
59
|
VALUE last_object;
|
|
56
60
|
|
|
57
61
|
VALUE reading_raw;
|
|
@@ -209,7 +209,7 @@ static VALUE Unpacker_read_array_header(VALUE self)
|
|
|
209
209
|
raise_unpacker_error(r);
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
return ULONG2NUM(size);
|
|
212
|
+
return ULONG2NUM(size); // long at least 32 bits
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
static VALUE Unpacker_read_map_header(VALUE self)
|
|
@@ -222,7 +222,7 @@ static VALUE Unpacker_read_map_header(VALUE self)
|
|
|
222
222
|
raise_unpacker_error((int)r);
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
return ULONG2NUM(size);
|
|
225
|
+
return ULONG2NUM(size); // long at least 32 bits
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
|
|
@@ -450,4 +450,3 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
|
450
450
|
|
|
451
451
|
rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
|
|
452
452
|
}
|
|
453
|
-
|
data/lib/msgpack/version.rb
CHANGED
data/msgpack.gemspec
CHANGED
data/spec/factory_spec.rb
CHANGED
|
@@ -422,6 +422,12 @@ describe MessagePack::Factory do
|
|
|
422
422
|
MessagePack::ExtensionValue.new(1, factory.dump(x: 1, y: 2, z: 3)),
|
|
423
423
|
3,
|
|
424
424
|
]
|
|
425
|
+
|
|
426
|
+
expect(factory.load(payload)).to be == [
|
|
427
|
+
1,
|
|
428
|
+
Point.new(1, 2, 3),
|
|
429
|
+
3,
|
|
430
|
+
]
|
|
425
431
|
end
|
|
426
432
|
|
|
427
433
|
it 'can be nested' do
|
|
@@ -468,6 +474,10 @@ describe MessagePack::Factory do
|
|
|
468
474
|
expect(roundtrip(:symbol)).to be :symbol
|
|
469
475
|
end
|
|
470
476
|
|
|
477
|
+
it 'works with empty symbol' do
|
|
478
|
+
expect(roundtrip(:"")).to be :""
|
|
479
|
+
end
|
|
480
|
+
|
|
471
481
|
it 'preserves encoding for ASCII symbols' do
|
|
472
482
|
expect(:symbol.encoding).to be Encoding::US_ASCII
|
|
473
483
|
expect(roundtrip(:symbol)).to be :symbol
|
|
@@ -577,6 +587,30 @@ describe MessagePack::Factory do
|
|
|
577
587
|
GC.stress = false
|
|
578
588
|
end
|
|
579
589
|
end
|
|
590
|
+
|
|
591
|
+
it 'does not crash in recursive extensions' do
|
|
592
|
+
my_hash_type = Class.new(Hash)
|
|
593
|
+
factory = MessagePack::Factory.new
|
|
594
|
+
factory.register_type(7,
|
|
595
|
+
my_hash_type,
|
|
596
|
+
packer: ->(value, packer) do
|
|
597
|
+
packer.write(value.to_h)
|
|
598
|
+
end,
|
|
599
|
+
unpacker: ->(unpacker) { my_hash_type.new(unpacker.read) },
|
|
600
|
+
recursive: true,
|
|
601
|
+
)
|
|
602
|
+
|
|
603
|
+
payload = factory.dump(
|
|
604
|
+
[my_hash_type.new]
|
|
605
|
+
)
|
|
606
|
+
|
|
607
|
+
begin
|
|
608
|
+
GC.stress = true
|
|
609
|
+
factory.load(payload)
|
|
610
|
+
ensure
|
|
611
|
+
GC.stress = false
|
|
612
|
+
end
|
|
613
|
+
end
|
|
580
614
|
end
|
|
581
615
|
|
|
582
616
|
describe 'DefaultFactory' do
|
data/spec/spec_helper.rb
CHANGED
|
@@ -20,7 +20,11 @@ require "msgpack/bigint"
|
|
|
20
20
|
if GC.respond_to?(:verify_compaction_references)
|
|
21
21
|
# This method was added in Ruby 3.0.0. Calling it this way asks the GC to
|
|
22
22
|
# move objects around, helping to find object movement bugs.
|
|
23
|
-
|
|
23
|
+
begin
|
|
24
|
+
GC.verify_compaction_references(double_heap: true, toward: :empty)
|
|
25
|
+
rescue NotImplementedError
|
|
26
|
+
# Some platforms don't support compaction
|
|
27
|
+
end
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
if GC.respond_to?(:auto_compact=)
|
|
@@ -29,6 +33,8 @@ end
|
|
|
29
33
|
|
|
30
34
|
IS_JRUBY = RUBY_ENGINE == 'jruby'
|
|
31
35
|
|
|
36
|
+
IS_TRUFFLERUBY = RUBY_ENGINE == 'truffleruby'
|
|
37
|
+
|
|
32
38
|
# checking if Hash#[]= (rb_hash_aset) dedupes string keys
|
|
33
39
|
def automatic_string_keys_deduplication?
|
|
34
40
|
h = {}
|
data/spec/timestamp_spec.rb
CHANGED
|
@@ -87,14 +87,14 @@ describe MessagePack::Timestamp do
|
|
|
87
87
|
|
|
88
88
|
let(:time96_min) { Time.at(-2**63).utc }
|
|
89
89
|
it 'is serialized into timestamp96' do
|
|
90
|
-
skip if IS_JRUBY # JRuby
|
|
90
|
+
skip if IS_JRUBY || IS_TRUFFLERUBY # JRuby and TruffleRuby both use underlying Java time classes that do not support |year| >= 1 billion
|
|
91
91
|
expect(factory.pack(time96_min).size).to be 15
|
|
92
92
|
expect(factory.unpack(factory.pack(time96_min)).utc).to eq(time96_min)
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
let(:time96_max) { Time.at(2**63 - 1).utc }
|
|
96
96
|
it 'is serialized into timestamp96' do
|
|
97
|
-
skip if IS_JRUBY # JRuby
|
|
97
|
+
skip if IS_JRUBY || IS_TRUFFLERUBY # JRuby and TruffleRuby both use underlying Java time classes that do not support |year| >= 1 billion
|
|
98
98
|
expect(factory.pack(time96_max).size).to be 15
|
|
99
99
|
expect(factory.unpack(factory.pack(time96_max)).utc).to eq(time96_max)
|
|
100
100
|
end
|
data/spec/unpacker_spec.rb
CHANGED
|
@@ -707,6 +707,18 @@ describe MessagePack::Unpacker do
|
|
|
707
707
|
described_class.new(:freeze => true)
|
|
708
708
|
end
|
|
709
709
|
|
|
710
|
+
if (-"test").equal?(-"test") # RUBY_VERSION >= "2.5"
|
|
711
|
+
it 'dedups strings' do
|
|
712
|
+
interned_str = -"test"
|
|
713
|
+
roundtrip = MessagePack.unpack(MessagePack.pack(interned_str), freeze: true)
|
|
714
|
+
expect(roundtrip).to be interned_str
|
|
715
|
+
|
|
716
|
+
interned_str = -""
|
|
717
|
+
roundtrip = MessagePack.unpack(MessagePack.pack(interned_str), freeze: true)
|
|
718
|
+
expect(roundtrip).to be interned_str
|
|
719
|
+
end
|
|
720
|
+
end
|
|
721
|
+
|
|
710
722
|
it 'can freeze objects when using .unpack' do
|
|
711
723
|
parsed_struct = MessagePack.unpack(buffer, freeze: true)
|
|
712
724
|
parsed_struct.should == struct
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: msgpack
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.5.
|
|
4
|
+
version: 1.5.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sadayuki Furuhashi
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2022-
|
|
13
|
+
date: 2022-08-23 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: bundler
|
|
@@ -96,6 +96,20 @@ dependencies:
|
|
|
96
96
|
- - ">="
|
|
97
97
|
- !ruby/object:Gem::Version
|
|
98
98
|
version: '0'
|
|
99
|
+
- !ruby/object:Gem::Dependency
|
|
100
|
+
name: benchmark-ips
|
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
|
102
|
+
requirements:
|
|
103
|
+
- - "~>"
|
|
104
|
+
- !ruby/object:Gem::Version
|
|
105
|
+
version: 2.10.0
|
|
106
|
+
type: :development
|
|
107
|
+
prerelease: false
|
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
109
|
+
requirements:
|
|
110
|
+
- - "~>"
|
|
111
|
+
- !ruby/object:Gem::Version
|
|
112
|
+
version: 2.10.0
|
|
99
113
|
description: MessagePack is a binary-based efficient object serialization library.
|
|
100
114
|
It enables to exchange structured objects between many languages like JSON. But
|
|
101
115
|
unlike JSON, it is very fast and small.
|
|
@@ -117,16 +131,7 @@ files:
|
|
|
117
131
|
- README.md
|
|
118
132
|
- Rakefile
|
|
119
133
|
- appveyor.yml
|
|
120
|
-
- bench/
|
|
121
|
-
- bench/pack_log.rb
|
|
122
|
-
- bench/pack_log_long.rb
|
|
123
|
-
- bench/pack_symbols.rb
|
|
124
|
-
- bench/run.sh
|
|
125
|
-
- bench/run_long.sh
|
|
126
|
-
- bench/run_symbols.sh
|
|
127
|
-
- bench/unpack.rb
|
|
128
|
-
- bench/unpack_log.rb
|
|
129
|
-
- bench/unpack_log_long.rb
|
|
134
|
+
- bench/bench.rb
|
|
130
135
|
- doclib/msgpack.rb
|
|
131
136
|
- doclib/msgpack/buffer.rb
|
|
132
137
|
- doclib/msgpack/core_ext.rb
|
|
@@ -231,7 +236,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
231
236
|
- !ruby/object:Gem::Version
|
|
232
237
|
version: '0'
|
|
233
238
|
requirements: []
|
|
234
|
-
rubygems_version: 3.
|
|
239
|
+
rubygems_version: 3.1.2
|
|
235
240
|
signing_key:
|
|
236
241
|
specification_version: 4
|
|
237
242
|
summary: MessagePack, a binary-based efficient data interchange format.
|
data/bench/pack.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
require 'viiite'
|
|
2
|
-
require 'msgpack'
|
|
3
|
-
|
|
4
|
-
data = { 'hello' => 'world', 'nested' => ['structure', {value: 42}] }
|
|
5
|
-
data_sym = { hello: 'world', nested: ['structure', {value: 42}] }
|
|
6
|
-
|
|
7
|
-
data = MessagePack.pack(:hello => 'world', :nested => ['structure', {:value => 42}])
|
|
8
|
-
|
|
9
|
-
Viiite.bench do |b|
|
|
10
|
-
b.range_over([10_000, 100_000, 1000_000], :runs) do |runs|
|
|
11
|
-
b.report(:strings) do
|
|
12
|
-
runs.times do
|
|
13
|
-
MessagePack.pack(data)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
b.report(:symbols) do
|
|
18
|
-
runs.times do
|
|
19
|
-
MessagePack.pack(data_sym)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
data/bench/pack_log.rb
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
require 'viiite'
|
|
2
|
-
require 'msgpack'
|
|
3
|
-
|
|
4
|
-
data_plain = { 'message' => '127.0.0.1 - - [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326 "http://www.example.com/start.html" "Mozilla/4.08 [en] (Win98; I ;Nav)"' }
|
|
5
|
-
data_structure = {
|
|
6
|
-
'remote_host' => '127.0.0.1',
|
|
7
|
-
'remote_user' => '-',
|
|
8
|
-
'date' => '10/Oct/2000:13:55:36 -0700',
|
|
9
|
-
'request' => 'GET /apache_pb.gif HTTP/1.0',
|
|
10
|
-
'method' => 'GET',
|
|
11
|
-
'path' => '/apache_pb.gif',
|
|
12
|
-
'protocol' => 'HTTP/1.0',
|
|
13
|
-
'status' => 200,
|
|
14
|
-
'bytes' => 2326,
|
|
15
|
-
'referer' => 'http://www.example.com/start.html',
|
|
16
|
-
'agent' => 'Mozilla/4.08 [en] (Win98; I ;Nav)',
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
Viiite.bench do |b|
|
|
20
|
-
b.range_over([10_000, 100_000, 1000_000], :runs) do |runs|
|
|
21
|
-
b.report(:plain) do
|
|
22
|
-
runs.times do
|
|
23
|
-
MessagePack.pack(data_plain)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
b.report(:structure) do
|
|
28
|
-
runs.times do
|
|
29
|
-
MessagePack.pack(data_structure)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|