msgpack 1.4.4 → 1.4.5
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 +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
|