msgpack 1.2.10 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yaml +57 -0
- data/.gitignore +3 -1
- data/.rubocop.yml +4 -1
- data/ChangeLog +60 -0
- data/Gemfile +3 -0
- data/README.md +264 -0
- data/Rakefile +1 -9
- data/doclib/msgpack/factory.rb +47 -3
- data/doclib/msgpack/packer.rb +5 -4
- data/doclib/msgpack/time.rb +22 -0
- data/doclib/msgpack/timestamp.rb +44 -0
- data/doclib/msgpack/unpacker.rb +2 -2
- data/ext/java/org/msgpack/jruby/Buffer.java +23 -16
- data/ext/java/org/msgpack/jruby/Decoder.java +46 -23
- data/ext/java/org/msgpack/jruby/Encoder.java +68 -30
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +37 -49
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +5 -8
- data/ext/java/org/msgpack/jruby/Factory.java +47 -7
- data/ext/java/org/msgpack/jruby/Packer.java +29 -17
- data/ext/java/org/msgpack/jruby/Unpacker.java +72 -37
- data/ext/msgpack/buffer.c +4 -16
- data/ext/msgpack/buffer.h +46 -5
- data/ext/msgpack/buffer_class.c +23 -15
- data/ext/msgpack/compat.h +1 -12
- data/ext/msgpack/extconf.rb +39 -7
- data/ext/msgpack/factory_class.c +87 -20
- data/ext/msgpack/packer.c +58 -8
- data/ext/msgpack/packer.h +24 -16
- data/ext/msgpack/packer_class.c +29 -31
- data/ext/msgpack/packer_ext_registry.c +22 -30
- data/ext/msgpack/packer_ext_registry.h +38 -31
- data/ext/msgpack/unpacker.c +102 -70
- data/ext/msgpack/unpacker.h +10 -2
- data/ext/msgpack/unpacker_class.c +35 -52
- data/ext/msgpack/unpacker_ext_registry.c +40 -16
- data/ext/msgpack/unpacker_ext_registry.h +21 -14
- data/lib/msgpack/bigint.rb +69 -0
- data/lib/msgpack/factory.rb +103 -0
- data/lib/msgpack/symbol.rb +21 -4
- data/lib/msgpack/time.rb +29 -0
- data/lib/msgpack/timestamp.rb +76 -0
- data/lib/msgpack/version.rb +4 -7
- data/lib/msgpack.rb +8 -12
- data/msgpack.gemspec +3 -7
- data/spec/bigint_spec.rb +26 -0
- data/spec/factory_spec.rb +299 -12
- data/spec/msgpack_spec.rb +1 -1
- data/spec/packer_spec.rb +18 -0
- data/spec/spec_helper.rb +30 -3
- data/spec/timestamp_spec.rb +159 -0
- data/spec/unpacker_spec.rb +135 -4
- metadata +21 -51
- data/.travis.yml +0 -43
- data/README.rdoc +0 -209
@@ -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,37 +43,29 @@ 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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
}
|
54
|
-
|
55
|
-
#ifndef HAVE_RB_HASH_CLEAR
|
56
|
-
|
57
|
-
static int
|
58
|
-
__rb_hash_clear_clear_i(key, value, dummy)
|
59
|
-
VALUE key, value, dummy;
|
60
|
-
{
|
61
|
-
return ST_DELETE;
|
46
|
+
if(RTEST(src->hash) && !rb_obj_frozen_p(src->hash)) {
|
47
|
+
dst->hash = rb_hash_dup(src->hash);
|
48
|
+
dst->cache = RTEST(src->cache) ? rb_hash_dup(src->cache) : Qnil;
|
49
|
+
} else {
|
50
|
+
// If the type registry is frozen we can safely share it, and share the cache as well.
|
51
|
+
dst->hash = src->hash;
|
52
|
+
dst->cache = src->cache;
|
53
|
+
}
|
62
54
|
}
|
63
55
|
|
64
|
-
#endif
|
65
|
-
|
66
56
|
VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
|
67
|
-
VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
|
57
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg)
|
68
58
|
{
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
59
|
+
if (!RTEST(pkrg->hash)) {
|
60
|
+
pkrg->hash = rb_hash_new();
|
61
|
+
}
|
62
|
+
|
63
|
+
if (RTEST(pkrg->cache)) {
|
64
|
+
/* clear lookup cache not to miss added type */
|
65
|
+
rb_hash_clear(pkrg->cache);
|
76
66
|
}
|
77
|
-
|
78
|
-
|
67
|
+
|
68
|
+
// TODO: Ruby embeded array limit is 3, merging `proc` and `arg` would be good.
|
69
|
+
VALUE entry = rb_ary_new3(4, INT2FIX(ext_type), proc, arg, INT2FIX(flags));
|
70
|
+
return rb_hash_aset(pkrg->hash, ext_module, entry);
|
79
71
|
}
|
@@ -21,6 +21,8 @@
|
|
21
21
|
#include "compat.h"
|
22
22
|
#include "ruby.h"
|
23
23
|
|
24
|
+
#define MSGPACK_EXT_RECURSIVE 0b0001
|
25
|
+
|
24
26
|
struct msgpack_packer_ext_registry_t;
|
25
27
|
typedef struct msgpack_packer_ext_registry_t msgpack_packer_ext_registry_t;
|
26
28
|
|
@@ -44,7 +46,7 @@ void msgpack_packer_ext_registry_dup(msgpack_packer_ext_registry_t* src,
|
|
44
46
|
msgpack_packer_ext_registry_t* dst);
|
45
47
|
|
46
48
|
VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
|
47
|
-
VALUE ext_module, int ext_type, VALUE proc, VALUE arg);
|
49
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg);
|
48
50
|
|
49
51
|
static int msgpack_packer_ext_find_superclass(VALUE key, VALUE value, VALUE arg)
|
50
52
|
{
|
@@ -60,59 +62,60 @@ static int msgpack_packer_ext_find_superclass(VALUE key, VALUE value, VALUE arg)
|
|
60
62
|
}
|
61
63
|
|
62
64
|
static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registry_t* pkrg,
|
63
|
-
VALUE lookup_class, int* ext_type_result)
|
65
|
+
VALUE lookup_class, int* ext_type_result, int* ext_flags_result)
|
64
66
|
{
|
65
67
|
// fetch lookup_class from hash, which is a hash to register classes
|
66
68
|
VALUE type = rb_hash_lookup(pkrg->hash, lookup_class);
|
67
69
|
if(type != Qnil) {
|
68
70
|
*ext_type_result = FIX2INT(rb_ary_entry(type, 0));
|
71
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(type, 3));
|
69
72
|
return rb_ary_entry(type, 1);
|
70
73
|
}
|
71
74
|
|
72
75
|
// fetch lookup_class from cache, which stores results of searching ancestors from pkrg->hash
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
76
|
+
if (RTEST(pkrg->cache)) {
|
77
|
+
VALUE type_inht = rb_hash_lookup(pkrg->cache, lookup_class);
|
78
|
+
if(type_inht != Qnil) {
|
79
|
+
*ext_type_result = FIX2INT(rb_ary_entry(type_inht, 0));
|
80
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(type_inht, 3));
|
81
|
+
return rb_ary_entry(type_inht, 1);
|
82
|
+
}
|
77
83
|
}
|
78
84
|
|
79
85
|
return Qnil;
|
80
86
|
}
|
81
87
|
|
82
88
|
static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_registry_t* pkrg,
|
83
|
-
VALUE instance, int* ext_type_result)
|
89
|
+
VALUE instance, int* ext_type_result, int* ext_flags_result)
|
84
90
|
{
|
85
|
-
VALUE lookup_class;
|
86
91
|
VALUE type;
|
87
92
|
|
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);
|
93
|
+
if (pkrg->hash == Qnil) { // No extensions registered
|
94
|
+
return Qnil;
|
95
|
+
}
|
103
96
|
|
104
|
-
|
105
|
-
|
106
|
-
|
97
|
+
/*
|
98
|
+
* 1. check whether singleton_class or class of this instance is registered (or resolved in past) or not.
|
99
|
+
*
|
100
|
+
* Objects of type Integer (Fixnum, Bignum), Float, Symbol and frozen
|
101
|
+
* `rb_class_of` returns the singleton_class if the object has one, or the "real class" otherwise.
|
102
|
+
*/
|
103
|
+
VALUE lookup_class = rb_class_of(instance);
|
104
|
+
type = msgpack_packer_ext_registry_fetch(pkrg, lookup_class, ext_type_result, ext_flags_result);
|
105
|
+
if(type != Qnil) {
|
106
|
+
return type;
|
107
107
|
}
|
108
108
|
|
109
109
|
/*
|
110
|
-
* 2. check the class of instance is registered
|
110
|
+
* 2. If the object had a singleton_class check if the real class of instance is registered
|
111
|
+
* (or resolved in past) or not.
|
111
112
|
*/
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
113
|
+
VALUE real_class = rb_obj_class(instance);
|
114
|
+
if(lookup_class != real_class) {
|
115
|
+
type = msgpack_packer_ext_registry_fetch(pkrg, real_class, ext_type_result, ext_flags_result);
|
116
|
+
if(type != Qnil) {
|
117
|
+
return type;
|
118
|
+
}
|
116
119
|
}
|
117
120
|
|
118
121
|
/*
|
@@ -126,8 +129,12 @@ static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_regist
|
|
126
129
|
VALUE superclass = args[1];
|
127
130
|
if(superclass != Qnil) {
|
128
131
|
VALUE superclass_type = rb_hash_lookup(pkrg->hash, superclass);
|
132
|
+
if (!RTEST(pkrg->cache)) {
|
133
|
+
pkrg->cache = rb_hash_new();
|
134
|
+
}
|
129
135
|
rb_hash_aset(pkrg->cache, lookup_class, superclass_type);
|
130
136
|
*ext_type_result = FIX2INT(rb_ary_entry(superclass_type, 0));
|
137
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(superclass_type, 3));
|
131
138
|
return rb_ary_entry(superclass_type, 1);
|
132
139
|
}
|
133
140
|
|
data/ext/msgpack/unpacker.c
CHANGED
@@ -52,9 +52,19 @@ void msgpack_unpacker_static_destroy()
|
|
52
52
|
|
53
53
|
#define HEAD_BYTE_REQUIRED 0xc1
|
54
54
|
|
55
|
-
|
55
|
+
static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
|
56
|
+
#ifdef UNPACKER_STACK_RMEM
|
57
|
+
return msgpack_rmem_alloc(&s_stack_rmem);
|
58
|
+
/*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
|
59
|
+
#else
|
60
|
+
/*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_t));*/
|
61
|
+
return xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_t));
|
62
|
+
#endif
|
63
|
+
}
|
64
|
+
|
65
|
+
msgpack_unpacker_t* _msgpack_unpacker_new(void)
|
56
66
|
{
|
57
|
-
|
67
|
+
msgpack_unpacker_t* uk = ZALLOC_N(msgpack_unpacker_t, 1);
|
58
68
|
|
59
69
|
msgpack_buffer_init(UNPACKER_BUFFER_(uk));
|
60
70
|
|
@@ -63,24 +73,23 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
|
63
73
|
uk->last_object = Qnil;
|
64
74
|
uk->reading_raw = Qnil;
|
65
75
|
|
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
|
76
|
+
uk->stack = _msgpack_unpacker_new_stack();
|
73
77
|
uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
78
|
+
|
79
|
+
return uk;
|
80
|
+
}
|
81
|
+
|
82
|
+
static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
|
83
|
+
#ifdef UNPACKER_STACK_RMEM
|
84
|
+
msgpack_rmem_free(&s_stack_rmem, stack);
|
85
|
+
#else
|
86
|
+
xfree(stack);
|
87
|
+
#endif
|
74
88
|
}
|
75
89
|
|
76
90
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
|
77
91
|
{
|
78
|
-
|
79
|
-
msgpack_rmem_free(&s_stack_rmem, uk->stack);
|
80
|
-
#else
|
81
|
-
xfree(uk->stack);
|
82
|
-
#endif
|
83
|
-
|
92
|
+
_msgpack_unpacker_free_stack(uk->stack);
|
84
93
|
msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
|
85
94
|
}
|
86
95
|
|
@@ -142,41 +151,39 @@ static inline void reset_head_byte(msgpack_unpacker_t* uk)
|
|
142
151
|
|
143
152
|
static inline int object_complete(msgpack_unpacker_t* uk, VALUE object)
|
144
153
|
{
|
154
|
+
if(uk->freeze) {
|
155
|
+
rb_obj_freeze(object);
|
156
|
+
}
|
157
|
+
|
145
158
|
uk->last_object = object;
|
146
159
|
reset_head_byte(uk);
|
147
160
|
return PRIMITIVE_OBJECT_COMPLETE;
|
148
161
|
}
|
149
162
|
|
150
|
-
static inline int
|
163
|
+
static inline int object_complete_symbol(msgpack_unpacker_t* uk, VALUE object)
|
151
164
|
{
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
return object_complete(uk, str);
|
156
|
-
}
|
157
|
-
|
158
|
-
static inline int object_complete_binary(msgpack_unpacker_t* uk, VALUE str)
|
159
|
-
{
|
160
|
-
#ifdef COMPAT_HAVE_ENCODING
|
161
|
-
ENCODING_SET(str, msgpack_rb_encindex_ascii8bit);
|
162
|
-
#endif
|
163
|
-
return object_complete(uk, str);
|
165
|
+
uk->last_object = object;
|
166
|
+
reset_head_byte(uk);
|
167
|
+
return PRIMITIVE_OBJECT_COMPLETE;
|
164
168
|
}
|
165
169
|
|
166
170
|
static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALUE str)
|
167
171
|
{
|
168
|
-
|
169
|
-
|
170
|
-
|
172
|
+
if (uk->optimized_symbol_ext_type && ext_type == uk->symbol_ext_type) {
|
173
|
+
return object_complete_symbol(uk, rb_str_intern(str));
|
174
|
+
}
|
175
|
+
|
176
|
+
int ext_flags;
|
177
|
+
VALUE proc = msgpack_unpacker_ext_registry_lookup(uk->ext_registry, ext_type, &ext_flags);
|
171
178
|
|
172
|
-
VALUE proc = msgpack_unpacker_ext_registry_lookup(&uk->ext_registry, ext_type);
|
173
179
|
if(proc != Qnil) {
|
174
|
-
VALUE obj
|
180
|
+
VALUE obj;
|
181
|
+
obj = rb_funcall(proc, s_call, 1, str == Qnil ? rb_str_buf_new(0) : str);
|
175
182
|
return object_complete(uk, obj);
|
176
183
|
}
|
177
184
|
|
178
185
|
if(uk->allow_unknown_ext) {
|
179
|
-
VALUE obj = MessagePack_ExtensionValue_new(ext_type, str);
|
186
|
+
VALUE obj = MessagePack_ExtensionValue_new(ext_type, str == Qnil ? rb_str_buf_new(0) : str);
|
180
187
|
return object_complete(uk, obj);
|
181
188
|
}
|
182
189
|
|
@@ -271,9 +278,10 @@ static int read_raw_body_cont(msgpack_unpacker_t* uk)
|
|
271
278
|
|
272
279
|
int ret;
|
273
280
|
if(uk->reading_raw_type == RAW_TYPE_STRING) {
|
274
|
-
|
275
|
-
|
276
|
-
|
281
|
+
ENCODING_SET(uk->reading_raw, msgpack_rb_encindex_utf8);
|
282
|
+
ret = object_complete(uk, uk->reading_raw);
|
283
|
+
} else if (uk->reading_raw_type == RAW_TYPE_BINARY) {
|
284
|
+
ret = object_complete(uk, uk->reading_raw);
|
277
285
|
} else {
|
278
286
|
ret = object_complete_ext(uk, uk->reading_raw_type, uk->reading_raw);
|
279
287
|
}
|
@@ -285,23 +293,57 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
285
293
|
{
|
286
294
|
/* assuming uk->reading_raw == Qnil */
|
287
295
|
|
296
|
+
int ext_flags;
|
297
|
+
VALUE proc;
|
298
|
+
|
299
|
+
if(!(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY)) {
|
300
|
+
proc = msgpack_unpacker_ext_registry_lookup(uk->ext_registry, raw_type, &ext_flags);
|
301
|
+
if(proc != Qnil && ext_flags & MSGPACK_EXT_RECURSIVE) {
|
302
|
+
VALUE obj;
|
303
|
+
uk->last_object = Qnil;
|
304
|
+
reset_head_byte(uk);
|
305
|
+
size_t ext_size = uk->reading_raw_remaining;
|
306
|
+
uk->reading_raw_remaining = 0;
|
307
|
+
|
308
|
+
msgpack_unpacker_stack_t* stack = uk->stack;
|
309
|
+
size_t stack_depth = uk->stack_depth;
|
310
|
+
size_t stack_capacity = uk->stack_capacity;
|
311
|
+
|
312
|
+
uk->stack = _msgpack_unpacker_new_stack();
|
313
|
+
uk->stack_depth = 0;
|
314
|
+
uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
315
|
+
|
316
|
+
obj = rb_funcall(proc, s_call, 1, uk->buffer.owner);
|
317
|
+
|
318
|
+
_msgpack_unpacker_free_stack(uk->stack);
|
319
|
+
uk->stack = stack;
|
320
|
+
uk->stack_depth = stack_depth;
|
321
|
+
uk->stack_capacity = stack_capacity;
|
322
|
+
|
323
|
+
msgpack_buffer_skip(UNPACKER_BUFFER_(uk), ext_size);
|
324
|
+
return object_complete(uk, obj);
|
325
|
+
}
|
326
|
+
}
|
327
|
+
|
288
328
|
/* try optimized read */
|
289
329
|
size_t length = uk->reading_raw_remaining;
|
290
330
|
if(length <= msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk))) {
|
291
|
-
/* don't use zerocopy for hash keys but get a frozen string directly
|
292
|
-
* because rb_hash_aset freezes keys and it causes copying */
|
293
|
-
bool will_freeze = is_reading_map_key(uk);
|
294
|
-
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze);
|
295
331
|
int ret;
|
296
|
-
if(
|
297
|
-
|
298
|
-
|
299
|
-
ret = object_complete_binary(uk, string);
|
332
|
+
if ((uk->optimized_symbol_ext_type && uk->symbol_ext_type == raw_type) || (uk->symbolize_keys && is_reading_map_key(uk))) {
|
333
|
+
VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, raw_type != RAW_TYPE_BINARY);
|
334
|
+
ret = object_complete_symbol(uk, symbol);
|
300
335
|
} else {
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
336
|
+
bool will_freeze = uk->freeze;
|
337
|
+
if(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY) {
|
338
|
+
/* don't use zerocopy for hash keys but get a frozen string directly
|
339
|
+
* because rb_hash_aset freezes keys and it causes copying */
|
340
|
+
will_freeze = will_freeze || is_reading_map_key(uk);
|
341
|
+
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
|
342
|
+
ret = object_complete(uk, string);
|
343
|
+
} else {
|
344
|
+
VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, false, false);
|
345
|
+
ret = object_complete_ext(uk, raw_type, string);
|
346
|
+
}
|
305
347
|
}
|
306
348
|
uk->reading_raw_remaining = 0;
|
307
349
|
return ret;
|
@@ -332,7 +374,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
332
374
|
SWITCH_RANGE(b, 0xa0, 0xbf) // FixRaw / fixstr
|
333
375
|
int count = b & 0x1f;
|
334
376
|
if(count == 0) {
|
335
|
-
return
|
377
|
+
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
336
378
|
}
|
337
379
|
/* read_raw_body_begin sets uk->reading_raw */
|
338
380
|
uk->reading_raw_remaining = count;
|
@@ -371,7 +413,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
371
413
|
uint8_t length = cb->u8;
|
372
414
|
int ext_type = (signed char) cb->buffer[1];
|
373
415
|
if(length == 0) {
|
374
|
-
return object_complete_ext(uk, ext_type,
|
416
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
375
417
|
}
|
376
418
|
uk->reading_raw_remaining = length;
|
377
419
|
return read_raw_body_begin(uk, ext_type);
|
@@ -383,7 +425,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
383
425
|
uint16_t length = _msgpack_be16(cb->u16);
|
384
426
|
int ext_type = (signed char) cb->buffer[2];
|
385
427
|
if(length == 0) {
|
386
|
-
return object_complete_ext(uk, ext_type,
|
428
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
387
429
|
}
|
388
430
|
uk->reading_raw_remaining = length;
|
389
431
|
return read_raw_body_begin(uk, ext_type);
|
@@ -395,7 +437,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
395
437
|
uint32_t length = _msgpack_be32(cb->u32);
|
396
438
|
int ext_type = (signed char) cb->buffer[4];
|
397
439
|
if(length == 0) {
|
398
|
-
return object_complete_ext(uk, ext_type,
|
440
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
399
441
|
}
|
400
442
|
uk->reading_raw_remaining = length;
|
401
443
|
return read_raw_body_begin(uk, ext_type);
|
@@ -517,7 +559,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
517
559
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
518
560
|
uint8_t count = cb->u8;
|
519
561
|
if(count == 0) {
|
520
|
-
return
|
562
|
+
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
521
563
|
}
|
522
564
|
/* read_raw_body_begin sets uk->reading_raw */
|
523
565
|
uk->reading_raw_remaining = count;
|
@@ -529,7 +571,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
529
571
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
530
572
|
uint16_t count = _msgpack_be16(cb->u16);
|
531
573
|
if(count == 0) {
|
532
|
-
return
|
574
|
+
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
533
575
|
}
|
534
576
|
/* read_raw_body_begin sets uk->reading_raw */
|
535
577
|
uk->reading_raw_remaining = count;
|
@@ -541,7 +583,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
541
583
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
542
584
|
uint32_t count = _msgpack_be32(cb->u32);
|
543
585
|
if(count == 0) {
|
544
|
-
return
|
586
|
+
return object_complete(uk, rb_utf8_str_new_static("", 0));
|
545
587
|
}
|
546
588
|
/* read_raw_body_begin sets uk->reading_raw */
|
547
589
|
uk->reading_raw_remaining = count;
|
@@ -553,7 +595,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
553
595
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
|
554
596
|
uint8_t count = cb->u8;
|
555
597
|
if(count == 0) {
|
556
|
-
return
|
598
|
+
return object_complete(uk, rb_str_new_static("", 0));
|
557
599
|
}
|
558
600
|
/* read_raw_body_begin sets uk->reading_raw */
|
559
601
|
uk->reading_raw_remaining = count;
|
@@ -565,7 +607,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
565
607
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
|
566
608
|
uint16_t count = _msgpack_be16(cb->u16);
|
567
609
|
if(count == 0) {
|
568
|
-
return
|
610
|
+
return object_complete(uk, rb_str_new_static("", 0));
|
569
611
|
}
|
570
612
|
/* read_raw_body_begin sets uk->reading_raw */
|
571
613
|
uk->reading_raw_remaining = count;
|
@@ -577,7 +619,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
577
619
|
READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
|
578
620
|
uint32_t count = _msgpack_be32(cb->u32);
|
579
621
|
if(count == 0) {
|
580
|
-
return
|
622
|
+
return object_complete(uk, rb_str_new_static("", 0));
|
581
623
|
}
|
582
624
|
/* read_raw_body_begin sets uk->reading_raw */
|
583
625
|
uk->reading_raw_remaining = count;
|
@@ -719,18 +761,8 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
|
|
719
761
|
break;
|
720
762
|
case STACK_TYPE_MAP_VALUE:
|
721
763
|
if(uk->symbolize_keys && rb_type(top->key) == T_STRING) {
|
722
|
-
/* here uses
|
723
|
-
#ifdef HAVE_RB_STR_INTERN
|
724
|
-
/* rb_str_intern is added since MRI 2.2.0 */
|
764
|
+
/* here uses rb_str_intern instead of rb_intern so that Ruby VM can GC unused symbols */
|
725
765
|
rb_hash_aset(top->object, rb_str_intern(top->key), uk->last_object);
|
726
|
-
#else
|
727
|
-
#ifndef HAVE_RB_INTERN_STR
|
728
|
-
/* MRI 1.8 doesn't have rb_intern_str or rb_intern2 */
|
729
|
-
rb_hash_aset(top->object, ID2SYM(rb_intern(RSTRING_PTR(top->key))), uk->last_object);
|
730
|
-
#else
|
731
|
-
rb_hash_aset(top->object, ID2SYM(rb_intern_str(top->key)), uk->last_object);
|
732
|
-
#endif
|
733
|
-
#endif
|
734
766
|
} else {
|
735
767
|
rb_hash_aset(top->object, top->key, uk->last_object);
|
736
768
|
}
|
data/ext/msgpack/unpacker.h
CHANGED
@@ -60,11 +60,14 @@ 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;
|
67
|
+
bool freeze;
|
67
68
|
bool allow_unknown_ext;
|
69
|
+
bool optimized_symbol_ext_type;
|
70
|
+
int symbol_ext_type;
|
68
71
|
};
|
69
72
|
|
70
73
|
#define UNPACKER_BUFFER_(uk) (&(uk)->buffer)
|
@@ -83,7 +86,7 @@ void msgpack_unpacker_static_init();
|
|
83
86
|
|
84
87
|
void msgpack_unpacker_static_destroy();
|
85
88
|
|
86
|
-
|
89
|
+
msgpack_unpacker_t* _msgpack_unpacker_new(void);
|
87
90
|
|
88
91
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk);
|
89
92
|
|
@@ -96,6 +99,11 @@ static inline void msgpack_unpacker_set_symbolized_keys(msgpack_unpacker_t* uk,
|
|
96
99
|
uk->symbolize_keys = enable;
|
97
100
|
}
|
98
101
|
|
102
|
+
static inline void msgpack_unpacker_set_freeze(msgpack_unpacker_t* uk, bool enable)
|
103
|
+
{
|
104
|
+
uk->freeze = enable;
|
105
|
+
}
|
106
|
+
|
99
107
|
static inline void msgpack_unpacker_set_allow_unknown_ext(msgpack_unpacker_t* uk, bool enable)
|
100
108
|
{
|
101
109
|
uk->allow_unknown_ext = enable;
|