msgpack 1.6.0 → 1.7.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/ChangeLog +25 -0
- data/README.md +27 -0
- data/ext/java/org/msgpack/jruby/Buffer.java +3 -3
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +11 -20
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +1 -1
- data/ext/java/org/msgpack/jruby/Factory.java +11 -50
- data/ext/java/org/msgpack/jruby/Packer.java +9 -24
- data/ext/java/org/msgpack/jruby/Unpacker.java +15 -32
- data/ext/msgpack/buffer.c +16 -17
- data/ext/msgpack/buffer.h +2 -8
- data/ext/msgpack/buffer_class.c +76 -5
- data/ext/msgpack/buffer_class.h +1 -0
- data/ext/msgpack/extconf.rb +18 -26
- data/ext/msgpack/factory_class.c +27 -61
- data/ext/msgpack/packer.c +13 -14
- data/ext/msgpack/packer.h +0 -4
- data/ext/msgpack/packer_class.c +19 -54
- data/ext/msgpack/packer_ext_registry.c +31 -28
- data/ext/msgpack/packer_ext_registry.h +10 -14
- data/ext/msgpack/rbinit.c +1 -1
- data/ext/msgpack/rmem.c +3 -4
- data/ext/msgpack/unpacker.c +12 -25
- data/ext/msgpack/unpacker.h +0 -4
- data/ext/msgpack/unpacker_class.c +14 -49
- data/ext/msgpack/unpacker_ext_registry.c +4 -16
- data/ext/msgpack/unpacker_ext_registry.h +3 -7
- data/lib/msgpack/buffer.rb +9 -0
- data/lib/msgpack/factory.rb +90 -63
- data/lib/msgpack/packer.rb +10 -1
- data/lib/msgpack/unpacker.rb +14 -1
- data/lib/msgpack/version.rb +1 -1
- data/lib/msgpack.rb +1 -0
- data/msgpack.gemspec +6 -3
- metadata +19 -48
- data/.github/workflows/ci.yaml +0 -57
- data/.gitignore +0 -23
- data/.rubocop.yml +0 -36
- data/Gemfile +0 -9
- data/Rakefile +0 -70
- data/appveyor.yml +0 -18
- data/bench/bench.rb +0 -78
- data/bin/console +0 -8
- data/doclib/msgpack/buffer.rb +0 -193
- data/doclib/msgpack/core_ext.rb +0 -101
- data/doclib/msgpack/error.rb +0 -19
- data/doclib/msgpack/extension_value.rb +0 -9
- data/doclib/msgpack/factory.rb +0 -145
- data/doclib/msgpack/packer.rb +0 -209
- data/doclib/msgpack/time.rb +0 -22
- data/doclib/msgpack/timestamp.rb +0 -44
- data/doclib/msgpack/unpacker.rb +0 -183
- data/doclib/msgpack.rb +0 -87
- data/msgpack.org.md +0 -46
- data/spec/bigint_spec.rb +0 -26
- data/spec/cases.json +0 -1
- data/spec/cases.msg +0 -0
- data/spec/cases_compact.msg +0 -0
- data/spec/cases_spec.rb +0 -39
- data/spec/cruby/buffer_io_spec.rb +0 -255
- data/spec/cruby/buffer_packer.rb +0 -29
- data/spec/cruby/buffer_spec.rb +0 -592
- data/spec/cruby/buffer_unpacker.rb +0 -19
- data/spec/cruby/unpacker_spec.rb +0 -70
- data/spec/ext_value_spec.rb +0 -99
- data/spec/exttypes.rb +0 -51
- data/spec/factory_spec.rb +0 -706
- data/spec/format_spec.rb +0 -301
- data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
- data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
- data/spec/jruby/unpacker_spec.rb +0 -186
- data/spec/msgpack_spec.rb +0 -214
- data/spec/pack_spec.rb +0 -61
- data/spec/packer_spec.rb +0 -575
- data/spec/random_compat.rb +0 -24
- data/spec/spec_helper.rb +0 -72
- data/spec/timestamp_spec.rb +0 -159
- data/spec/unpack_spec.rb +0 -57
- data/spec/unpacker_spec.rb +0 -869
data/ext/msgpack/unpacker.c
CHANGED
@@ -19,20 +19,16 @@
|
|
19
19
|
#include "unpacker.h"
|
20
20
|
#include "rmem.h"
|
21
21
|
#include "extension_value_class.h"
|
22
|
+
#include <assert.h>
|
22
23
|
|
23
|
-
#if !defined(
|
24
|
-
|
25
|
-
#define UNPACKER_STACK_RMEM
|
24
|
+
#if !defined(HAVE_RB_PROC_CALL_WITH_BLOCK)
|
25
|
+
#define rb_proc_call_with_block(recv, argc, argv, block) rb_funcallv(recv, rb_intern("call"), argc, argv)
|
26
26
|
#endif
|
27
27
|
|
28
28
|
static int RAW_TYPE_STRING = 256;
|
29
29
|
static int RAW_TYPE_BINARY = 257;
|
30
30
|
|
31
|
-
static ID s_call;
|
32
|
-
|
33
|
-
#ifdef UNPACKER_STACK_RMEM
|
34
31
|
static msgpack_rmem_t s_stack_rmem;
|
35
|
-
#endif
|
36
32
|
|
37
33
|
#if !defined(HAVE_RB_HASH_NEW_CAPA)
|
38
34
|
static inline VALUE rb_hash_new_capa(long capa)
|
@@ -43,18 +39,14 @@ static inline VALUE rb_hash_new_capa(long capa)
|
|
43
39
|
|
44
40
|
void msgpack_unpacker_static_init(void)
|
45
41
|
{
|
46
|
-
|
47
|
-
msgpack_rmem_init(&s_stack_rmem);
|
48
|
-
#endif
|
42
|
+
assert(sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE);
|
49
43
|
|
50
|
-
|
44
|
+
msgpack_rmem_init(&s_stack_rmem);
|
51
45
|
}
|
52
46
|
|
53
47
|
void msgpack_unpacker_static_destroy(void)
|
54
48
|
{
|
55
|
-
#ifdef UNPACKER_STACK_RMEM
|
56
49
|
msgpack_rmem_destroy(&s_stack_rmem);
|
57
|
-
#endif
|
58
50
|
}
|
59
51
|
|
60
52
|
#define HEAD_BYTE_REQUIRED 0xc1
|
@@ -62,13 +54,8 @@ void msgpack_unpacker_static_destroy(void)
|
|
62
54
|
static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
|
63
55
|
msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
|
64
56
|
stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
65
|
-
#ifdef UNPACKER_STACK_RMEM
|
66
57
|
stack->data = msgpack_rmem_alloc(&s_stack_rmem);
|
67
58
|
/*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
|
68
|
-
#else
|
69
|
-
/*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_entry_t));*/
|
70
|
-
stack->data = xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_entry_t));
|
71
|
-
#endif
|
72
59
|
return stack;
|
73
60
|
}
|
74
61
|
|
@@ -85,11 +72,9 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
|
85
72
|
}
|
86
73
|
|
87
74
|
static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
xfree(stack->data);
|
92
|
-
#endif
|
75
|
+
if (!msgpack_rmem_free(&s_stack_rmem, stack->data)) {
|
76
|
+
rb_bug("Failed to free an rmem pointer, memory leak?");
|
77
|
+
}
|
93
78
|
xfree(stack);
|
94
79
|
}
|
95
80
|
|
@@ -120,6 +105,7 @@ void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
|
|
120
105
|
/* See MessagePack_Buffer_wrap */
|
121
106
|
/* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
|
122
107
|
rb_gc_mark(uk->buffer_ref);
|
108
|
+
rb_gc_mark(uk->self);
|
123
109
|
}
|
124
110
|
|
125
111
|
void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
|
@@ -192,7 +178,8 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
192
178
|
|
193
179
|
if(proc != Qnil) {
|
194
180
|
VALUE obj;
|
195
|
-
|
181
|
+
VALUE arg = (str == Qnil ? rb_str_buf_new(0) : str);
|
182
|
+
obj = rb_proc_call_with_block(proc, 1, &arg, Qnil);
|
196
183
|
return object_complete(uk, obj);
|
197
184
|
}
|
198
185
|
|
@@ -322,7 +309,7 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
322
309
|
child_stack->parent = uk->stack;
|
323
310
|
uk->stack = child_stack;
|
324
311
|
|
325
|
-
obj =
|
312
|
+
obj = rb_proc_call_with_block(proc, 1, &uk->self, Qnil);
|
326
313
|
|
327
314
|
uk->stack = child_stack->parent;
|
328
315
|
_msgpack_unpacker_free_stack(child_stack);
|
data/ext/msgpack/unpacker.h
CHANGED
@@ -21,9 +21,7 @@
|
|
21
21
|
#include "buffer.h"
|
22
22
|
#include "unpacker_ext_registry.h"
|
23
23
|
|
24
|
-
#ifndef MSGPACK_UNPACKER_STACK_CAPACITY
|
25
24
|
#define MSGPACK_UNPACKER_STACK_CAPACITY 128
|
26
|
-
#endif
|
27
25
|
|
28
26
|
struct msgpack_unpacker_t;
|
29
27
|
typedef struct msgpack_unpacker_t msgpack_unpacker_t;
|
@@ -49,8 +47,6 @@ struct msgpack_unpacker_stack_t {
|
|
49
47
|
msgpack_unpacker_stack_t *parent;
|
50
48
|
};
|
51
49
|
|
52
|
-
#define MSGPACK_UNPACKER_STACK_SIZE (8+4+8+8) /* assumes size_t <= 64bit, enum <= 32bit, VALUE <= 64bit */
|
53
|
-
|
54
50
|
struct msgpack_unpacker_t {
|
55
51
|
msgpack_buffer_t buffer;
|
56
52
|
msgpack_unpacker_stack_t *stack;
|
@@ -51,6 +51,7 @@ static void Unpacker_free(void *ptr)
|
|
51
51
|
static void Unpacker_mark(void *ptr)
|
52
52
|
{
|
53
53
|
msgpack_unpacker_t* uk = ptr;
|
54
|
+
msgpack_buffer_mark(uk);
|
54
55
|
msgpack_unpacker_mark(uk);
|
55
56
|
msgpack_unpacker_ext_registry_mark(uk->ext_registry);
|
56
57
|
}
|
@@ -117,7 +118,7 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
117
118
|
|
118
119
|
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
119
120
|
|
120
|
-
uk->buffer_ref =
|
121
|
+
uk->buffer_ref = Qnil;
|
121
122
|
|
122
123
|
MessagePack_Buffer_set_options(UNPACKER_BUFFER_(uk), io, options);
|
123
124
|
|
@@ -177,6 +178,9 @@ NORETURN(static void raise_unpacker_error(int r))
|
|
177
178
|
static VALUE Unpacker_buffer(VALUE self)
|
178
179
|
{
|
179
180
|
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
181
|
+
if (!RTEST(uk->buffer_ref)) {
|
182
|
+
uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
|
183
|
+
}
|
180
184
|
return uk->buffer_ref;
|
181
185
|
}
|
182
186
|
|
@@ -245,18 +249,6 @@ static VALUE Unpacker_read_map_header(VALUE self)
|
|
245
249
|
return ULONG2NUM(size); // long at least 32 bits
|
246
250
|
}
|
247
251
|
|
248
|
-
|
249
|
-
static VALUE Unpacker_feed(VALUE self, VALUE data)
|
250
|
-
{
|
251
|
-
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
252
|
-
|
253
|
-
StringValue(data);
|
254
|
-
|
255
|
-
msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), data);
|
256
|
-
|
257
|
-
return self;
|
258
|
-
}
|
259
|
-
|
260
252
|
static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
|
261
253
|
{
|
262
254
|
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
@@ -354,39 +346,19 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
|
|
354
346
|
return mapping;
|
355
347
|
}
|
356
348
|
|
357
|
-
static VALUE
|
349
|
+
static VALUE Unpacker_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
|
358
350
|
{
|
359
|
-
|
360
|
-
|
361
|
-
int ext_type;
|
362
|
-
VALUE proc;
|
363
|
-
VALUE arg;
|
364
|
-
VALUE ext_module;
|
365
|
-
|
366
|
-
switch (argc) {
|
367
|
-
case 1:
|
368
|
-
/* register_type(0x7f) {|data| block... } */
|
369
|
-
rb_need_block();
|
370
|
-
proc = rb_block_lambda();
|
371
|
-
arg = proc;
|
372
|
-
ext_module = Qnil;
|
373
|
-
break;
|
374
|
-
case 3:
|
375
|
-
/* register_type(0x7f, Time, :from_msgpack_ext) */
|
376
|
-
ext_module = argv[1];
|
377
|
-
arg = argv[2];
|
378
|
-
proc = rb_obj_method(ext_module, arg);
|
379
|
-
break;
|
380
|
-
default:
|
381
|
-
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 3)", argc);
|
351
|
+
if (OBJ_FROZEN(self)) {
|
352
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Unpacker");
|
382
353
|
}
|
383
354
|
|
384
|
-
ext_type = NUM2INT(
|
355
|
+
int ext_type = NUM2INT(rb_ext_type);
|
385
356
|
if(ext_type < -128 || ext_type > 127) {
|
386
357
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
387
358
|
}
|
388
359
|
|
389
|
-
|
360
|
+
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
361
|
+
msgpack_unpacker_ext_registry_put(self, &uk->ext_registry, ext_module, ext_type, 0, proc);
|
390
362
|
|
391
363
|
return Qnil;
|
392
364
|
}
|
@@ -419,7 +391,6 @@ VALUE MessagePack_Unpacker_new(int argc, VALUE* argv)
|
|
419
391
|
void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
420
392
|
{
|
421
393
|
msgpack_unpacker_static_init();
|
422
|
-
msgpack_unpacker_ext_registry_static_init();
|
423
394
|
|
424
395
|
mTypeError = rb_define_module_under(mMessagePack, "TypeError");
|
425
396
|
|
@@ -453,20 +424,14 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
453
424
|
rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
|
454
425
|
rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
|
455
426
|
rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
|
456
|
-
rb_define_method(cMessagePack_Unpacker, "feed",
|
457
|
-
|
427
|
+
rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed_reference, 1);
|
428
|
+
rb_define_alias(cMessagePack_Unpacker, "feed_reference", "feed");
|
458
429
|
rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
|
459
430
|
rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1);
|
460
431
|
rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
|
461
432
|
|
462
433
|
rb_define_private_method(cMessagePack_Unpacker, "registered_types_internal", Unpacker_registered_types_internal, 0);
|
463
|
-
|
464
|
-
|
465
|
-
//s_unpacker_value = MessagePack_Unpacker_alloc(cMessagePack_Unpacker);
|
466
|
-
//rb_gc_register_address(&s_unpacker_value);
|
467
|
-
//Data_Get_Struct(s_unpacker_value, msgpack_unpacker_t, s_unpacker);
|
468
|
-
/* prefer reference than copying */
|
469
|
-
//msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(s_unpacker), 0);
|
434
|
+
rb_define_private_method(cMessagePack_Unpacker, "register_type_internal", Unpacker_register_type_internal, 3);
|
470
435
|
|
471
436
|
rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
|
472
437
|
}
|
@@ -18,19 +18,6 @@
|
|
18
18
|
|
19
19
|
#include "unpacker_ext_registry.h"
|
20
20
|
|
21
|
-
static ID s_call;
|
22
|
-
static ID s_dup;
|
23
|
-
|
24
|
-
void msgpack_unpacker_ext_registry_static_init(void)
|
25
|
-
{
|
26
|
-
s_call = rb_intern("call");
|
27
|
-
s_dup = rb_intern("dup");
|
28
|
-
}
|
29
|
-
|
30
|
-
|
31
|
-
void msgpack_unpacker_ext_registry_static_destroy(void)
|
32
|
-
{ }
|
33
|
-
|
34
21
|
void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg)
|
35
22
|
{
|
36
23
|
if (ukrg) {
|
@@ -76,11 +63,12 @@ void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg
|
|
76
63
|
}
|
77
64
|
}
|
78
65
|
|
79
|
-
void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
|
80
|
-
VALUE ext_module, int ext_type, int flags, VALUE proc
|
66
|
+
void msgpack_unpacker_ext_registry_put(VALUE owner, msgpack_unpacker_ext_registry_t** ukrg,
|
67
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc)
|
81
68
|
{
|
82
69
|
msgpack_unpacker_ext_registry_t* ext_registry = msgpack_unpacker_ext_registry_cow(*ukrg);
|
83
70
|
|
84
|
-
|
71
|
+
VALUE entry = rb_ary_new3(3, ext_module, proc, INT2FIX(flags));
|
72
|
+
RB_OBJ_WRITE(owner, &ext_registry->array[ext_type + 128], entry);
|
85
73
|
*ukrg = ext_registry;
|
86
74
|
}
|
@@ -31,10 +31,6 @@ struct msgpack_unpacker_ext_registry_t {
|
|
31
31
|
VALUE array[256];
|
32
32
|
};
|
33
33
|
|
34
|
-
void msgpack_unpacker_ext_registry_static_init(void);
|
35
|
-
|
36
|
-
void msgpack_unpacker_ext_registry_static_destroy(void);
|
37
|
-
|
38
34
|
void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg);
|
39
35
|
|
40
36
|
static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_registry_t* src, msgpack_unpacker_ext_registry_t** dst)
|
@@ -47,8 +43,8 @@ static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_reg
|
|
47
43
|
|
48
44
|
void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg);
|
49
45
|
|
50
|
-
void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
|
51
|
-
VALUE ext_module, int ext_type, int flags, VALUE proc
|
46
|
+
void msgpack_unpacker_ext_registry_put(VALUE owner, msgpack_unpacker_ext_registry_t** ukrg,
|
47
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc);
|
52
48
|
|
53
49
|
static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_registry_t* ukrg,
|
54
50
|
int ext_type, int* ext_flags_result)
|
@@ -56,7 +52,7 @@ static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_re
|
|
56
52
|
if (ukrg) {
|
57
53
|
VALUE entry = ukrg->array[ext_type + 128];
|
58
54
|
if (entry != Qnil) {
|
59
|
-
*ext_flags_result = FIX2INT(rb_ary_entry(entry,
|
55
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(entry, 2));
|
60
56
|
return rb_ary_entry(entry, 1);
|
61
57
|
}
|
62
58
|
}
|
data/lib/msgpack/factory.rb
CHANGED
@@ -2,11 +2,46 @@ module MessagePack
|
|
2
2
|
class Factory
|
3
3
|
# see ext for other methods
|
4
4
|
|
5
|
+
def register_type(type, klass, options = { packer: :to_msgpack_ext, unpacker: :from_msgpack_ext })
|
6
|
+
raise FrozenError, "can't modify frozen MessagePack::Factory" if frozen?
|
7
|
+
|
8
|
+
if options
|
9
|
+
options = options.dup
|
10
|
+
case packer = options[:packer]
|
11
|
+
when nil, Proc
|
12
|
+
# all good
|
13
|
+
when String, Symbol
|
14
|
+
options[:packer] = packer.to_sym.to_proc
|
15
|
+
when Method
|
16
|
+
options[:packer] = packer.to_proc
|
17
|
+
when packer.respond_to?(:call)
|
18
|
+
options[:packer] = packer.method(:call).to_proc
|
19
|
+
else
|
20
|
+
raise ::TypeError, "expected :packer argument to be a callable object, got: #{packer.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
case unpacker = options[:unpacker]
|
24
|
+
when nil, Proc
|
25
|
+
# all good
|
26
|
+
when String, Symbol
|
27
|
+
options[:unpacker] = klass.method(unpacker).to_proc
|
28
|
+
when Method
|
29
|
+
options[:unpacker] = unpacker.to_proc
|
30
|
+
when packer.respond_to?(:call)
|
31
|
+
options[:unpacker] = unpacker.method(:call).to_proc
|
32
|
+
else
|
33
|
+
raise ::TypeError, "expected :unpacker argument to be a callable object, got: #{unpacker.inspect}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
register_type_internal(type, klass, options)
|
38
|
+
end
|
39
|
+
|
5
40
|
# [ {type: id, class: Class(or nil), packer: arg, unpacker: arg}, ... ]
|
6
41
|
def registered_types(selector=:both)
|
7
42
|
packer, unpacker = registered_types_internal
|
8
|
-
# packer: Class -> [tid, proc,
|
9
|
-
# unpacker: tid -> [klass, proc,
|
43
|
+
# packer: Class -> [tid, proc, _flags]
|
44
|
+
# unpacker: tid -> [klass, proc, _flags]
|
10
45
|
|
11
46
|
list = []
|
12
47
|
|
@@ -14,27 +49,31 @@ module MessagePack
|
|
14
49
|
when :both
|
15
50
|
packer.each_pair do |klass, ary|
|
16
51
|
type = ary[0]
|
17
|
-
|
18
|
-
|
19
|
-
if unpacker.has_key?(type)
|
20
|
-
|
52
|
+
packer_proc = ary[1]
|
53
|
+
unpacker_proc = nil
|
54
|
+
if unpacker.has_key?(type)
|
55
|
+
unpacker_proc = unpacker.delete(type)[1]
|
21
56
|
end
|
22
|
-
list << {type: type, class: klass, packer:
|
57
|
+
list << {type: type, class: klass, packer: packer_proc, unpacker: unpacker_proc}
|
23
58
|
end
|
24
59
|
|
25
60
|
# unpacker definition only
|
26
61
|
unpacker.each_pair do |type, ary|
|
27
|
-
list << {type: type, class: ary[0], packer: nil, unpacker: ary[
|
62
|
+
list << {type: type, class: ary[0], packer: nil, unpacker: ary[1]}
|
28
63
|
end
|
29
64
|
|
30
65
|
when :packer
|
31
66
|
packer.each_pair do |klass, ary|
|
32
|
-
|
67
|
+
if ary[1]
|
68
|
+
list << {type: ary[0], class: klass, packer: ary[1]}
|
69
|
+
end
|
33
70
|
end
|
34
71
|
|
35
72
|
when :unpacker
|
36
73
|
unpacker.each_pair do |type, ary|
|
37
|
-
|
74
|
+
if ary[1]
|
75
|
+
list << {type: type, class: ary[0], unpacker: ary[1]}
|
76
|
+
end
|
38
77
|
end
|
39
78
|
|
40
79
|
else
|
@@ -88,33 +127,34 @@ module MessagePack
|
|
88
127
|
|
89
128
|
class Pool
|
90
129
|
if RUBY_ENGINE == "ruby"
|
91
|
-
class
|
130
|
+
class MemberPool
|
92
131
|
def initialize(size, &block)
|
93
132
|
@size = size
|
94
133
|
@new_member = block
|
95
134
|
@members = []
|
96
135
|
end
|
97
136
|
|
98
|
-
def
|
99
|
-
@members.pop || @new_member.call
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
137
|
+
def with
|
138
|
+
member = @members.pop || @new_member.call
|
139
|
+
begin
|
140
|
+
yield member
|
141
|
+
ensure
|
142
|
+
# If the pool is already full, we simply drop the extra member.
|
143
|
+
# This is because contrary to a connection pool, creating an extra instance
|
144
|
+
# is extremely unlikely to cause some kind of resource exhaustion.
|
145
|
+
#
|
146
|
+
# We could cycle the members (keep the newer one) but first It's more work and second
|
147
|
+
# the older member might have been created pre-fork, so it might be at least partially
|
148
|
+
# in shared memory.
|
149
|
+
if member && @members.size < @size
|
150
|
+
member.reset
|
151
|
+
@members << member
|
152
|
+
end
|
113
153
|
end
|
114
154
|
end
|
115
155
|
end
|
116
156
|
else
|
117
|
-
class
|
157
|
+
class MemberPool
|
118
158
|
def initialize(size, &block)
|
119
159
|
@size = size
|
120
160
|
@new_member = block
|
@@ -122,63 +162,50 @@ module MessagePack
|
|
122
162
|
@mutex = Mutex.new
|
123
163
|
end
|
124
164
|
|
125
|
-
def
|
126
|
-
@mutex.synchronize { @members.pop } || @new_member.call
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
member.
|
133
|
-
|
165
|
+
def with
|
166
|
+
member = @mutex.synchronize { @members.pop } || @new_member.call
|
167
|
+
begin
|
168
|
+
yield member
|
169
|
+
ensure
|
170
|
+
member.reset
|
171
|
+
@mutex.synchronize do
|
172
|
+
if member && @members.size < @size
|
173
|
+
@members << member
|
174
|
+
end
|
134
175
|
end
|
135
176
|
end
|
136
177
|
end
|
137
178
|
end
|
138
179
|
end
|
139
180
|
|
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
181
|
def initialize(factory, size, options = nil)
|
157
182
|
options = nil if !options || options.empty?
|
158
183
|
@factory = factory
|
159
|
-
@packers =
|
160
|
-
@unpackers =
|
184
|
+
@packers = MemberPool.new(size) { factory.packer(options).freeze }
|
185
|
+
@unpackers = MemberPool.new(size) { factory.unpacker(options).freeze }
|
161
186
|
end
|
162
187
|
|
163
188
|
def load(data)
|
164
|
-
|
165
|
-
|
166
|
-
unpacker.feed_reference(data)
|
189
|
+
@unpackers.with do |unpacker|
|
190
|
+
unpacker.feed(data)
|
167
191
|
unpacker.full_unpack
|
168
|
-
ensure
|
169
|
-
@unpackers.checkin(unpacker)
|
170
192
|
end
|
171
193
|
end
|
172
194
|
|
173
195
|
def dump(object)
|
174
|
-
|
175
|
-
begin
|
196
|
+
@packers.with do |packer|
|
176
197
|
packer.write(object)
|
177
198
|
packer.full_pack
|
178
|
-
ensure
|
179
|
-
@packers.checkin(packer)
|
180
199
|
end
|
181
200
|
end
|
201
|
+
|
202
|
+
def unpacker(&block)
|
203
|
+
@unpackers.with(&block)
|
204
|
+
end
|
205
|
+
|
206
|
+
def packer(&block)
|
207
|
+
@packers.with(&block)
|
208
|
+
end
|
182
209
|
end
|
183
210
|
end
|
184
211
|
end
|
data/lib/msgpack/packer.rb
CHANGED
@@ -2,11 +2,20 @@ module MessagePack
|
|
2
2
|
class Packer
|
3
3
|
# see ext for other methods
|
4
4
|
|
5
|
+
# The semantic of duping a packer is just too weird.
|
6
|
+
undef_method :dup
|
7
|
+
undef_method :clone
|
8
|
+
|
9
|
+
def register_type(type, klass, method_name = nil, &block)
|
10
|
+
raise ArgumentError, "expected Module/Class got: #{klass.inspect}" unless klass.is_a?(Module)
|
11
|
+
register_type_internal(type, klass, block || method_name.to_proc)
|
12
|
+
end
|
13
|
+
|
5
14
|
def registered_types
|
6
15
|
list = []
|
7
16
|
|
8
17
|
registered_types_internal.each_pair do |klass, ary|
|
9
|
-
list << {type: ary[0], class: klass, packer: ary[
|
18
|
+
list << {type: ary[0], class: klass, packer: ary[1]}
|
10
19
|
end
|
11
20
|
|
12
21
|
list.sort{|a, b| a[:type] <=> b[:type] }
|
data/lib/msgpack/unpacker.rb
CHANGED
@@ -2,11 +2,24 @@ module MessagePack
|
|
2
2
|
class Unpacker
|
3
3
|
# see ext for other methods
|
4
4
|
|
5
|
+
# The semantic of duping an unpacker is just too weird.
|
6
|
+
undef_method :dup
|
7
|
+
undef_method :clone
|
8
|
+
|
9
|
+
def register_type(type, klass = nil, method_name = nil, &block)
|
10
|
+
if klass && method_name
|
11
|
+
block = klass.method(method_name).to_proc
|
12
|
+
elsif !block_given?
|
13
|
+
raise ArgumentError, "register_type takes either 3 arguments or a block"
|
14
|
+
end
|
15
|
+
register_type_internal(type, klass, block)
|
16
|
+
end
|
17
|
+
|
5
18
|
def registered_types
|
6
19
|
list = []
|
7
20
|
|
8
21
|
registered_types_internal.each_pair do |type, ary|
|
9
|
-
list << {type: type, class: ary[0], unpacker: ary[
|
22
|
+
list << {type: type, class: ary[0], unpacker: ary[1]}
|
10
23
|
end
|
11
24
|
|
12
25
|
list.sort{|a, b| a[:type] <=> b[:type] }
|
data/lib/msgpack/version.rb
CHANGED
data/lib/msgpack.rb
CHANGED
data/msgpack.gemspec
CHANGED
@@ -12,19 +12,22 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.homepage = "http://msgpack.org/"
|
13
13
|
s.require_paths = ["lib"]
|
14
14
|
if /java/ =~ RUBY_PLATFORM
|
15
|
-
s.files = Dir['lib/**/*.rb', 'lib/**/*.jar']
|
15
|
+
s.files = Dir['lib/**/*.rb', 'lib/**/*.jar', 'LICENSE']
|
16
16
|
s.platform = Gem::Platform.new('java')
|
17
17
|
else
|
18
|
-
s.files = `git ls-files`.split("\
|
18
|
+
s.files = `git ls-files -z`.split("\x0").reject do |f|
|
19
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features|bench|doclib|msgpack.org.md|Gemfile|Rakefile)|\.(?:git|circleci|rubocop)|appveyor)})
|
20
|
+
end
|
19
21
|
s.extensions = ["ext/msgpack/extconf.rb"]
|
20
22
|
end
|
21
23
|
|
22
|
-
s.required_ruby_version = ">= 2.
|
24
|
+
s.required_ruby_version = ">= 2.5"
|
23
25
|
|
24
26
|
s.add_development_dependency 'bundler'
|
25
27
|
s.add_development_dependency 'rake'
|
26
28
|
s.add_development_dependency 'rake-compiler', ['>= 1.1.9']
|
27
29
|
s.add_development_dependency 'rspec', ['~> 3.3']
|
30
|
+
s.add_development_dependency 'ruby_memcheck'
|
28
31
|
s.add_development_dependency 'yard'
|
29
32
|
s.add_development_dependency 'json'
|
30
33
|
s.add_development_dependency 'benchmark-ips', ['~> 2.10.0']
|