msgpack 1.5.0 → 1.5.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/.github/workflows/ci.yaml +5 -5
- data/ChangeLog +13 -0
- data/ext/java/org/msgpack/jruby/Encoder.java +2 -1
- data/ext/msgpack/buffer.c +0 -31
- data/ext/msgpack/buffer.h +9 -1
- data/ext/msgpack/compat.h +0 -99
- data/ext/msgpack/extconf.rb +8 -10
- data/ext/msgpack/packer.c +0 -24
- data/ext/msgpack/packer.h +1 -7
- data/ext/msgpack/unpacker.c +45 -39
- data/ext/msgpack/unpacker_class.c +0 -1
- data/lib/msgpack/version.rb +1 -1
- data/spec/factory_spec.rb +27 -0
- data/spec/spec_helper.rb +8 -1
- data/spec/timestamp_spec.rb +2 -2
- data/spec/unpacker_spec.rb +12 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c335ddbadfa205f9fabd011bdcbe768924a532e762550a8c974035eb2b6ca59
|
4
|
+
data.tar.gz: 24abdf9bb3b34484ded41acc0ac4291ba25ee48660cca66968b265453b35ed96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0ebbe1cca5508d5a1fe4b28d7558e1cbe35e82bdf3b4596e3998feb86298e4bba718153a275ab808bf83651225f20cea52e1117df816e629cc05fbf2513f53c
|
7
|
+
data.tar.gz: 17ed1e47c07f1388a78b844ff2621414531eea6287b020a1568c9f2b6c2d3e8cbacff6e18a00159604fc241676cdd7a1542af4c4a41f1fc0795945912e885d6f
|
data/.github/workflows/ci.yaml
CHANGED
@@ -25,12 +25,12 @@ jobs:
|
|
25
25
|
bundler-cache: true # 'bundle install' and cache
|
26
26
|
- run: bundle exec rake
|
27
27
|
|
28
|
-
|
28
|
+
other:
|
29
29
|
strategy:
|
30
30
|
fail-fast: false
|
31
31
|
matrix:
|
32
32
|
os: [ubuntu]
|
33
|
-
ruby: ['jruby-9.2.19.0', 'jruby-9.3.3.0']
|
33
|
+
ruby: ['jruby-9.2.19.0', 'jruby-9.3.3.0', 'truffleruby']
|
34
34
|
runs-on: ${{ matrix.os }}-latest
|
35
35
|
steps:
|
36
36
|
- uses: actions/checkout@v2
|
@@ -38,7 +38,7 @@ jobs:
|
|
38
38
|
with:
|
39
39
|
ruby-version: ${{ matrix.ruby }}
|
40
40
|
bundler-cache: true # 'bundle install' and cache
|
41
|
-
- run: bundle exec rake
|
41
|
+
- run: bundle exec rake spec
|
42
42
|
|
43
43
|
head-versions:
|
44
44
|
continue-on-error: true
|
@@ -46,7 +46,7 @@ jobs:
|
|
46
46
|
fail-fast: false
|
47
47
|
matrix:
|
48
48
|
os: [ubuntu]
|
49
|
-
ruby: ['ruby-head', 'jruby-head'
|
49
|
+
ruby: ['ruby-head', 'jruby-head']
|
50
50
|
runs-on: ${{ matrix.os }}-latest
|
51
51
|
steps:
|
52
52
|
- uses: actions/checkout@v2
|
@@ -54,4 +54,4 @@ jobs:
|
|
54
54
|
with:
|
55
55
|
ruby-version: ${{ matrix.ruby }}
|
56
56
|
bundler-cache: true # 'bundle install' and cache
|
57
|
-
- run: bundle exec rake || echo "failed, but ignore it"
|
57
|
+
- run: bundle exec rake spec || echo "failed, but ignore it"
|
data/ChangeLog
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
2022-05-30 version 1.5.3:
|
2
|
+
|
3
|
+
* Fix deduplication of empty strings when using the `freeze: true` option.
|
4
|
+
* Use `rb_hash_new_capa` when available (Ruby 3.2) for improved performance when parsing large hashes.
|
5
|
+
|
6
|
+
2022-05-27 version 1.5.2:
|
7
|
+
|
8
|
+
* Fix bug about unpacking ext type objects with the recursive option
|
9
|
+
|
10
|
+
2022-04-07 version 1.5.1:
|
11
|
+
|
12
|
+
* Fix bug about packing/unpacking ext type objects with the recursive option
|
13
|
+
|
1
14
|
2022-04-06 version 1.5.0:
|
2
15
|
|
3
16
|
* Add recursive option on Factory#register_type to operate Packer/Unpacker manually
|
@@ -415,6 +415,7 @@ public class Encoder {
|
|
415
415
|
if (entry.isRecursive()) {
|
416
416
|
ByteBuffer oldBuffer = buffer;
|
417
417
|
buffer = ByteBuffer.allocate(CACHE_LINE_SIZE - ARRAY_HEADER_SIZE);
|
418
|
+
boolean previousRecursiveExtension = recursiveExtension;
|
418
419
|
recursiveExtension = true;
|
419
420
|
|
420
421
|
ByteList payload;
|
@@ -423,7 +424,7 @@ public class Encoder {
|
|
423
424
|
proc.callMethod(runtime.getCurrentContext(), "call", args);
|
424
425
|
payload = new ByteList(buffer.array(), 0, buffer.position(), binaryEncoding, false);
|
425
426
|
} finally {
|
426
|
-
recursiveExtension =
|
427
|
+
recursiveExtension = previousRecursiveExtension;
|
427
428
|
buffer = oldBuffer;
|
428
429
|
}
|
429
430
|
appendExt(type, payload);
|
data/ext/msgpack/buffer.c
CHANGED
@@ -300,30 +300,6 @@ static inline void _msgpack_buffer_add_new_chunk(msgpack_buffer_t* b)
|
|
300
300
|
}
|
301
301
|
}
|
302
302
|
|
303
|
-
static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE string)
|
304
|
-
{
|
305
|
-
VALUE mapped_string = rb_str_dup(string);
|
306
|
-
ENCODING_SET(mapped_string, msgpack_rb_encindex_ascii8bit);
|
307
|
-
|
308
|
-
_msgpack_buffer_add_new_chunk(b);
|
309
|
-
|
310
|
-
char* data = RSTRING_PTR(mapped_string);
|
311
|
-
size_t length = RSTRING_LEN(mapped_string);
|
312
|
-
|
313
|
-
b->tail.first = (char*) data;
|
314
|
-
b->tail.last = (char*) data + length;
|
315
|
-
b->tail.mapped_string = mapped_string;
|
316
|
-
b->tail.mem = NULL;
|
317
|
-
|
318
|
-
/* msgpack_buffer_writable_size should return 0 for mapped chunk */
|
319
|
-
b->tail_buffer_end = b->tail.last;
|
320
|
-
|
321
|
-
/* consider read_buffer */
|
322
|
-
if(b->head == &b->tail) {
|
323
|
-
b->read_buffer = b->tail.first;
|
324
|
-
}
|
325
|
-
}
|
326
|
-
|
327
303
|
void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string)
|
328
304
|
{
|
329
305
|
size_t length = RSTRING_LEN(string);
|
@@ -332,16 +308,9 @@ void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string)
|
|
332
308
|
msgpack_buffer_flush(b);
|
333
309
|
if (ENCODING_GET(string) == msgpack_rb_encindex_ascii8bit) {
|
334
310
|
rb_funcall(b->io, b->io_write_all_method, 1, string);
|
335
|
-
} else if(!STR_DUP_LIKELY_DOES_COPY(string)) {
|
336
|
-
VALUE s = rb_str_dup(string);
|
337
|
-
ENCODING_SET(s, msgpack_rb_encindex_ascii8bit);
|
338
|
-
rb_funcall(b->io, b->io_write_all_method, 1, s);
|
339
311
|
} else {
|
340
312
|
msgpack_buffer_append(b, RSTRING_PTR(string), length);
|
341
313
|
}
|
342
|
-
} else if(!STR_DUP_LIKELY_DOES_COPY(string)) {
|
343
|
-
_msgpack_buffer_append_reference(b, string);
|
344
|
-
|
345
314
|
} else {
|
346
315
|
msgpack_buffer_append(b, RSTRING_PTR(string), length);
|
347
316
|
}
|
data/ext/msgpack/buffer.h
CHANGED
@@ -49,6 +49,10 @@
|
|
49
49
|
|
50
50
|
#define NO_MAPPED_STRING ((VALUE)0)
|
51
51
|
|
52
|
+
#ifndef RB_ENC_INTERNED_STR_NULL_CHECK
|
53
|
+
#define RB_ENC_INTERNED_STR_NULL_CHECK 0
|
54
|
+
#endif
|
55
|
+
|
52
56
|
extern int msgpack_rb_encindex_utf8;
|
53
57
|
extern int msgpack_rb_encindex_usascii;
|
54
58
|
extern int msgpack_rb_encindex_ascii8bit;
|
@@ -456,7 +460,11 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
|
|
456
460
|
|
457
461
|
#ifdef HAVE_RB_ENC_INTERNED_STR
|
458
462
|
if (will_be_frozen) {
|
459
|
-
|
463
|
+
if (RB_ENC_INTERNED_STR_NULL_CHECK && length == 0) {
|
464
|
+
result = rb_enc_interned_str("", length, utf8 ? rb_utf8_encoding() : rb_ascii8bit_encoding());
|
465
|
+
} else {
|
466
|
+
result = rb_enc_interned_str(b->read_buffer, length, utf8 ? rb_utf8_encoding() : rb_ascii8bit_encoding());
|
467
|
+
}
|
460
468
|
} else {
|
461
469
|
if (utf8) {
|
462
470
|
result = rb_utf8_str_new(b->read_buffer, length);
|
data/ext/msgpack/compat.h
CHANGED
@@ -22,104 +22,5 @@
|
|
22
22
|
#include "ruby.h"
|
23
23
|
#include "ruby/encoding.h"
|
24
24
|
|
25
|
-
#if defined(HAVE_RUBY_ST_H)
|
26
|
-
# include "ruby/st.h" /* ruby hash on Ruby 1.9 */
|
27
|
-
#elif defined(HAVE_ST_H)
|
28
|
-
# include "st.h" /* ruby hash on Ruby 1.8 */
|
29
|
-
#endif
|
30
|
-
|
31
|
-
|
32
|
-
/*
|
33
|
-
* ZALLOC_N (ruby 2.2 or later)
|
34
|
-
*/
|
35
|
-
#ifndef RB_ZALLOC_N
|
36
|
-
# define RB_ZALLOC_N(type,n) ((type*)ruby_xcalloc((size_t)(n),sizeof(type)))
|
37
|
-
#endif
|
38
|
-
#ifndef ZALLOC_N
|
39
|
-
# define ZALLOC_N(type,n) RB_ZALLOC_N(type,n)
|
40
|
-
#endif
|
41
|
-
|
42
|
-
|
43
|
-
/*
|
44
|
-
* define STR_DUP_LIKELY_DOES_COPY
|
45
|
-
* check rb_str_dup actually copies the string or not
|
46
|
-
*/
|
47
|
-
#if defined(RUBY_VM) && defined(FL_ALL) && defined(FL_USER1) && defined(FL_USER3) /* MRI 1.9 */
|
48
|
-
# define STR_DUP_LIKELY_DOES_COPY(str) FL_ALL(str, FL_USER1|FL_USER3) /* same as STR_ASSOC_P(str) */
|
49
|
-
|
50
|
-
#elif defined(FL_TEST) && defined(ELTS_SHARED) /* MRI 1.8 */
|
51
|
-
# define STR_DUP_LIKELY_DOES_COPY(str) (!FL_TEST(str, ELTS_SHARED))
|
52
|
-
|
53
|
-
//#elif defined(RUBINIUS) || defined(JRUBY) /* Rubinius and JRuby */
|
54
|
-
#else
|
55
|
-
# define STR_DUP_LIKELY_DOES_COPY(str) (1)
|
56
|
-
|
57
|
-
#endif
|
58
|
-
|
59
|
-
|
60
|
-
/*
|
61
|
-
* SIZET2NUM
|
62
|
-
*/
|
63
|
-
#ifndef SIZET2NUM /* MRI 1.8 */
|
64
|
-
# define SIZET2NUM(v) ULL2NUM(v)
|
65
|
-
#endif
|
66
|
-
|
67
|
-
|
68
|
-
/*
|
69
|
-
* rb_errinfo()
|
70
|
-
*/
|
71
|
-
#if defined(RUBY_VM) /* MRI 1.9 */
|
72
|
-
# define COMPAT_RERAISE rb_exc_raise(rb_errinfo())
|
73
|
-
|
74
|
-
#elif defined(JRUBY) /* JRuby */
|
75
|
-
# define COMPAT_RERAISE rb_exc_raise(rb_gv_get("$!"))
|
76
|
-
|
77
|
-
#else /* MRI 1.8 and Rubinius */
|
78
|
-
# define COMPAT_RERAISE rb_exc_raise(ruby_errinfo)
|
79
|
-
#endif
|
80
|
-
|
81
|
-
|
82
|
-
/*
|
83
|
-
* RBIGNUM_POSITIVE_P
|
84
|
-
*/
|
85
|
-
#ifndef RBIGNUM_POSITIVE_P
|
86
|
-
# if defined(RUBINIUS) /* Rubinius <= v1.2.3 */
|
87
|
-
# define RBIGNUM_POSITIVE_P(b) (rb_funcall(b, rb_intern(">="), 1, INT2FIX(0)) == Qtrue)
|
88
|
-
|
89
|
-
# elif defined(JRUBY) /* JRuby */
|
90
|
-
# define RBIGNUM_POSITIVE_P(b) (rb_funcall(b, rb_intern(">="), 1, INT2FIX(0)) == Qtrue)
|
91
|
-
# define rb_big2ull(b) rb_num2ull(b)
|
92
|
-
/*#define rb_big2ll(b) rb_num2ll(b)*/
|
93
|
-
|
94
|
-
# else /* MRI 1.8 */
|
95
|
-
# define RBIGNUM_POSITIVE_P(b) (RBIGNUM(b)->sign)
|
96
|
-
# endif
|
97
|
-
#endif
|
98
|
-
|
99
|
-
|
100
|
-
/*
|
101
|
-
* RSTRING_PTR, RSTRING_LEN
|
102
|
-
*/
|
103
|
-
#ifndef RSTRING_PTR /* MRI 1.8.5 */
|
104
|
-
# define RSTRING_PTR(s) (RSTRING(s)->ptr)
|
105
|
-
#endif
|
106
|
-
|
107
|
-
#ifndef RSTRING_LEN /* MRI 1.8.5 */
|
108
|
-
# define RSTRING_LEN(s) (RSTRING(s)->len)
|
109
|
-
#endif
|
110
|
-
|
111
|
-
|
112
|
-
/*
|
113
|
-
* RSTRUCT_GET
|
114
|
-
*/
|
115
|
-
#ifndef RSTRUCT_GET
|
116
|
-
# ifdef RSTRUCT_PTR /* MRI <= 2.0.0 */
|
117
|
-
# define RSTRUCT_GET(st, idx) (RSTRUCT_PTR(st)[idx])
|
118
|
-
# else /* Rubinius */
|
119
|
-
# define RSTRUCT_GET(st, idx) (rb_struct_aref(st, INT2FIX(idx)))
|
120
|
-
# endif
|
121
|
-
#endif
|
122
|
-
|
123
|
-
|
124
25
|
#endif
|
125
26
|
|
data/ext/msgpack/extconf.rb
CHANGED
@@ -2,7 +2,8 @@ require 'mkmf'
|
|
2
2
|
|
3
3
|
have_header("ruby/st.h")
|
4
4
|
have_header("st.h")
|
5
|
-
have_func("rb_enc_interned_str", "ruby.h")
|
5
|
+
have_func("rb_enc_interned_str", "ruby.h") # Ruby 3.0+
|
6
|
+
have_func("rb_hash_new_capa", "ruby.h") # Ruby 3.2+
|
6
7
|
|
7
8
|
unless RUBY_PLATFORM.include? 'mswin'
|
8
9
|
$CFLAGS << %[ -I.. -Wall -O3 -g -std=gnu99]
|
@@ -12,14 +13,12 @@ end
|
|
12
13
|
#$CFLAGS << %[ -DDISABLE_BUFFER_READ_REFERENCE_OPTIMIZE]
|
13
14
|
#$CFLAGS << %[ -DDISABLE_BUFFER_READ_TO_S_OPTIMIZE]
|
14
15
|
|
15
|
-
if
|
16
|
-
#
|
17
|
-
$CFLAGS <<
|
18
|
-
# Rubinius C extensions don't grab GVL while rmem is not thread safe
|
19
|
-
$CFLAGS << %[ -DDISABLE_RMEM]
|
16
|
+
if RUBY_VERSION.start_with?('3.0.')
|
17
|
+
# https://bugs.ruby-lang.org/issues/18772
|
18
|
+
$CFLAGS << ' -DRB_ENC_INTERNED_STR_NULL_CHECK=1 '
|
20
19
|
end
|
21
20
|
|
22
|
-
# checking if Hash#[]= (rb_hash_aset) dedupes string keys
|
21
|
+
# checking if Hash#[]= (rb_hash_aset) dedupes string keys (Ruby 2.6+)
|
23
22
|
h = {}
|
24
23
|
x = {}
|
25
24
|
r = rand.to_s
|
@@ -32,7 +31,7 @@ else
|
|
32
31
|
end
|
33
32
|
|
34
33
|
|
35
|
-
# checking if String#-@ (str_uminus) dedupes... '
|
34
|
+
# checking if String#-@ (str_uminus) dedupes... ' (Ruby 2.5+)
|
36
35
|
begin
|
37
36
|
a = -(%w(t e s t).join)
|
38
37
|
b = -(%w(t e s t).join)
|
@@ -45,7 +44,7 @@ rescue NoMethodError
|
|
45
44
|
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
|
46
45
|
end
|
47
46
|
|
48
|
-
# checking if String#-@ (str_uminus) directly interns frozen strings... '
|
47
|
+
# checking if String#-@ (str_uminus) directly interns frozen strings... ' (Ruby 3.0+)
|
49
48
|
begin
|
50
49
|
s = rand.to_s.freeze
|
51
50
|
if (-s).equal?(s) && (-s.dup).equal?(s)
|
@@ -62,4 +61,3 @@ if warnflags = CONFIG['warnflags']
|
|
62
61
|
end
|
63
62
|
|
64
63
|
create_makefile('msgpack/msgpack')
|
65
|
-
|
data/ext/msgpack/packer.c
CHANGED
@@ -18,24 +18,10 @@
|
|
18
18
|
|
19
19
|
#include "packer.h"
|
20
20
|
|
21
|
-
#ifdef RUBINIUS
|
22
|
-
static ID s_to_iter;
|
23
|
-
static ID s_next;
|
24
|
-
static ID s_key;
|
25
|
-
static ID s_value;
|
26
|
-
#endif
|
27
|
-
|
28
21
|
static ID s_call;
|
29
22
|
|
30
23
|
void msgpack_packer_static_init()
|
31
24
|
{
|
32
|
-
#ifdef RUBINIUS
|
33
|
-
s_to_iter = rb_intern("to_iter");
|
34
|
-
s_next = rb_intern("next");
|
35
|
-
s_key = rb_intern("key");
|
36
|
-
s_value = rb_intern("value");
|
37
|
-
#endif
|
38
|
-
|
39
25
|
s_call = rb_intern("call");
|
40
26
|
}
|
41
27
|
|
@@ -108,17 +94,7 @@ void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v)
|
|
108
94
|
unsigned int len32 = (unsigned int)len;
|
109
95
|
msgpack_packer_write_map_header(pk, len32);
|
110
96
|
|
111
|
-
#ifdef RUBINIUS
|
112
|
-
VALUE iter = rb_funcall(v, s_to_iter, 0);
|
113
|
-
VALUE entry = Qnil;
|
114
|
-
while(RTEST(entry = rb_funcall(iter, s_next, 1, entry))) {
|
115
|
-
VALUE key = rb_funcall(entry, s_key, 0);
|
116
|
-
VALUE val = rb_funcall(entry, s_value, 0);
|
117
|
-
write_hash_foreach(key, val, (VALUE) pk);
|
118
|
-
}
|
119
|
-
#else
|
120
97
|
rb_hash_foreach(v, write_hash_foreach, (VALUE) pk);
|
121
|
-
#endif
|
122
98
|
}
|
123
99
|
|
124
100
|
struct msgpack_call_proc_args_t;
|
data/ext/msgpack/packer.h
CHANGED
@@ -408,13 +408,7 @@ static inline bool msgpack_packer_is_utf8_compat_string(VALUE v, int encindex)
|
|
408
408
|
{
|
409
409
|
return encindex == msgpack_rb_encindex_utf8
|
410
410
|
|| encindex == msgpack_rb_encindex_usascii
|
411
|
-
|
412
|
-
/* Because ENC_CODERANGE_ASCIIONLY does not scan string, it may return ENC_CODERANGE_UNKNOWN unlike */
|
413
|
-
/* rb_enc_str_asciionly_p. It is always faster than rb_str_encode if it is available. */
|
414
|
-
/* Very old Rubinius (< v1.3.1) doesn't have ENC_CODERANGE_ASCIIONLY. */
|
415
|
-
|| (rb_enc_asciicompat(rb_enc_from_index(encindex)) && ENC_CODERANGE_ASCIIONLY(v))
|
416
|
-
#endif
|
417
|
-
;
|
411
|
+
|| (rb_enc_asciicompat(rb_enc_from_index(encindex)) && ENC_CODERANGE_ASCIIONLY(v));
|
418
412
|
}
|
419
413
|
|
420
414
|
static inline void msgpack_packer_write_string_value(msgpack_packer_t* pk, VALUE v)
|
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
|
@@ -52,6 +59,16 @@ 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
|
+
#ifdef UNPACKER_STACK_RMEM
|
64
|
+
return msgpack_rmem_alloc(&s_stack_rmem);
|
65
|
+
/*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
|
66
|
+
#else
|
67
|
+
/*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_t));*/
|
68
|
+
return xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_t));
|
69
|
+
#endif
|
70
|
+
}
|
71
|
+
|
55
72
|
msgpack_unpacker_t* _msgpack_unpacker_new(void)
|
56
73
|
{
|
57
74
|
msgpack_unpacker_t* uk = ZALLOC_N(msgpack_unpacker_t, 1);
|
@@ -63,26 +80,23 @@ msgpack_unpacker_t* _msgpack_unpacker_new(void)
|
|
63
80
|
uk->last_object = Qnil;
|
64
81
|
uk->reading_raw = Qnil;
|
65
82
|
|
66
|
-
|
67
|
-
uk->stack = msgpack_rmem_alloc(&s_stack_rmem);
|
68
|
-
/*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
|
69
|
-
#else
|
70
|
-
/*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_t));*/
|
71
|
-
uk->stack = xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_t));
|
72
|
-
#endif
|
83
|
+
uk->stack = _msgpack_unpacker_new_stack();
|
73
84
|
uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
74
85
|
|
75
86
|
return uk;
|
76
87
|
}
|
77
88
|
|
89
|
+
static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
|
90
|
+
#ifdef UNPACKER_STACK_RMEM
|
91
|
+
msgpack_rmem_free(&s_stack_rmem, stack);
|
92
|
+
#else
|
93
|
+
xfree(stack);
|
94
|
+
#endif
|
95
|
+
}
|
96
|
+
|
78
97
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
|
79
98
|
{
|
80
|
-
|
81
|
-
msgpack_rmem_free(&s_stack_rmem, uk->stack);
|
82
|
-
#else
|
83
|
-
xfree(uk->stack);
|
84
|
-
#endif
|
85
|
-
|
99
|
+
_msgpack_unpacker_free_stack(uk->stack);
|
86
100
|
msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
|
87
101
|
}
|
88
102
|
|
@@ -295,10 +309,23 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
295
309
|
VALUE obj;
|
296
310
|
uk->last_object = Qnil;
|
297
311
|
reset_head_byte(uk);
|
298
|
-
size_t ext_size = uk->reading_raw_remaining;
|
299
312
|
uk->reading_raw_remaining = 0;
|
313
|
+
|
314
|
+
msgpack_unpacker_stack_t* stack = uk->stack;
|
315
|
+
size_t stack_depth = uk->stack_depth;
|
316
|
+
size_t stack_capacity = uk->stack_capacity;
|
317
|
+
|
318
|
+
uk->stack = _msgpack_unpacker_new_stack();
|
319
|
+
uk->stack_depth = 0;
|
320
|
+
uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
321
|
+
|
300
322
|
obj = rb_funcall(proc, s_call, 1, uk->buffer.owner);
|
301
|
-
|
323
|
+
|
324
|
+
_msgpack_unpacker_free_stack(uk->stack);
|
325
|
+
uk->stack = stack;
|
326
|
+
uk->stack_depth = stack_depth;
|
327
|
+
uk->stack_capacity = stack_capacity;
|
328
|
+
|
302
329
|
return object_complete(uk, obj);
|
303
330
|
}
|
304
331
|
}
|
@@ -351,9 +378,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
351
378
|
|
352
379
|
SWITCH_RANGE(b, 0xa0, 0xbf) // FixRaw / fixstr
|
353
380
|
int count = b & 0x1f;
|
354
|
-
if(count == 0) {
|
355
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
356
|
-
}
|
357
381
|
/* read_raw_body_begin sets uk->reading_raw */
|
358
382
|
uk->reading_raw_remaining = count;
|
359
383
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -370,7 +394,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
370
394
|
if(count == 0) {
|
371
395
|
return object_complete(uk, rb_hash_new());
|
372
396
|
}
|
373
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
397
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
374
398
|
|
375
399
|
SWITCH_RANGE(b, 0xc0, 0xdf) // Variable
|
376
400
|
switch(b) {
|
@@ -536,9 +560,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
536
560
|
{
|
537
561
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
538
562
|
uint8_t count = cb->u8;
|
539
|
-
if(count == 0) {
|
540
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
541
|
-
}
|
542
563
|
/* read_raw_body_begin sets uk->reading_raw */
|
543
564
|
uk->reading_raw_remaining = count;
|
544
565
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -548,9 +569,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
548
569
|
{
|
549
570
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
550
571
|
uint16_t count = _msgpack_be16(cb->u16);
|
551
|
-
if(count == 0) {
|
552
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
553
|
-
}
|
554
572
|
/* read_raw_body_begin sets uk->reading_raw */
|
555
573
|
uk->reading_raw_remaining = count;
|
556
574
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -560,9 +578,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
560
578
|
{
|
561
579
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
562
580
|
uint32_t count = _msgpack_be32(cb->u32);
|
563
|
-
if(count == 0) {
|
564
|
-
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
565
|
-
}
|
566
581
|
/* read_raw_body_begin sets uk->reading_raw */
|
567
582
|
uk->reading_raw_remaining = count;
|
568
583
|
return read_raw_body_begin(uk, RAW_TYPE_STRING);
|
@@ -572,9 +587,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
572
587
|
{
|
573
588
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
574
589
|
uint8_t count = cb->u8;
|
575
|
-
if(count == 0) {
|
576
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
577
|
-
}
|
578
590
|
/* read_raw_body_begin sets uk->reading_raw */
|
579
591
|
uk->reading_raw_remaining = count;
|
580
592
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -584,9 +596,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
584
596
|
{
|
585
597
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
586
598
|
uint16_t count = _msgpack_be16(cb->u16);
|
587
|
-
if(count == 0) {
|
588
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
589
|
-
}
|
590
599
|
/* read_raw_body_begin sets uk->reading_raw */
|
591
600
|
uk->reading_raw_remaining = count;
|
592
601
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -596,9 +605,6 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
596
605
|
{
|
597
606
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
598
607
|
uint32_t count = _msgpack_be32(cb->u32);
|
599
|
-
if(count == 0) {
|
600
|
-
return object_complete(uk, rb_str_new_static("", 0));
|
601
|
-
}
|
602
608
|
/* read_raw_body_begin sets uk->reading_raw */
|
603
609
|
uk->reading_raw_remaining = count;
|
604
610
|
return read_raw_body_begin(uk, RAW_TYPE_BINARY);
|
@@ -631,7 +637,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
631
637
|
if(count == 0) {
|
632
638
|
return object_complete(uk, rb_hash_new());
|
633
639
|
}
|
634
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
640
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
635
641
|
}
|
636
642
|
|
637
643
|
case 0xdf: // map 32
|
@@ -641,7 +647,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
641
647
|
if(count == 0) {
|
642
648
|
return object_complete(uk, rb_hash_new());
|
643
649
|
}
|
644
|
-
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2,
|
650
|
+
return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
|
645
651
|
}
|
646
652
|
|
647
653
|
default:
|
data/lib/msgpack/version.rb
CHANGED
data/spec/factory_spec.rb
CHANGED
@@ -422,6 +422,33 @@ 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
|
+
]
|
431
|
+
end
|
432
|
+
|
433
|
+
it 'can be nested' do
|
434
|
+
factory = MessagePack::Factory.new
|
435
|
+
factory.register_type(
|
436
|
+
0x02,
|
437
|
+
Set,
|
438
|
+
packer: ->(set, packer) do
|
439
|
+
packer.write(set.to_a)
|
440
|
+
nil
|
441
|
+
end,
|
442
|
+
unpacker: ->(unpacker) do
|
443
|
+
unpacker.read.to_set
|
444
|
+
end,
|
445
|
+
recursive: true,
|
446
|
+
)
|
447
|
+
|
448
|
+
expected = Set[1, Set[2, Set[3]]]
|
449
|
+
payload = factory.dump(expected)
|
450
|
+
expect(payload).to be == "\xC7\v\x02\x92\x01\xC7\x06\x02\x92\x02\xD5\x02\x91\x03".b
|
451
|
+
expect(factory.load(factory.dump(expected))).to be == expected
|
425
452
|
end
|
426
453
|
end
|
427
454
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require "set"
|
1
2
|
|
2
3
|
if ENV['SIMPLE_COV']
|
3
4
|
require 'simplecov'
|
@@ -19,7 +20,11 @@ require "msgpack/bigint"
|
|
19
20
|
if GC.respond_to?(:verify_compaction_references)
|
20
21
|
# This method was added in Ruby 3.0.0. Calling it this way asks the GC to
|
21
22
|
# move objects around, helping to find object movement bugs.
|
22
|
-
|
23
|
+
begin
|
24
|
+
GC.verify_compaction_references(double_heap: true, toward: :empty)
|
25
|
+
rescue NotImplementedError
|
26
|
+
# Some platforms don't support compaction
|
27
|
+
end
|
23
28
|
end
|
24
29
|
|
25
30
|
if GC.respond_to?(:auto_compact=)
|
@@ -28,6 +33,8 @@ end
|
|
28
33
|
|
29
34
|
IS_JRUBY = RUBY_ENGINE == 'jruby'
|
30
35
|
|
36
|
+
IS_TRUFFLERUBY = RUBY_ENGINE == 'truffleruby'
|
37
|
+
|
31
38
|
# checking if Hash#[]= (rb_hash_aset) dedupes string keys
|
32
39
|
def automatic_string_keys_deduplication?
|
33
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.3
|
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-07-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -231,7 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
231
231
|
- !ruby/object:Gem::Version
|
232
232
|
version: '0'
|
233
233
|
requirements: []
|
234
|
-
rubygems_version: 3.
|
234
|
+
rubygems_version: 3.1.2
|
235
235
|
signing_key:
|
236
236
|
specification_version: 4
|
237
237
|
summary: MessagePack, a binary-based efficient data interchange format.
|