msgpack 1.4.4 → 1.4.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yaml +4 -3
- data/ChangeLog +8 -0
- data/doclib/msgpack/factory.rb +1 -1
- data/doclib/msgpack/packer.rb +5 -4
- data/doclib/msgpack/unpacker.rb +2 -2
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +9 -14
- data/ext/msgpack/buffer.h +2 -2
- data/ext/msgpack/buffer_class.c +11 -12
- data/ext/msgpack/factory_class.c +16 -11
- data/ext/msgpack/packer_class.c +7 -3
- data/ext/msgpack/packer_ext_registry.c +13 -8
- data/ext/msgpack/packer_ext_registry.h +30 -28
- data/ext/msgpack/unpacker.c +12 -14
- data/ext/msgpack/unpacker.h +2 -2
- data/ext/msgpack/unpacker_class.c +12 -40
- data/ext/msgpack/unpacker_ext_registry.c +38 -15
- data/ext/msgpack/unpacker_ext_registry.h +16 -12
- data/lib/msgpack/symbol.rb +8 -1
- data/lib/msgpack/version.rb +1 -1
- data/spec/factory_spec.rb +70 -14
- data/spec/spec_helper.rb +2 -4
- data/spec/timestamp_spec.rb +0 -2
- data/spec/unpacker_spec.rb +22 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a51f64e1c017cafcef6fe080992135f5c610984ecd126f4a3a2127baa4e4a644
|
4
|
+
data.tar.gz: bf45726e8f6cb658390199ecb51345e034c908207b090d53934f037555d7c37a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ee24ab0cb11c648e9a022f23053c118c020b7c79cac14e00a1bb82faf90c59302727a2dc691c63a959225b06a5c40ec5e09fd8f35154c7474b1e652e27b9bc5
|
7
|
+
data.tar.gz: 2fee550949875cc119f1865b9519c75794124ec17065b1da1ec0fd06af29ed7fbdd37d709bf8cdb217d3cf86e3004a18fab16a6ac032eec176735725439ec268
|
data/.github/workflows/ci.yaml
CHANGED
@@ -12,6 +12,7 @@ on:
|
|
12
12
|
jobs:
|
13
13
|
mri:
|
14
14
|
strategy:
|
15
|
+
fail-fast: false
|
15
16
|
matrix:
|
16
17
|
os: [ubuntu, macos, windows]
|
17
18
|
ruby: ['2.4', '2.5', '2.6', '2.7', '3.0', '3.1']
|
@@ -26,11 +27,10 @@ jobs:
|
|
26
27
|
|
27
28
|
jruby:
|
28
29
|
strategy:
|
30
|
+
fail-fast: false
|
29
31
|
matrix:
|
30
32
|
os: [ubuntu]
|
31
|
-
|
32
|
-
# https://github.com/ruby/setup-ruby#supported-versions
|
33
|
-
ruby: ['jruby-9.2.19.0', 'jruby-9.3.2.0']
|
33
|
+
ruby: ['jruby-9.2.19.0', 'jruby-9.3.3.0']
|
34
34
|
runs-on: ${{ matrix.os }}-latest
|
35
35
|
steps:
|
36
36
|
- uses: actions/checkout@v2
|
@@ -43,6 +43,7 @@ jobs:
|
|
43
43
|
head-versions:
|
44
44
|
continue-on-error: true
|
45
45
|
strategy:
|
46
|
+
fail-fast: false
|
46
47
|
matrix:
|
47
48
|
os: [ubuntu]
|
48
49
|
ruby: ['ruby-head', 'jruby-head', 'truffleruby']
|
data/ChangeLog
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
2022-02-15 version 1.4.5:
|
2
|
+
|
3
|
+
* Fix to create UTF-8 Symbol keys when symbolize_keys: true
|
4
|
+
* Fix to assume Symbols as US-ASCII or UTF-8
|
5
|
+
* Optimize Packer/Unpacker initialization
|
6
|
+
* Optimize extension class lookup
|
7
|
+
* Rename Packer#clear as Packer#reset (#clear is still available as an alias)
|
8
|
+
|
1
9
|
2022-01-22 version 1.4.4:
|
2
10
|
|
3
11
|
* Specify the build option --platform=8 for older Java platforms
|
data/doclib/msgpack/factory.rb
CHANGED
@@ -63,7 +63,7 @@ module MessagePack
|
|
63
63
|
|
64
64
|
#
|
65
65
|
# Register a type and Class to be registered for packer and/or unpacker.
|
66
|
-
# If options are not
|
66
|
+
# If options are not specified, factory will use :to_msgpack_ext for packer, and
|
67
67
|
# :from_msgpack_ext for unpacker.
|
68
68
|
#
|
69
69
|
# @param type [Fixnum] type id of registered Class (0-127)
|
data/doclib/msgpack/packer.rb
CHANGED
@@ -14,7 +14,7 @@ module MessagePack
|
|
14
14
|
# @overload initialize(io, options={})
|
15
15
|
# @param io [IO]
|
16
16
|
# @param options [Hash]
|
17
|
-
# This packer writes
|
17
|
+
# This packer writes serialized objects into the IO when the internal buffer is filled.
|
18
18
|
# _io_ must respond to write(string) or append(string) method.
|
19
19
|
#
|
20
20
|
# Supported options:
|
@@ -33,12 +33,12 @@ module MessagePack
|
|
33
33
|
#
|
34
34
|
# @overload register_type(type, klass, &block)
|
35
35
|
# @param type [Fixnum] type id (0-127) user defined type id for specified Class
|
36
|
-
# @param klass [Class] Class to be serialized with
|
36
|
+
# @param klass [Class] Class to be serialized with specified type id
|
37
37
|
# @yieldparam object [Object] object to be serialized
|
38
38
|
#
|
39
39
|
# @overload register_type(type, klass, method_name)
|
40
40
|
# @param type [Fixnum] type id (0-127) user defined type id for specified Class
|
41
|
-
# @param klass [Class] Class to be serialized with
|
41
|
+
# @param klass [Class] Class to be serialized with specified type id
|
42
42
|
# @param method_name [Symbol] method which returns bytes of serialized representation
|
43
43
|
#
|
44
44
|
# @return nil
|
@@ -155,8 +155,9 @@ module MessagePack
|
|
155
155
|
#
|
156
156
|
# @return nil
|
157
157
|
#
|
158
|
-
def
|
158
|
+
def reset
|
159
159
|
end
|
160
|
+
alias clear reset
|
160
161
|
|
161
162
|
#
|
162
163
|
# Returns size of the internal buffer. Same as buffer.size.
|
data/doclib/msgpack/unpacker.rb
CHANGED
@@ -36,7 +36,7 @@ module MessagePack
|
|
36
36
|
#
|
37
37
|
# @overload register_type(type, klass, class_method_name)
|
38
38
|
# @param type [Fixnum] type id (0-127) user defined type id for specified Class
|
39
|
-
# @param klass [Class] Class to be serialized with
|
39
|
+
# @param klass [Class] Class to be serialized with specified type id
|
40
40
|
# @param class_method_name [Symbol] class method which returns an instance object
|
41
41
|
#
|
42
42
|
# @return nil
|
@@ -149,7 +149,7 @@ module MessagePack
|
|
149
149
|
#
|
150
150
|
# It repeats until the io or internal buffer does not include any complete objects.
|
151
151
|
#
|
152
|
-
# If
|
152
|
+
# If an IO is set, it repeats to read data from the IO when the buffer
|
153
153
|
# becomes empty until the IO raises EOFError.
|
154
154
|
#
|
155
155
|
# This method could raise same errors with _read_ excepting EOFError.
|
@@ -82,26 +82,21 @@ public class ExtensionRegistry {
|
|
82
82
|
* Objects of type Integer (Fixnum, Bignum), Float, Symbol and frozen
|
83
83
|
* String have no singleton class and raise a TypeError when trying to get
|
84
84
|
* it.
|
85
|
-
*
|
86
|
-
* Since all but symbols are already filtered out when reaching this code
|
87
|
-
* only symbols are checked here.
|
88
85
|
*/
|
89
|
-
|
90
|
-
|
91
|
-
pair = fetchEntryByModule(lookupClass);
|
92
|
-
if (pair != null) {
|
93
|
-
return pair;
|
94
|
-
}
|
95
|
-
}
|
96
|
-
|
97
|
-
pair = fetchEntryByModule(object.getType());
|
86
|
+
lookupClass = object.getMetaClass();
|
87
|
+
pair = fetchEntryByModule(lookupClass);
|
98
88
|
if (pair != null) {
|
99
89
|
return pair;
|
100
90
|
}
|
101
91
|
|
102
|
-
|
103
|
-
|
92
|
+
RubyModule realClass = object.getType();
|
93
|
+
if (realClass != lookupClass) {
|
94
|
+
pair = fetchEntryByModule(realClass);
|
95
|
+
if (pair != null) {
|
96
|
+
return pair;
|
97
|
+
}
|
104
98
|
}
|
99
|
+
|
105
100
|
ExtensionEntry e = findEntryByModuleOrAncestor(lookupClass);
|
106
101
|
if (e != null && e.hasPacker()) {
|
107
102
|
extensionsByAncestor.put(e.getExtensionModule(), e);
|
data/ext/msgpack/buffer.h
CHANGED
@@ -494,9 +494,9 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
|
|
494
494
|
#endif // HAVE_RB_ENC_INTERNED_STR
|
495
495
|
}
|
496
496
|
|
497
|
-
static inline VALUE msgpack_buffer_read_top_as_symbol(msgpack_buffer_t* b, size_t length)
|
497
|
+
static inline VALUE msgpack_buffer_read_top_as_symbol(msgpack_buffer_t* b, size_t length, bool utf8)
|
498
498
|
{
|
499
|
-
return rb_str_intern(msgpack_buffer_read_top_as_string(b, length, true,
|
499
|
+
return rb_str_intern(msgpack_buffer_read_top_as_string(b, length, true, utf8));
|
500
500
|
}
|
501
501
|
|
502
502
|
#endif
|
data/ext/msgpack/buffer_class.c
CHANGED
@@ -62,24 +62,22 @@ static VALUE Buffer_alloc(VALUE klass)
|
|
62
62
|
|
63
63
|
static ID get_partial_read_method(VALUE io)
|
64
64
|
{
|
65
|
-
if(rb_respond_to(io, s_readpartial)) {
|
65
|
+
if(io != Qnil && rb_respond_to(io, s_readpartial)) {
|
66
66
|
return s_readpartial;
|
67
|
-
} else if(rb_respond_to(io, s_read)) {
|
68
|
-
return s_read;
|
69
|
-
} else {
|
70
|
-
return s_read;
|
71
67
|
}
|
68
|
+
return s_read;
|
72
69
|
}
|
73
70
|
|
74
71
|
static ID get_write_all_method(VALUE io)
|
75
72
|
{
|
76
|
-
if(
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
73
|
+
if(io != Qnil) {
|
74
|
+
if(rb_respond_to(io, s_write)) {
|
75
|
+
return s_write;
|
76
|
+
} else if(rb_respond_to(io, s_append)) {
|
77
|
+
return s_append;
|
78
|
+
}
|
82
79
|
}
|
80
|
+
return s_write;
|
83
81
|
}
|
84
82
|
|
85
83
|
void MessagePack_Buffer_set_options(msgpack_buffer_t* b, VALUE io, VALUE options)
|
@@ -245,10 +243,11 @@ static VALUE read_until_eof_rescue(VALUE args)
|
|
245
243
|
return Qnil;
|
246
244
|
}
|
247
245
|
|
248
|
-
static VALUE read_until_eof_error(VALUE args)
|
246
|
+
static VALUE read_until_eof_error(VALUE args, VALUE error)
|
249
247
|
{
|
250
248
|
/* ignore EOFError */
|
251
249
|
UNUSED(args);
|
250
|
+
UNUSED(error);
|
252
251
|
return Qnil;
|
253
252
|
}
|
254
253
|
|
data/ext/msgpack/factory_class.c
CHANGED
@@ -30,7 +30,7 @@ typedef struct msgpack_factory_t msgpack_factory_t;
|
|
30
30
|
|
31
31
|
struct msgpack_factory_t {
|
32
32
|
msgpack_packer_ext_registry_t pkrg;
|
33
|
-
msgpack_unpacker_ext_registry_t ukrg;
|
33
|
+
msgpack_unpacker_ext_registry_t *ukrg;
|
34
34
|
bool has_symbol_ext_type;
|
35
35
|
bool optimized_symbol_ext_type;
|
36
36
|
int symbol_ext_type;
|
@@ -49,14 +49,14 @@ static void Factory_free(msgpack_factory_t* fc)
|
|
49
49
|
return;
|
50
50
|
}
|
51
51
|
msgpack_packer_ext_registry_destroy(&fc->pkrg);
|
52
|
-
|
52
|
+
msgpack_unpacker_ext_registry_release(fc->ukrg);
|
53
53
|
xfree(fc);
|
54
54
|
}
|
55
55
|
|
56
56
|
void Factory_mark(msgpack_factory_t* fc)
|
57
57
|
{
|
58
58
|
msgpack_packer_ext_registry_mark(&fc->pkrg);
|
59
|
-
msgpack_unpacker_ext_registry_mark(
|
59
|
+
msgpack_unpacker_ext_registry_mark(fc->ukrg);
|
60
60
|
}
|
61
61
|
|
62
62
|
static VALUE Factory_alloc(VALUE klass)
|
@@ -72,7 +72,7 @@ static VALUE Factory_initialize(int argc, VALUE* argv, VALUE self)
|
|
72
72
|
FACTORY(self, fc);
|
73
73
|
|
74
74
|
msgpack_packer_ext_registry_init(&fc->pkrg);
|
75
|
-
|
75
|
+
// fc->ukrg is lazily initialized
|
76
76
|
|
77
77
|
fc->has_symbol_ext_type = false;
|
78
78
|
|
@@ -113,9 +113,7 @@ VALUE MessagePack_Factory_unpacker(int argc, VALUE* argv, VALUE self)
|
|
113
113
|
|
114
114
|
msgpack_unpacker_t* uk;
|
115
115
|
Data_Get_Struct(unpacker, msgpack_unpacker_t, uk);
|
116
|
-
|
117
|
-
msgpack_unpacker_ext_registry_destroy(&uk->ext_registry);
|
118
|
-
msgpack_unpacker_ext_registry_dup(&fc->ukrg, &uk->ext_registry);
|
116
|
+
msgpack_unpacker_ext_registry_borrow(fc->ukrg, &uk->ext_registry);
|
119
117
|
uk->optimized_symbol_ext_type = fc->optimized_symbol_ext_type;
|
120
118
|
uk->symbol_ext_type = fc->symbol_ext_type;
|
121
119
|
|
@@ -127,12 +125,19 @@ static VALUE Factory_registered_types_internal(VALUE self)
|
|
127
125
|
FACTORY(self, fc);
|
128
126
|
|
129
127
|
VALUE uk_mapping = rb_hash_new();
|
130
|
-
|
131
|
-
|
132
|
-
|
128
|
+
if (fc->ukrg) {
|
129
|
+
for(int i=0; i < 256; i++) {
|
130
|
+
if(fc->ukrg->array[i] != Qnil) {
|
131
|
+
rb_hash_aset(uk_mapping, INT2FIX(i - 128), fc->ukrg->array[i]);
|
132
|
+
}
|
133
133
|
}
|
134
134
|
}
|
135
|
-
|
135
|
+
|
136
|
+
return rb_ary_new3(
|
137
|
+
2,
|
138
|
+
RTEST(fc->pkrg.hash) ? rb_hash_dup(fc->pkrg.hash) : rb_hash_new(),
|
139
|
+
uk_mapping
|
140
|
+
);
|
136
141
|
}
|
137
142
|
|
138
143
|
static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
data/ext/msgpack/packer_class.c
CHANGED
@@ -281,7 +281,7 @@ static VALUE Packer_flush(VALUE self)
|
|
281
281
|
return self;
|
282
282
|
}
|
283
283
|
|
284
|
-
static VALUE
|
284
|
+
static VALUE Packer_reset(VALUE self)
|
285
285
|
{
|
286
286
|
PACKER(self, pk);
|
287
287
|
msgpack_buffer_clear(PACKER_BUFFER_(pk));
|
@@ -339,7 +339,10 @@ static VALUE Packer_write_to(VALUE self, VALUE io)
|
|
339
339
|
static VALUE Packer_registered_types_internal(VALUE self)
|
340
340
|
{
|
341
341
|
PACKER(self, pk);
|
342
|
-
|
342
|
+
if (RTEST(pk->ext_registry.hash)) {
|
343
|
+
return rb_hash_dup(pk->ext_registry.hash);
|
344
|
+
}
|
345
|
+
return rb_hash_new();
|
343
346
|
}
|
344
347
|
|
345
348
|
static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
|
@@ -440,7 +443,8 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
|
|
440
443
|
rb_define_method(cMessagePack_Packer, "flush", Packer_flush, 0);
|
441
444
|
|
442
445
|
/* delegation methods */
|
443
|
-
rb_define_method(cMessagePack_Packer, "
|
446
|
+
rb_define_method(cMessagePack_Packer, "reset", Packer_reset, 0);
|
447
|
+
rb_define_alias(cMessagePack_Packer, "clear", "reset");
|
444
448
|
rb_define_method(cMessagePack_Packer, "size", Packer_size, 0);
|
445
449
|
rb_define_method(cMessagePack_Packer, "empty?", Packer_empty_p, 0);
|
446
450
|
rb_define_method(cMessagePack_Packer, "write_to", Packer_write_to, 1);
|
@@ -30,8 +30,8 @@ void msgpack_packer_ext_registry_static_destroy()
|
|
30
30
|
|
31
31
|
void msgpack_packer_ext_registry_init(msgpack_packer_ext_registry_t* pkrg)
|
32
32
|
{
|
33
|
-
pkrg->hash =
|
34
|
-
pkrg->cache =
|
33
|
+
pkrg->hash = Qnil;
|
34
|
+
pkrg->cache = Qnil;
|
35
35
|
}
|
36
36
|
|
37
37
|
void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
|
@@ -43,15 +43,20 @@ void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
|
|
43
43
|
void msgpack_packer_ext_registry_dup(msgpack_packer_ext_registry_t* src,
|
44
44
|
msgpack_packer_ext_registry_t* dst)
|
45
45
|
{
|
46
|
-
dst->hash = rb_hash_dup(src->hash);
|
47
|
-
dst->cache = rb_hash_dup(src->cache);
|
46
|
+
dst->hash = RTEST(src->hash) ? rb_hash_dup(src->hash) : Qnil;
|
47
|
+
dst->cache = RTEST(src->cache) ? rb_hash_dup(src->cache): Qnil;
|
48
48
|
}
|
49
49
|
|
50
50
|
VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
|
51
51
|
VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
|
52
52
|
{
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
53
|
+
if (!RTEST(pkrg->hash)) {
|
54
|
+
pkrg->hash = rb_hash_new();
|
55
|
+
}
|
56
|
+
|
57
|
+
if (RTEST(pkrg->cache)) {
|
58
|
+
/* clear lookup cache not to miss added type */
|
59
|
+
rb_hash_clear(pkrg->cache);
|
60
|
+
}
|
61
|
+
return rb_hash_aset(pkrg->hash, ext_module, rb_ary_new3(3, INT2FIX(ext_type), proc, arg));
|
57
62
|
}
|
@@ -70,10 +70,12 @@ static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registr
|
|
70
70
|
}
|
71
71
|
|
72
72
|
// fetch lookup_class from cache, which stores results of searching ancestors from pkrg->hash
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
73
|
+
if (RTEST(pkrg->cache)) {
|
74
|
+
VALUE type_inht = rb_hash_lookup(pkrg->cache, lookup_class);
|
75
|
+
if(type_inht != Qnil) {
|
76
|
+
*ext_type_result = FIX2INT(rb_ary_entry(type_inht, 0));
|
77
|
+
return rb_ary_entry(type_inht, 1);
|
78
|
+
}
|
77
79
|
}
|
78
80
|
|
79
81
|
return Qnil;
|
@@ -82,37 +84,34 @@ static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registr
|
|
82
84
|
static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_registry_t* pkrg,
|
83
85
|
VALUE instance, int* ext_type_result)
|
84
86
|
{
|
85
|
-
VALUE lookup_class;
|
86
87
|
VALUE type;
|
87
88
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
* Objects of type Integer (Fixnum, Bignum), Float, Symbol and frozen
|
92
|
-
* String have no singleton class and raise a TypeError when trying to get
|
93
|
-
* it. See implementation of #singleton_class in ruby's source code:
|
94
|
-
* VALUE rb_singleton_class(VALUE obj);
|
95
|
-
*
|
96
|
-
* Since all but symbols are already filtered out when reaching this code
|
97
|
-
* only symbols are checked here.
|
98
|
-
*/
|
99
|
-
if (!SYMBOL_P(instance)) {
|
100
|
-
lookup_class = rb_singleton_class(instance);
|
101
|
-
|
102
|
-
type = msgpack_packer_ext_registry_fetch(pkrg, lookup_class, ext_type_result);
|
89
|
+
if (pkrg->hash == Qnil) { // No extensions registered
|
90
|
+
return Qnil;
|
91
|
+
}
|
103
92
|
|
104
|
-
|
105
|
-
|
106
|
-
|
93
|
+
/*
|
94
|
+
* 1. check whether singleton_class or class of this instance is registered (or resolved in past) or not.
|
95
|
+
*
|
96
|
+
* Objects of type Integer (Fixnum, Bignum), Float, Symbol and frozen
|
97
|
+
* `rb_class_of` returns the singleton_class if the object has one, or the "real class" otherwise.
|
98
|
+
*/
|
99
|
+
VALUE lookup_class = rb_class_of(instance);
|
100
|
+
type = msgpack_packer_ext_registry_fetch(pkrg, lookup_class, ext_type_result);
|
101
|
+
if(type != Qnil) {
|
102
|
+
return type;
|
107
103
|
}
|
108
104
|
|
109
105
|
/*
|
110
|
-
* 2. check the class of instance is registered
|
106
|
+
* 2. If the object had a singleton_class check if the real class of instance is registered
|
107
|
+
* (or resolved in past) or not.
|
111
108
|
*/
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
109
|
+
VALUE real_class = rb_obj_class(instance);
|
110
|
+
if(lookup_class != real_class) {
|
111
|
+
type = msgpack_packer_ext_registry_fetch(pkrg, real_class, ext_type_result);
|
112
|
+
if(type != Qnil) {
|
113
|
+
return type;
|
114
|
+
}
|
116
115
|
}
|
117
116
|
|
118
117
|
/*
|
@@ -126,6 +125,9 @@ static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_regist
|
|
126
125
|
VALUE superclass = args[1];
|
127
126
|
if(superclass != Qnil) {
|
128
127
|
VALUE superclass_type = rb_hash_lookup(pkrg->hash, superclass);
|
128
|
+
if (!RTEST(pkrg->cache)) {
|
129
|
+
pkrg->cache = rb_hash_new();
|
130
|
+
}
|
129
131
|
rb_hash_aset(pkrg->cache, lookup_class, superclass_type);
|
130
132
|
*ext_type_result = FIX2INT(rb_ary_entry(superclass_type, 0));
|
131
133
|
return rb_ary_entry(superclass_type, 1);
|
data/ext/msgpack/unpacker.c
CHANGED
@@ -52,9 +52,9 @@ void msgpack_unpacker_static_destroy()
|
|
52
52
|
|
53
53
|
#define HEAD_BYTE_REQUIRED 0xc1
|
54
54
|
|
55
|
-
|
55
|
+
msgpack_unpacker_t* _msgpack_unpacker_new(void)
|
56
56
|
{
|
57
|
-
|
57
|
+
msgpack_unpacker_t* uk = ZALLOC_N(msgpack_unpacker_t, 1);
|
58
58
|
|
59
59
|
msgpack_buffer_init(UNPACKER_BUFFER_(uk));
|
60
60
|
|
@@ -71,6 +71,8 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
|
71
71
|
uk->stack = xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_t));
|
72
72
|
#endif
|
73
73
|
uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
74
|
+
|
75
|
+
return uk;
|
74
76
|
}
|
75
77
|
|
76
78
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
|
@@ -164,7 +166,7 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
164
166
|
return object_complete_symbol(uk, rb_str_intern(str));
|
165
167
|
}
|
166
168
|
|
167
|
-
VALUE proc = msgpack_unpacker_ext_registry_lookup(
|
169
|
+
VALUE proc = msgpack_unpacker_ext_registry_lookup(uk->ext_registry, ext_type);
|
168
170
|
if(proc != Qnil) {
|
169
171
|
VALUE obj = rb_funcall(proc, s_call, 1, str);
|
170
172
|
return object_complete(uk, obj);
|
@@ -286,24 +288,20 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
286
288
|
if(length <= msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk))) {
|
287
289
|
int ret;
|
288
290
|
if ((uk->optimized_symbol_ext_type && uk->symbol_ext_type == raw_type) || (uk->symbolize_keys && is_reading_map_key(uk))) {
|
289
|
-
VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length);
|
291
|
+
VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, raw_type != RAW_TYPE_BINARY);
|
290
292
|
ret = object_complete_symbol(uk, symbol);
|
291
293
|
} else {
|
292
|
-
|
293
|
-
* because rb_hash_aset freezes keys and it causes copying */
|
294
|
-
bool will_freeze = uk->freeze || is_reading_map_key(uk);
|
295
|
-
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
|
294
|
+
bool will_freeze = uk->freeze;
|
296
295
|
if(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY) {
|
296
|
+
/* don't use zerocopy for hash keys but get a frozen string directly
|
297
|
+
* because rb_hash_aset freezes keys and it causes copying */
|
298
|
+
will_freeze = will_freeze || is_reading_map_key(uk);
|
299
|
+
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
|
297
300
|
ret = object_complete(uk, string);
|
298
301
|
} else {
|
302
|
+
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, false, false);
|
299
303
|
ret = object_complete_ext(uk, raw_type, string);
|
300
304
|
}
|
301
|
-
|
302
|
-
# if !HASH_ASET_DEDUPE
|
303
|
-
if(will_freeze) {
|
304
|
-
rb_obj_freeze(string);
|
305
|
-
}
|
306
|
-
# endif
|
307
305
|
}
|
308
306
|
uk->reading_raw_remaining = 0;
|
309
307
|
return ret;
|
data/ext/msgpack/unpacker.h
CHANGED
@@ -60,7 +60,7 @@ struct msgpack_unpacker_t {
|
|
60
60
|
|
61
61
|
VALUE buffer_ref;
|
62
62
|
|
63
|
-
msgpack_unpacker_ext_registry_t ext_registry;
|
63
|
+
msgpack_unpacker_ext_registry_t *ext_registry;
|
64
64
|
|
65
65
|
/* options */
|
66
66
|
bool symbolize_keys;
|
@@ -86,7 +86,7 @@ void msgpack_unpacker_static_init();
|
|
86
86
|
|
87
87
|
void msgpack_unpacker_static_destroy();
|
88
88
|
|
89
|
-
|
89
|
+
msgpack_unpacker_t* _msgpack_unpacker_new(void);
|
90
90
|
|
91
91
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk);
|
92
92
|
|
@@ -45,7 +45,7 @@ static void Unpacker_free(msgpack_unpacker_t* uk)
|
|
45
45
|
if(uk == NULL) {
|
46
46
|
return;
|
47
47
|
}
|
48
|
-
|
48
|
+
msgpack_unpacker_ext_registry_release(uk->ext_registry);
|
49
49
|
_msgpack_unpacker_destroy(uk);
|
50
50
|
xfree(uk);
|
51
51
|
}
|
@@ -53,13 +53,12 @@ static void Unpacker_free(msgpack_unpacker_t* uk)
|
|
53
53
|
static void Unpacker_mark(msgpack_unpacker_t* uk)
|
54
54
|
{
|
55
55
|
msgpack_unpacker_mark(uk);
|
56
|
-
msgpack_unpacker_ext_registry_mark(
|
56
|
+
msgpack_unpacker_ext_registry_mark(uk->ext_registry);
|
57
57
|
}
|
58
58
|
|
59
59
|
VALUE MessagePack_Unpacker_alloc(VALUE klass)
|
60
60
|
{
|
61
|
-
msgpack_unpacker_t* uk =
|
62
|
-
_msgpack_unpacker_init(uk);
|
61
|
+
msgpack_unpacker_t* uk = _msgpack_unpacker_new();
|
63
62
|
|
64
63
|
VALUE self = Data_Wrap_Struct(klass, Unpacker_mark, Unpacker_free, uk);
|
65
64
|
return self;
|
@@ -94,7 +93,6 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
94
93
|
|
95
94
|
UNPACKER(self, uk);
|
96
95
|
|
97
|
-
msgpack_unpacker_ext_registry_init(&uk->ext_registry);
|
98
96
|
uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
|
99
97
|
|
100
98
|
MessagePack_Buffer_set_options(UNPACKER_BUFFER_(uk), io, options);
|
@@ -133,7 +131,7 @@ static VALUE Unpacker_allow_unknown_ext_p(VALUE self)
|
|
133
131
|
return uk->allow_unknown_ext ? Qtrue : Qfalse;
|
134
132
|
}
|
135
133
|
|
136
|
-
static void raise_unpacker_error(int r)
|
134
|
+
NORETURN(static void raise_unpacker_error(int r))
|
137
135
|
{
|
138
136
|
switch(r) {
|
139
137
|
case PRIMITIVE_EOF:
|
@@ -222,34 +220,6 @@ static VALUE Unpacker_read_map_header(VALUE self)
|
|
222
220
|
return ULONG2NUM(size);
|
223
221
|
}
|
224
222
|
|
225
|
-
static VALUE Unpacker_peek_next_type(VALUE self)
|
226
|
-
{
|
227
|
-
UNPACKER(self, uk);
|
228
|
-
|
229
|
-
int r = msgpack_unpacker_peek_next_object_type(uk);
|
230
|
-
if(r < 0) {
|
231
|
-
raise_unpacker_error(r);
|
232
|
-
}
|
233
|
-
|
234
|
-
switch((enum msgpack_unpacker_object_type) r) {
|
235
|
-
case TYPE_NIL:
|
236
|
-
return rb_intern("nil");
|
237
|
-
case TYPE_BOOLEAN:
|
238
|
-
return rb_intern("boolean");
|
239
|
-
case TYPE_INTEGER:
|
240
|
-
return rb_intern("integer");
|
241
|
-
case TYPE_FLOAT:
|
242
|
-
return rb_intern("float");
|
243
|
-
case TYPE_RAW:
|
244
|
-
return rb_intern("raw");
|
245
|
-
case TYPE_ARRAY:
|
246
|
-
return rb_intern("array");
|
247
|
-
case TYPE_MAP:
|
248
|
-
return rb_intern("map");
|
249
|
-
default:
|
250
|
-
rb_raise(eUnpackError, "logically unknown type %d", r);
|
251
|
-
}
|
252
|
-
}
|
253
223
|
|
254
224
|
static VALUE Unpacker_feed(VALUE self, VALUE data)
|
255
225
|
{
|
@@ -296,9 +266,10 @@ static VALUE Unpacker_each_impl(VALUE self)
|
|
296
266
|
}
|
297
267
|
}
|
298
268
|
|
299
|
-
static VALUE Unpacker_rescue_EOFError(VALUE
|
269
|
+
static VALUE Unpacker_rescue_EOFError(VALUE args, VALUE error)
|
300
270
|
{
|
301
|
-
UNUSED(
|
271
|
+
UNUSED(args);
|
272
|
+
UNUSED(error);
|
302
273
|
return Qnil;
|
303
274
|
}
|
304
275
|
|
@@ -347,9 +318,11 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
|
|
347
318
|
UNPACKER(self, uk);
|
348
319
|
|
349
320
|
VALUE mapping = rb_hash_new();
|
350
|
-
|
351
|
-
|
352
|
-
|
321
|
+
if (uk->ext_registry) {
|
322
|
+
for(int i=0; i < 256; i++) {
|
323
|
+
if(uk->ext_registry->array[i] != Qnil) {
|
324
|
+
rb_hash_aset(mapping, INT2FIX(i - 128), uk->ext_registry->array[i]);
|
325
|
+
}
|
353
326
|
}
|
354
327
|
}
|
355
328
|
|
@@ -451,7 +424,6 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
451
424
|
rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
|
452
425
|
rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
|
453
426
|
rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
|
454
|
-
//rb_define_method(cMessagePack_Unpacker, "peek_next_type", Unpacker_peek_next_type, 0); // TODO
|
455
427
|
rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1);
|
456
428
|
rb_define_method(cMessagePack_Unpacker, "feed_reference", Unpacker_feed_reference, 1);
|
457
429
|
rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
|
@@ -27,36 +27,59 @@ void msgpack_unpacker_ext_registry_static_init()
|
|
27
27
|
s_dup = rb_intern("dup");
|
28
28
|
}
|
29
29
|
|
30
|
+
|
30
31
|
void msgpack_unpacker_ext_registry_static_destroy()
|
31
32
|
{ }
|
32
33
|
|
33
|
-
void
|
34
|
+
void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg)
|
34
35
|
{
|
35
|
-
|
36
|
-
|
36
|
+
if (ukrg) {
|
37
|
+
for(int i=0; i < 256; i++) {
|
38
|
+
if (ukrg->array[i] != Qnil) {
|
39
|
+
rb_gc_mark(ukrg->array[i]);
|
40
|
+
}
|
41
|
+
}
|
37
42
|
}
|
38
43
|
}
|
39
44
|
|
40
|
-
|
45
|
+
msgpack_unpacker_ext_registry_t* msgpack_unpacker_ext_registry_cow(msgpack_unpacker_ext_registry_t* src)
|
41
46
|
{
|
42
|
-
|
43
|
-
|
47
|
+
msgpack_unpacker_ext_registry_t* dst;
|
48
|
+
if (src) {
|
49
|
+
if (src->borrow_count) {
|
50
|
+
dst = ALLOC(msgpack_unpacker_ext_registry_t);
|
51
|
+
dst->borrow_count = 0;
|
52
|
+
MEMCPY(dst->array, src->array, VALUE, 256);
|
53
|
+
msgpack_unpacker_ext_registry_release(src);
|
54
|
+
return dst;
|
55
|
+
} else {
|
56
|
+
return src;
|
57
|
+
}
|
58
|
+
} else {
|
59
|
+
dst = ALLOC(msgpack_unpacker_ext_registry_t);
|
60
|
+
dst->borrow_count = 0;
|
61
|
+
for(int i=0; i < 256; i++) {
|
62
|
+
dst->array[i] = Qnil;
|
63
|
+
}
|
64
|
+
return dst;
|
44
65
|
}
|
45
66
|
}
|
46
67
|
|
47
|
-
void
|
48
|
-
msgpack_unpacker_ext_registry_t* dst)
|
68
|
+
void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg)
|
49
69
|
{
|
50
|
-
|
51
|
-
|
70
|
+
if (ukrg) {
|
71
|
+
if (ukrg->borrow_count) {
|
72
|
+
ukrg->borrow_count--;
|
73
|
+
} else {
|
74
|
+
xfree(ukrg);
|
75
|
+
}
|
52
76
|
}
|
53
77
|
}
|
54
78
|
|
55
|
-
|
79
|
+
void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
|
56
80
|
VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
|
57
81
|
{
|
58
|
-
|
59
|
-
|
60
|
-
ukrg
|
61
|
-
return before;
|
82
|
+
msgpack_unpacker_ext_registry_t* ext_registry = msgpack_unpacker_ext_registry_cow(*ukrg);
|
83
|
+
ext_registry->array[ext_type + 128] = rb_ary_new3(3, ext_module, proc, arg);
|
84
|
+
*ukrg = ext_registry;
|
62
85
|
}
|
@@ -25,35 +25,39 @@ struct msgpack_unpacker_ext_registry_t;
|
|
25
25
|
typedef struct msgpack_unpacker_ext_registry_t msgpack_unpacker_ext_registry_t;
|
26
26
|
|
27
27
|
struct msgpack_unpacker_ext_registry_t {
|
28
|
+
unsigned int borrow_count;
|
28
29
|
VALUE array[256];
|
29
|
-
//int bitmap;
|
30
30
|
};
|
31
31
|
|
32
32
|
void msgpack_unpacker_ext_registry_static_init();
|
33
33
|
|
34
34
|
void msgpack_unpacker_ext_registry_static_destroy();
|
35
35
|
|
36
|
-
void
|
36
|
+
void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg);
|
37
37
|
|
38
|
-
static inline void
|
39
|
-
{
|
38
|
+
static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_registry_t* src, msgpack_unpacker_ext_registry_t** dst)
|
39
|
+
{
|
40
|
+
if (src) {
|
41
|
+
src->borrow_count++;
|
42
|
+
*dst = src;
|
43
|
+
}
|
44
|
+
}
|
40
45
|
|
41
46
|
void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg);
|
42
47
|
|
43
|
-
void
|
44
|
-
msgpack_unpacker_ext_registry_t* dst);
|
45
|
-
|
46
|
-
VALUE msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t* ukrg,
|
48
|
+
void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
|
47
49
|
VALUE ext_module, int ext_type, VALUE proc, VALUE arg);
|
48
50
|
|
49
51
|
static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_registry_t* ukrg,
|
50
52
|
int ext_type)
|
51
53
|
{
|
52
|
-
|
53
|
-
|
54
|
-
|
54
|
+
if (ukrg) {
|
55
|
+
VALUE entry = ukrg->array[ext_type + 128];
|
56
|
+
if (entry != Qnil) {
|
57
|
+
return rb_ary_entry(entry, 1);
|
58
|
+
}
|
55
59
|
}
|
56
|
-
return
|
60
|
+
return Qnil;
|
57
61
|
}
|
58
62
|
|
59
63
|
#endif
|
data/lib/msgpack/symbol.rb
CHANGED
@@ -14,6 +14,13 @@ class Symbol
|
|
14
14
|
# The canonical way to do it for symbols would be:
|
15
15
|
# data.unpack1('A*').to_sym
|
16
16
|
# However in this instance we can take a shortcut
|
17
|
-
|
17
|
+
|
18
|
+
# We assume the string encoding is UTF-8, and let Ruby create either
|
19
|
+
# an ASCII symbol or UTF-8 symbol.
|
20
|
+
data.force_encoding(Encoding::UTF_8).to_sym
|
21
|
+
rescue EncodingError
|
22
|
+
# If somehow the string wasn't valid UTF-8 not valid ASCII, we fallback
|
23
|
+
# to what has been the historical behavior of creating a binary symbol
|
24
|
+
data.force_encoding(Encoding::BINARY).to_sym
|
18
25
|
end
|
19
26
|
end
|
data/lib/msgpack/version.rb
CHANGED
data/spec/factory_spec.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
1
|
require 'spec_helper'
|
3
2
|
|
4
3
|
describe MessagePack::Factory do
|
@@ -42,6 +41,21 @@ describe MessagePack::Factory do
|
|
42
41
|
unpacker.feed(MessagePack::ExtensionValue.new(1, 'a').to_msgpack)
|
43
42
|
expect{ unpacker.read }.to raise_error(MessagePack::UnknownExtTypeError)
|
44
43
|
end
|
44
|
+
|
45
|
+
it 'does not share the extension registry with unpackers' do
|
46
|
+
subject.register_type(0x00, Symbol)
|
47
|
+
expect do
|
48
|
+
unpacker = subject.unpacker
|
49
|
+
expect do
|
50
|
+
unpacker.register_type(0x01) {}
|
51
|
+
end.to change { unpacker.registered_types }
|
52
|
+
|
53
|
+
second_unpacker = subject.unpacker
|
54
|
+
expect do
|
55
|
+
second_unpacker.register_type(0x01) {}
|
56
|
+
end.to_not change { unpacker.registered_types }
|
57
|
+
end.to_not change { subject.registered_types }
|
58
|
+
end
|
45
59
|
end
|
46
60
|
|
47
61
|
describe '#dump and #load' do
|
@@ -255,29 +269,25 @@ describe MessagePack::Factory do
|
|
255
269
|
subject { factory.packer.pack(value).to_s }
|
256
270
|
before { stub_const('Value', Class.new{ include Mod }) }
|
257
271
|
let(:value) { Value.new }
|
258
|
-
it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
|
272
|
+
it { is_expected.to eq "\xC7\x0F\x01value_msgpacked".force_encoding(Encoding::BINARY) }
|
259
273
|
end
|
260
274
|
|
261
275
|
describe "packing an object which has been extended by the module" do
|
262
276
|
subject { factory.packer.pack(object).to_s }
|
263
277
|
let(:object) { Object.new.extend Mod }
|
264
|
-
it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
|
278
|
+
it { is_expected.to eq "\xC7\x0F\x01value_msgpacked".force_encoding(Encoding::BINARY) }
|
265
279
|
end
|
266
280
|
|
267
281
|
describe "unpacking with the module" do
|
268
|
-
subject { factory.unpacker.feed("\xC7\x06\x01module").unpack }
|
282
|
+
subject { factory.unpacker.feed("\xC7\x06\x01module".force_encoding(Encoding::BINARY)).unpack }
|
269
283
|
it { is_expected.to eq "unpacked module" }
|
270
284
|
end
|
271
285
|
end
|
272
286
|
end
|
273
287
|
|
274
288
|
describe 'the special treatment of symbols with ext type' do
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
def symbol_after_roundtrip
|
279
|
-
packed_symbol = packer.pack(:symbol).to_s
|
280
|
-
unpacker.feed(packed_symbol).unpack
|
289
|
+
def roundtrip(object, options = nil)
|
290
|
+
subject.load(subject.dump(object), options)
|
281
291
|
end
|
282
292
|
|
283
293
|
context 'using the optimized symbol unpacker' do
|
@@ -293,13 +303,25 @@ describe MessagePack::Factory do
|
|
293
303
|
end
|
294
304
|
|
295
305
|
it 'lets symbols survive a roundtrip' do
|
296
|
-
expect(
|
306
|
+
expect(roundtrip(:symbol)).to be :symbol
|
307
|
+
end
|
308
|
+
|
309
|
+
it 'preserves encoding for ASCII symbols' do
|
310
|
+
expect(:symbol.encoding).to be Encoding::US_ASCII
|
311
|
+
expect(roundtrip(:symbol)).to be :symbol
|
312
|
+
expect(roundtrip(:symbol).encoding).to be Encoding::US_ASCII
|
313
|
+
end
|
314
|
+
|
315
|
+
it 'preserves encoding for UTF-8 symbols' do
|
316
|
+
expect(:"fée".encoding).to be Encoding::UTF_8
|
317
|
+
expect(roundtrip(:"fée").encoding).to be Encoding::UTF_8
|
318
|
+
expect(roundtrip(:"fée")).to be :"fée"
|
297
319
|
end
|
298
320
|
end
|
299
321
|
|
300
322
|
context 'if no ext type is registered for symbols' do
|
301
323
|
it 'converts symbols to string' do
|
302
|
-
expect(
|
324
|
+
expect(roundtrip(:symbol)).to eq 'symbol'
|
303
325
|
end
|
304
326
|
end
|
305
327
|
|
@@ -308,7 +330,41 @@ describe MessagePack::Factory do
|
|
308
330
|
before { subject.register_type(0x00, ::Symbol) }
|
309
331
|
|
310
332
|
it 'lets symbols survive a roundtrip' do
|
311
|
-
expect(
|
333
|
+
expect(roundtrip(:symbol)).to be :symbol
|
334
|
+
end
|
335
|
+
|
336
|
+
it 'works with hash keys' do
|
337
|
+
expect(roundtrip(symbol: 1)).to be == { symbol: 1 }
|
338
|
+
end
|
339
|
+
|
340
|
+
it 'works with frozen: true option' do
|
341
|
+
expect(roundtrip(:symbol, freeze: true)).to be :symbol
|
342
|
+
end
|
343
|
+
|
344
|
+
it 'preserves encoding for ASCII symbols' do
|
345
|
+
expect(:symbol.encoding).to be Encoding::US_ASCII
|
346
|
+
expect(roundtrip(:symbol)).to be :symbol
|
347
|
+
expect(roundtrip(:symbol).encoding).to be Encoding::US_ASCII
|
348
|
+
end
|
349
|
+
|
350
|
+
it 'preserves encoding for UTF-8 symbols' do
|
351
|
+
expect(:"fée".encoding).to be Encoding::UTF_8
|
352
|
+
expect(roundtrip(:"fée")).to be :"fée"
|
353
|
+
expect(roundtrip(:"fée").encoding).to be Encoding::UTF_8
|
354
|
+
end
|
355
|
+
|
356
|
+
it 'does not handle symbols in other encodings' do
|
357
|
+
symbol = "fàe".encode(Encoding::ISO_8859_1).to_sym
|
358
|
+
expect(symbol.encoding).to be Encoding::ISO_8859_1
|
359
|
+
|
360
|
+
if IS_JRUBY
|
361
|
+
# JRuby doesn't quite behave like MRI here.
|
362
|
+
# "fàe".force_encoding(Encoding::BINARY).to_sym is able to lookup the existing ISO-8859-1 symbol
|
363
|
+
# It likely is a JRuby bug.
|
364
|
+
expect(roundtrip(symbol).encoding).to be Encoding::ISO_8859_1
|
365
|
+
else
|
366
|
+
expect(roundtrip(symbol).encoding).to be Encoding::BINARY
|
367
|
+
end
|
312
368
|
end
|
313
369
|
end
|
314
370
|
|
@@ -332,7 +388,7 @@ describe MessagePack::Factory do
|
|
332
388
|
before { subject.register_type(0x00, ::Symbol) }
|
333
389
|
|
334
390
|
it 'lets symbols survive a roundtrip' do
|
335
|
-
expect(
|
391
|
+
expect(roundtrip(:symbol)).to be :symbol
|
336
392
|
end
|
337
393
|
|
338
394
|
after do
|
data/spec/spec_helper.rb
CHANGED
@@ -25,9 +25,7 @@ if GC.respond_to?(:auto_compact=)
|
|
25
25
|
GC.auto_compact = true
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
/java/ =~ RUBY_PLATFORM
|
30
|
-
end
|
28
|
+
IS_JRUBY = RUBY_ENGINE == 'jruby'
|
31
29
|
|
32
30
|
# checking if Hash#[]= (rb_hash_aset) dedupes string keys
|
33
31
|
def automatic_string_keys_deduplication?
|
@@ -46,7 +44,7 @@ def string_deduplication?
|
|
46
44
|
(-r1).equal?(-r2)
|
47
45
|
end
|
48
46
|
|
49
|
-
if
|
47
|
+
if IS_JRUBY
|
50
48
|
RSpec.configure do |c|
|
51
49
|
c.treat_symbols_as_metadata_keys_with_true_values = true
|
52
50
|
c.filter_run_excluding :encodings => !(defined? Encoding)
|
data/spec/timestamp_spec.rb
CHANGED
data/spec/unpacker_spec.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
|
3
1
|
require 'stringio'
|
4
2
|
require 'tempfile'
|
5
3
|
require 'zlib'
|
@@ -302,6 +300,21 @@ describe MessagePack::Unpacker do
|
|
302
300
|
MessagePack.unpack(MessagePack.pack(symbolized_hash), :symbolize_keys => true).should == symbolized_hash
|
303
301
|
end
|
304
302
|
|
303
|
+
it 'MessagePack.unpack symbolize_keys preserve encoding' do
|
304
|
+
hash = { :ascii => 1, :utf8_é => 2}
|
305
|
+
loaded_hash = MessagePack.load(MessagePack.pack(hash), :symbolize_keys => true)
|
306
|
+
|
307
|
+
hash.keys[0].encoding.should == Encoding::US_ASCII # Ruby coerce symbols to US-ASCII when possible.
|
308
|
+
loaded_hash.keys[0].should == hash.keys[0]
|
309
|
+
loaded_hash.keys[0].encoding.should == hash.keys[0].encoding
|
310
|
+
|
311
|
+
hash.keys[1].encoding.should == Encoding::UTF_8
|
312
|
+
loaded_hash.keys[1].should == hash.keys[1]
|
313
|
+
loaded_hash.keys[1].encoding.should == hash.keys[1].encoding
|
314
|
+
|
315
|
+
MessagePack.unpack(MessagePack.pack(hash), :symbolize_keys => true).should == hash
|
316
|
+
end
|
317
|
+
|
305
318
|
it 'Unpacker#unpack symbolize_keys' do
|
306
319
|
unpacker = MessagePack::Unpacker.new(:symbolize_keys => true)
|
307
320
|
symbolized_hash = {:a => 'b', :c => 'd'}
|
@@ -765,7 +778,13 @@ describe MessagePack::Unpacker do
|
|
765
778
|
|
766
779
|
context 'binary encoding', :encodings do
|
767
780
|
let :buffer do
|
768
|
-
MessagePack.pack({
|
781
|
+
MessagePack.pack({
|
782
|
+
'hello'.b => 'world'.b,
|
783
|
+
'nested'.b => [
|
784
|
+
'object'.b,
|
785
|
+
{'structure'.b => true},
|
786
|
+
]
|
787
|
+
})
|
769
788
|
end
|
770
789
|
|
771
790
|
let :unpacker do
|
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.4.
|
4
|
+
version: 1.4.5
|
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-02-15 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|