msgpack 1.4.5 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yaml +5 -5
- data/ChangeLog +14 -0
- data/README.md +22 -0
- data/doclib/msgpack/factory.rb +45 -2
- data/ext/java/org/msgpack/jruby/Buffer.java +6 -0
- data/ext/java/org/msgpack/jruby/Decoder.java +23 -19
- data/ext/java/org/msgpack/jruby/Encoder.java +46 -18
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +24 -31
- data/ext/java/org/msgpack/jruby/Factory.java +40 -5
- data/ext/java/org/msgpack/jruby/Packer.java +21 -11
- data/ext/java/org/msgpack/jruby/Unpacker.java +44 -22
- data/ext/msgpack/buffer_class.c +12 -3
- data/ext/msgpack/factory_class.c +62 -5
- data/ext/msgpack/packer.c +42 -5
- data/ext/msgpack/packer.h +24 -0
- data/ext/msgpack/packer_class.c +22 -19
- data/ext/msgpack/packer_ext_registry.c +13 -4
- data/ext/msgpack/packer_ext_registry.h +10 -5
- data/ext/msgpack/unpacker.c +59 -19
- data/ext/msgpack/unpacker_class.c +14 -5
- data/ext/msgpack/unpacker_ext_registry.c +3 -2
- data/ext/msgpack/unpacker_ext_registry.h +5 -2
- data/lib/msgpack/bigint.rb +69 -0
- data/lib/msgpack/factory.rb +103 -0
- data/lib/msgpack/version.rb +1 -1
- data/lib/msgpack.rb +4 -5
- data/spec/bigint_spec.rb +26 -0
- data/spec/factory_spec.rb +220 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/timestamp_spec.rb +2 -2
- metadata +4 -2
data/ext/msgpack/unpacker.c
CHANGED
@@ -52,6 +52,16 @@ void msgpack_unpacker_static_destroy()
|
|
52
52
|
|
53
53
|
#define HEAD_BYTE_REQUIRED 0xc1
|
54
54
|
|
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
|
+
|
55
65
|
msgpack_unpacker_t* _msgpack_unpacker_new(void)
|
56
66
|
{
|
57
67
|
msgpack_unpacker_t* uk = ZALLOC_N(msgpack_unpacker_t, 1);
|
@@ -63,26 +73,23 @@ msgpack_unpacker_t* _msgpack_unpacker_new(void)
|
|
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;
|
74
78
|
|
75
79
|
return uk;
|
76
80
|
}
|
77
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
|
88
|
+
}
|
89
|
+
|
78
90
|
void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
|
79
91
|
{
|
80
|
-
|
81
|
-
msgpack_rmem_free(&s_stack_rmem, uk->stack);
|
82
|
-
#else
|
83
|
-
xfree(uk->stack);
|
84
|
-
#endif
|
85
|
-
|
92
|
+
_msgpack_unpacker_free_stack(uk->stack);
|
86
93
|
msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
|
87
94
|
}
|
88
95
|
|
@@ -166,14 +173,17 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
166
173
|
return object_complete_symbol(uk, rb_str_intern(str));
|
167
174
|
}
|
168
175
|
|
169
|
-
|
176
|
+
int ext_flags;
|
177
|
+
VALUE proc = msgpack_unpacker_ext_registry_lookup(uk->ext_registry, ext_type, &ext_flags);
|
178
|
+
|
170
179
|
if(proc != Qnil) {
|
171
|
-
VALUE obj
|
180
|
+
VALUE obj;
|
181
|
+
obj = rb_funcall(proc, s_call, 1, str == Qnil ? rb_str_buf_new(0) : str);
|
172
182
|
return object_complete(uk, obj);
|
173
183
|
}
|
174
184
|
|
175
185
|
if(uk->allow_unknown_ext) {
|
176
|
-
VALUE obj = MessagePack_ExtensionValue_new(ext_type, str);
|
186
|
+
VALUE obj = MessagePack_ExtensionValue_new(ext_type, str == Qnil ? rb_str_buf_new(0) : str);
|
177
187
|
return object_complete(uk, obj);
|
178
188
|
}
|
179
189
|
|
@@ -283,6 +293,36 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
283
293
|
{
|
284
294
|
/* assuming uk->reading_raw == Qnil */
|
285
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
|
+
uk->reading_raw_remaining = 0;
|
306
|
+
|
307
|
+
msgpack_unpacker_stack_t* stack = uk->stack;
|
308
|
+
size_t stack_depth = uk->stack_depth;
|
309
|
+
size_t stack_capacity = uk->stack_capacity;
|
310
|
+
|
311
|
+
uk->stack = _msgpack_unpacker_new_stack();
|
312
|
+
uk->stack_depth = 0;
|
313
|
+
uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
314
|
+
|
315
|
+
obj = rb_funcall(proc, s_call, 1, uk->buffer.owner);
|
316
|
+
|
317
|
+
_msgpack_unpacker_free_stack(uk->stack);
|
318
|
+
uk->stack = stack;
|
319
|
+
uk->stack_depth = stack_depth;
|
320
|
+
uk->stack_capacity = stack_capacity;
|
321
|
+
|
322
|
+
return object_complete(uk, obj);
|
323
|
+
}
|
324
|
+
}
|
325
|
+
|
286
326
|
/* try optimized read */
|
287
327
|
size_t length = uk->reading_raw_remaining;
|
288
328
|
if(length <= msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk))) {
|
@@ -371,7 +411,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
371
411
|
uint8_t length = cb->u8;
|
372
412
|
int ext_type = (signed char) cb->buffer[1];
|
373
413
|
if(length == 0) {
|
374
|
-
return object_complete_ext(uk, ext_type,
|
414
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
375
415
|
}
|
376
416
|
uk->reading_raw_remaining = length;
|
377
417
|
return read_raw_body_begin(uk, ext_type);
|
@@ -383,7 +423,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
383
423
|
uint16_t length = _msgpack_be16(cb->u16);
|
384
424
|
int ext_type = (signed char) cb->buffer[2];
|
385
425
|
if(length == 0) {
|
386
|
-
return object_complete_ext(uk, ext_type,
|
426
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
387
427
|
}
|
388
428
|
uk->reading_raw_remaining = length;
|
389
429
|
return read_raw_body_begin(uk, ext_type);
|
@@ -395,7 +435,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
|
|
395
435
|
uint32_t length = _msgpack_be32(cb->u32);
|
396
436
|
int ext_type = (signed char) cb->buffer[4];
|
397
437
|
if(length == 0) {
|
398
|
-
return object_complete_ext(uk, ext_type,
|
438
|
+
return object_complete_ext(uk, ext_type, Qnil);
|
399
439
|
}
|
400
440
|
uk->reading_raw_remaining = length;
|
401
441
|
return read_raw_body_begin(uk, ext_type);
|
@@ -33,6 +33,10 @@ static VALUE eUnexpectedTypeError;
|
|
33
33
|
static VALUE eUnknownExtTypeError;
|
34
34
|
static VALUE mTypeError; // obsoleted. only for backward compatibility. See #86.
|
35
35
|
|
36
|
+
static VALUE sym_symbolize_keys;
|
37
|
+
static VALUE sym_freeze;
|
38
|
+
static VALUE sym_allow_unknown_ext;
|
39
|
+
|
36
40
|
#define UNPACKER(from, name) \
|
37
41
|
msgpack_unpacker_t *name = NULL; \
|
38
42
|
Data_Get_Struct(from, msgpack_unpacker_t, name); \
|
@@ -83,7 +87,7 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
83
87
|
} else if(argc == 2) {
|
84
88
|
io = argv[0];
|
85
89
|
options = argv[1];
|
86
|
-
if(rb_type(options) != T_HASH) {
|
90
|
+
if(options != Qnil && rb_type(options) != T_HASH) {
|
87
91
|
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
|
88
92
|
}
|
89
93
|
|
@@ -100,13 +104,13 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
100
104
|
if(options != Qnil) {
|
101
105
|
VALUE v;
|
102
106
|
|
103
|
-
v = rb_hash_aref(options,
|
107
|
+
v = rb_hash_aref(options, sym_symbolize_keys);
|
104
108
|
msgpack_unpacker_set_symbolized_keys(uk, RTEST(v));
|
105
109
|
|
106
|
-
v = rb_hash_aref(options,
|
110
|
+
v = rb_hash_aref(options, sym_freeze);
|
107
111
|
msgpack_unpacker_set_freeze(uk, RTEST(v));
|
108
112
|
|
109
|
-
v = rb_hash_aref(options,
|
113
|
+
v = rb_hash_aref(options, sym_allow_unknown_ext);
|
110
114
|
msgpack_unpacker_set_allow_unknown_ext(uk, RTEST(v));
|
111
115
|
}
|
112
116
|
|
@@ -143,6 +147,7 @@ NORETURN(static void raise_unpacker_error(int r))
|
|
143
147
|
case PRIMITIVE_UNEXPECTED_TYPE:
|
144
148
|
rb_raise(eUnexpectedTypeError, "unexpected type");
|
145
149
|
case PRIMITIVE_UNEXPECTED_EXT_TYPE:
|
150
|
+
// rb_bug("unexpected extension type");
|
146
151
|
rb_raise(eUnknownExtTypeError, "unexpected extension type");
|
147
152
|
default:
|
148
153
|
rb_raise(eUnpackError, "logically unknown error %d", r);
|
@@ -361,7 +366,7 @@ static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
|
361
366
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
362
367
|
}
|
363
368
|
|
364
|
-
msgpack_unpacker_ext_registry_put(&uk->ext_registry, ext_module, ext_type, proc, arg);
|
369
|
+
msgpack_unpacker_ext_registry_put(&uk->ext_registry, ext_module, ext_type, 0, proc, arg);
|
365
370
|
|
366
371
|
return Qnil;
|
367
372
|
}
|
@@ -411,6 +416,10 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
411
416
|
|
412
417
|
eUnknownExtTypeError = rb_define_class_under(mMessagePack, "UnknownExtTypeError", eUnpackError);
|
413
418
|
|
419
|
+
sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
|
420
|
+
sym_freeze = ID2SYM(rb_intern("freeze"));
|
421
|
+
sym_allow_unknown_ext = ID2SYM(rb_intern("allow_unknown_ext"));
|
422
|
+
|
414
423
|
rb_define_alloc_func(cMessagePack_Unpacker, MessagePack_Unpacker_alloc);
|
415
424
|
|
416
425
|
rb_define_method(cMessagePack_Unpacker, "initialize", MessagePack_Unpacker_initialize, -1);
|
@@ -77,9 +77,10 @@ void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg
|
|
77
77
|
}
|
78
78
|
|
79
79
|
void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
|
80
|
-
VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
|
80
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg)
|
81
81
|
{
|
82
82
|
msgpack_unpacker_ext_registry_t* ext_registry = msgpack_unpacker_ext_registry_cow(*ukrg);
|
83
|
-
|
83
|
+
|
84
|
+
ext_registry->array[ext_type + 128] = rb_ary_new3(4, ext_module, proc, arg, INT2FIX(flags));
|
84
85
|
*ukrg = ext_registry;
|
85
86
|
}
|
@@ -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_unpacker_ext_registry_t;
|
25
27
|
typedef struct msgpack_unpacker_ext_registry_t msgpack_unpacker_ext_registry_t;
|
26
28
|
|
@@ -46,14 +48,15 @@ static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_reg
|
|
46
48
|
void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg);
|
47
49
|
|
48
50
|
void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
|
49
|
-
VALUE ext_module, int ext_type, VALUE proc, VALUE arg);
|
51
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg);
|
50
52
|
|
51
53
|
static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_registry_t* ukrg,
|
52
|
-
int ext_type)
|
54
|
+
int ext_type, int* ext_flags_result)
|
53
55
|
{
|
54
56
|
if (ukrg) {
|
55
57
|
VALUE entry = ukrg->array[ext_type + 128];
|
56
58
|
if (entry != Qnil) {
|
59
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(entry, 3));
|
57
60
|
return rb_ary_entry(entry, 1);
|
58
61
|
}
|
59
62
|
}
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MessagePack
|
4
|
+
module Bigint
|
5
|
+
# We split the bigint in 32bits chunks so that individual part fits into
|
6
|
+
# a MRI immediate Integer.
|
7
|
+
CHUNK_BITLENGTH = 32
|
8
|
+
FORMAT = 'CL>*'
|
9
|
+
|
10
|
+
if Integer.instance_method(:[]).arity != 1 # Ruby 2.7 and newer
|
11
|
+
# Starting from Ruby 2.7 we can address arbitrary bitranges inside an Integer with Integer#[]
|
12
|
+
# This allows to not allocate any Integer.
|
13
|
+
def self.to_msgpack_ext(bigint)
|
14
|
+
members = []
|
15
|
+
|
16
|
+
if bigint < 0
|
17
|
+
bigint = -bigint
|
18
|
+
members << 1
|
19
|
+
else
|
20
|
+
members << 0
|
21
|
+
end
|
22
|
+
|
23
|
+
offset = 0
|
24
|
+
length = bigint.bit_length
|
25
|
+
while offset < length
|
26
|
+
members << bigint[offset, CHUNK_BITLENGTH]
|
27
|
+
offset += CHUNK_BITLENGTH
|
28
|
+
end
|
29
|
+
|
30
|
+
members.pack(FORMAT)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
# On 2.6 and older since we can't address arbitrary bitranges, so we fallback to shifting the bigint.
|
34
|
+
# This means that after each shift, we may allocate another Integer instance.
|
35
|
+
BASE = (2**CHUNK_BITLENGTH) - 1
|
36
|
+
def self.to_msgpack_ext(bigint)
|
37
|
+
members = []
|
38
|
+
|
39
|
+
if bigint < 0
|
40
|
+
bigint = -bigint
|
41
|
+
members << 1
|
42
|
+
else
|
43
|
+
members << 0
|
44
|
+
end
|
45
|
+
|
46
|
+
while bigint > 0
|
47
|
+
members << (bigint & BASE)
|
48
|
+
bigint = bigint >> CHUNK_BITLENGTH
|
49
|
+
end
|
50
|
+
|
51
|
+
members.pack(FORMAT)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.from_msgpack_ext(data)
|
56
|
+
parts = data.unpack(FORMAT)
|
57
|
+
|
58
|
+
sign = parts.shift
|
59
|
+
sum = parts.pop.to_i
|
60
|
+
|
61
|
+
parts.reverse_each do |part|
|
62
|
+
sum = sum << CHUNK_BITLENGTH
|
63
|
+
sum += part
|
64
|
+
end
|
65
|
+
|
66
|
+
sign == 0 ? sum : -sum
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/msgpack/factory.rb
CHANGED
@@ -77,5 +77,108 @@ module MessagePack
|
|
77
77
|
packer.full_pack
|
78
78
|
end
|
79
79
|
alias :pack :dump
|
80
|
+
|
81
|
+
def pool(size = 1, **options)
|
82
|
+
Pool.new(
|
83
|
+
frozen? ? self : dup.freeze,
|
84
|
+
size,
|
85
|
+
options.empty? ? nil : options,
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
class Pool
|
90
|
+
if RUBY_ENGINE == "ruby"
|
91
|
+
class AbstractPool
|
92
|
+
def initialize(size, &block)
|
93
|
+
@size = size
|
94
|
+
@new_member = block
|
95
|
+
@members = []
|
96
|
+
end
|
97
|
+
|
98
|
+
def checkout
|
99
|
+
@members.pop || @new_member.call
|
100
|
+
end
|
101
|
+
|
102
|
+
def checkin(member)
|
103
|
+
# If the pool is already full, we simply drop the extra member.
|
104
|
+
# This is because contrary to a connection pool, creating an extra instance
|
105
|
+
# is extremely unlikely to cause some kind of resource exhaustion.
|
106
|
+
#
|
107
|
+
# We could cycle the members (keep the newer one) but first It's more work and second
|
108
|
+
# the older member might have been created pre-fork, so it might be at least partially
|
109
|
+
# in shared memory.
|
110
|
+
if member && @members.size < @size
|
111
|
+
member.reset
|
112
|
+
@members << member
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
else
|
117
|
+
class AbstractPool
|
118
|
+
def initialize(size, &block)
|
119
|
+
@size = size
|
120
|
+
@new_member = block
|
121
|
+
@members = []
|
122
|
+
@mutex = Mutex.new
|
123
|
+
end
|
124
|
+
|
125
|
+
def checkout
|
126
|
+
@mutex.synchronize { @members.pop } || @new_member.call
|
127
|
+
end
|
128
|
+
|
129
|
+
def checkin(member)
|
130
|
+
@mutex.synchronize do
|
131
|
+
if member && @members.size < @size
|
132
|
+
member.reset
|
133
|
+
@members << member
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class PackerPool < AbstractPool
|
141
|
+
private
|
142
|
+
|
143
|
+
def reset(packer)
|
144
|
+
packer.clear
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class UnpackerPool < AbstractPool
|
149
|
+
private
|
150
|
+
|
151
|
+
def reset(unpacker)
|
152
|
+
unpacker.reset
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def initialize(factory, size, options = nil)
|
157
|
+
options = nil if !options || options.empty?
|
158
|
+
@factory = factory
|
159
|
+
@packers = PackerPool.new(size) { factory.packer(options) }
|
160
|
+
@unpackers = UnpackerPool.new(size) { factory.unpacker(options) }
|
161
|
+
end
|
162
|
+
|
163
|
+
def load(data)
|
164
|
+
unpacker = @unpackers.checkout
|
165
|
+
begin
|
166
|
+
unpacker.feed_reference(data)
|
167
|
+
unpacker.full_unpack
|
168
|
+
ensure
|
169
|
+
@unpackers.checkin(unpacker)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def dump(object)
|
174
|
+
packer = @packers.checkout
|
175
|
+
begin
|
176
|
+
packer.write(object)
|
177
|
+
packer.full_pack
|
178
|
+
ensure
|
179
|
+
@packers.checkin(packer)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
80
183
|
end
|
81
184
|
end
|
data/lib/msgpack/version.rb
CHANGED
data/lib/msgpack.rb
CHANGED
@@ -17,16 +17,15 @@ require "msgpack/time"
|
|
17
17
|
|
18
18
|
module MessagePack
|
19
19
|
DefaultFactory = MessagePack::Factory.new
|
20
|
-
DEFAULT_EMPTY_PARAMS = {}.freeze
|
21
20
|
|
22
21
|
def load(src, param = nil)
|
23
22
|
unpacker = nil
|
24
23
|
|
25
24
|
if src.is_a? String
|
26
|
-
unpacker = DefaultFactory.unpacker param
|
25
|
+
unpacker = DefaultFactory.unpacker param
|
27
26
|
unpacker.feed_reference src
|
28
27
|
else
|
29
|
-
unpacker = DefaultFactory.unpacker src, param
|
28
|
+
unpacker = DefaultFactory.unpacker src, param
|
30
29
|
end
|
31
30
|
|
32
31
|
unpacker.full_unpack
|
@@ -36,8 +35,8 @@ module MessagePack
|
|
36
35
|
module_function :load
|
37
36
|
module_function :unpack
|
38
37
|
|
39
|
-
def pack(v,
|
40
|
-
packer = DefaultFactory.packer(
|
38
|
+
def pack(v, io = nil, options = nil)
|
39
|
+
packer = DefaultFactory.packer(io, options)
|
41
40
|
packer.write v
|
42
41
|
packer.full_pack
|
43
42
|
end
|
data/spec/bigint_spec.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MessagePack::Bigint do
|
4
|
+
it 'serialize and deserialize arbitrary sized integer' do
|
5
|
+
[
|
6
|
+
1,
|
7
|
+
-1,
|
8
|
+
120938120391283122132313,
|
9
|
+
-21903120391203912391023920332103,
|
10
|
+
210290021321301203912933021323,
|
11
|
+
].each do |int|
|
12
|
+
expect(MessagePack::Bigint.from_msgpack_ext(MessagePack::Bigint.to_msgpack_ext(int))).to be == int
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'has a stable format' do
|
17
|
+
{
|
18
|
+
120938120391283122132313 => "\x00\x9F\xF4UY\x11\x92\x9A?\x00\x00\x19\x9C".b,
|
19
|
+
-21903120391203912391023920332103 => "\x01/\xB2\xBDG\xBD\xDE\xAA\xEBt\xCC\x8A\xC1\x00\x00\x01\x14".b,
|
20
|
+
210290021321301203912933021323 => "\x00\xC4\xD8\x96\x8Bm\xCB\xC7\x03\xA7{\xD4\"\x00\x00\x00\x02".b,
|
21
|
+
}.each do |int, payload|
|
22
|
+
expect(MessagePack::Bigint.to_msgpack_ext(int)).to be == payload
|
23
|
+
expect(MessagePack::Bigint.from_msgpack_ext(payload)).to be == int
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|