msgpack 1.7.1 → 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 +5 -0
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +5 -9
- data/ext/java/org/msgpack/jruby/Factory.java +7 -50
- data/ext/java/org/msgpack/jruby/Packer.java +3 -20
- data/ext/java/org/msgpack/jruby/Unpacker.java +8 -24
- data/ext/msgpack/buffer.c +7 -5
- data/ext/msgpack/buffer.h +3 -1
- data/ext/msgpack/buffer_class.c +72 -1
- data/ext/msgpack/buffer_class.h +1 -0
- data/ext/msgpack/extconf.rb +1 -2
- data/ext/msgpack/factory_class.c +23 -60
- data/ext/msgpack/packer.c +12 -14
- data/ext/msgpack/packer.h +0 -4
- data/ext/msgpack/packer_class.c +6 -36
- data/ext/msgpack/packer_ext_registry.c +31 -28
- data/ext/msgpack/packer_ext_registry.h +10 -14
- data/ext/msgpack/unpacker.c +7 -6
- data/ext/msgpack/unpacker_class.c +5 -30
- data/ext/msgpack/unpacker_ext_registry.c +4 -16
- data/ext/msgpack/unpacker_ext_registry.h +3 -7
- data/lib/msgpack/factory.rb +49 -10
- data/lib/msgpack/packer.rb +6 -1
- data/lib/msgpack/unpacker.rb +10 -1
- data/lib/msgpack/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f5b1af6b3a51f5ccc6bcf67c94c1fc6193b02fe01b123e2cfb06a6df9607116
|
4
|
+
data.tar.gz: cc057f24e1ffa4cdc3e331499eb04de4c2383b0657dcf0baeba08300fd20862e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3eb06321a534ca9b16e321cc4a71458532578dafe7967314a662223b1fbf4aa93449c98177fa982aa532ce3732ddda4a6d497704df0e9c874da07f378c73595c
|
7
|
+
data.tar.gz: 8e540755e3db9e21d7dfa4354854e8b0486f5a1bbf82c3994c6095022205f7873153d364df9310d8072c481de38ca2b4c3e088e4221c3451ceb9438312489419
|
data/ChangeLog
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
2023-07-18 1.7.2:
|
2
|
+
|
3
|
+
* Fix a potential GC bug when packing data using recursive extensions and buffers containing over 512KkiB of data (See #341).
|
4
|
+
* Fix a regression where feeding an empty string to an Unpacker would be considered like the end of the buffer.
|
5
|
+
|
1
6
|
2023-05-19 1.7.1:
|
2
7
|
|
3
8
|
* Fix JRuby 9.4 compatibility.
|
@@ -54,8 +54,8 @@ public class ExtensionRegistry {
|
|
54
54
|
return hash;
|
55
55
|
}
|
56
56
|
|
57
|
-
public void put(RubyModule mod, int typeId, boolean recursive, IRubyObject packerProc, IRubyObject
|
58
|
-
ExtensionEntry entry = new ExtensionEntry(mod, typeId, recursive, packerProc,
|
57
|
+
public void put(RubyModule mod, int typeId, boolean recursive, IRubyObject packerProc, IRubyObject unpackerProc) {
|
58
|
+
ExtensionEntry entry = new ExtensionEntry(mod, typeId, recursive, packerProc, unpackerProc);
|
59
59
|
extensionsByModule.put(mod, entry);
|
60
60
|
extensionsByTypeId[typeId + 128] = entry;
|
61
61
|
extensionsByAncestor.clear();
|
@@ -114,18 +114,14 @@ public class ExtensionRegistry {
|
|
114
114
|
private final int typeId;
|
115
115
|
private final boolean recursive;
|
116
116
|
private final IRubyObject packerProc;
|
117
|
-
private final IRubyObject packerArg;
|
118
117
|
private final IRubyObject unpackerProc;
|
119
|
-
private final IRubyObject unpackerArg;
|
120
118
|
|
121
|
-
public ExtensionEntry(RubyModule mod, int typeId, boolean recursive, IRubyObject packerProc, IRubyObject
|
119
|
+
public ExtensionEntry(RubyModule mod, int typeId, boolean recursive, IRubyObject packerProc, IRubyObject unpackerProc) {
|
122
120
|
this.mod = mod;
|
123
121
|
this.typeId = typeId;
|
124
122
|
this.recursive = recursive;
|
125
123
|
this.packerProc = packerProc;
|
126
|
-
this.packerArg = packerArg;
|
127
124
|
this.unpackerProc = unpackerProc;
|
128
|
-
this.unpackerArg = unpackerArg;
|
129
125
|
}
|
130
126
|
|
131
127
|
public RubyModule getExtensionModule() {
|
@@ -157,11 +153,11 @@ public class ExtensionRegistry {
|
|
157
153
|
}
|
158
154
|
|
159
155
|
public RubyArray<?> toPackerTuple(ThreadContext ctx) {
|
160
|
-
return ctx.runtime.newArray(new IRubyObject[] {ctx.runtime.newFixnum(typeId), packerProc
|
156
|
+
return ctx.runtime.newArray(new IRubyObject[] {ctx.runtime.newFixnum(typeId), packerProc});
|
161
157
|
}
|
162
158
|
|
163
159
|
public RubyArray<?> toUnpackerTuple(ThreadContext ctx) {
|
164
|
-
return ctx.runtime.newArray(new IRubyObject[] {mod, unpackerProc
|
160
|
+
return ctx.runtime.newArray(new IRubyObject[] {mod, unpackerProc});
|
165
161
|
}
|
166
162
|
|
167
163
|
public IRubyObject[] toPackerProcTypeIdPair(ThreadContext ctx) {
|
@@ -80,43 +80,15 @@ public class Factory extends RubyObject {
|
|
80
80
|
});
|
81
81
|
}
|
82
82
|
|
83
|
-
@JRubyMethod(name = "
|
84
|
-
public IRubyObject
|
83
|
+
@JRubyMethod(name = "register_type_internal", required = 3, visibility = PRIVATE)
|
84
|
+
public IRubyObject registerTypeInternal(ThreadContext ctx, IRubyObject type, IRubyObject mod, IRubyObject opts) {
|
85
85
|
testFrozen("MessagePack::Factory");
|
86
86
|
|
87
87
|
Ruby runtime = ctx.runtime;
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
IRubyObject
|
92
|
-
IRubyObject unpackerArg;
|
93
|
-
|
94
|
-
RubyHash options = null;
|
95
|
-
|
96
|
-
if (args.length == 2) {
|
97
|
-
packerArg = runtime.newSymbol("to_msgpack_ext");
|
98
|
-
unpackerArg = runtime.newSymbol("from_msgpack_ext");
|
99
|
-
} else if (args.length == 3) {
|
100
|
-
if (args[args.length - 1] instanceof RubyHash) {
|
101
|
-
options = (RubyHash) args[args.length - 1];
|
102
|
-
packerArg = options.fastARef(runtime.newSymbol("packer"));
|
103
|
-
if (packerArg != null && packerArg.isNil()) {
|
104
|
-
packerArg = null;
|
105
|
-
}
|
106
|
-
unpackerArg = options.fastARef(runtime.newSymbol("unpacker"));
|
107
|
-
if (unpackerArg != null && unpackerArg.isNil()) {
|
108
|
-
unpackerArg = null;
|
109
|
-
}
|
110
|
-
IRubyObject optimizedSymbolsParsingArg = options.fastARef(runtime.newSymbol("optimized_symbols_parsing"));
|
111
|
-
if (optimizedSymbolsParsingArg != null && optimizedSymbolsParsingArg.isTrue()) {
|
112
|
-
throw runtime.newArgumentError("JRuby implementation does not support the optimized_symbols_parsing option");
|
113
|
-
}
|
114
|
-
} else {
|
115
|
-
throw runtime.newArgumentError(String.format("expected Hash but found %s.", args[args.length - 1].getType().getName()));
|
116
|
-
}
|
117
|
-
} else {
|
118
|
-
throw runtime.newArgumentError(String.format("wrong number of arguments (%d for 2..3)", 2 + args.length));
|
119
|
-
}
|
88
|
+
RubyHash options = (RubyHash) opts;
|
89
|
+
|
90
|
+
IRubyObject packerProc = options.fastARef(runtime.newSymbol("packer"));
|
91
|
+
IRubyObject unpackerProc = options.fastARef(runtime.newSymbol("unpacker"));
|
120
92
|
|
121
93
|
long typeId = ((RubyFixnum) type).getLongValue();
|
122
94
|
if (typeId < -128 || typeId > 127) {
|
@@ -128,21 +100,6 @@ public class Factory extends RubyObject {
|
|
128
100
|
}
|
129
101
|
RubyModule extModule = (RubyModule) mod;
|
130
102
|
|
131
|
-
IRubyObject packerProc = runtime.getNil();
|
132
|
-
IRubyObject unpackerProc = runtime.getNil();
|
133
|
-
if (packerArg != null) {
|
134
|
-
packerProc = packerArg.callMethod(ctx, "to_proc");
|
135
|
-
}
|
136
|
-
if (unpackerArg != null) {
|
137
|
-
if (unpackerArg instanceof RubyString || unpackerArg instanceof RubySymbol) {
|
138
|
-
unpackerProc = extModule.method(unpackerArg.callMethod(ctx, "to_sym"));
|
139
|
-
} else if (unpackerArg instanceof RubyProc || unpackerArg instanceof RubyMethod) {
|
140
|
-
unpackerProc = unpackerArg;
|
141
|
-
} else {
|
142
|
-
unpackerProc = unpackerArg.callMethod(ctx, "method", runtime.newSymbol("call"));
|
143
|
-
}
|
144
|
-
}
|
145
|
-
|
146
103
|
boolean recursive = false;
|
147
104
|
if (options != null) {
|
148
105
|
IRubyObject recursiveExtensionArg = options.fastARef(runtime.newSymbol("recursive"));
|
@@ -151,7 +108,7 @@ public class Factory extends RubyObject {
|
|
151
108
|
}
|
152
109
|
}
|
153
110
|
|
154
|
-
extensionRegistry.put(extModule, (int) typeId, recursive, packerProc,
|
111
|
+
extensionRegistry.put(extModule, (int) typeId, recursive, packerProc, unpackerProc);
|
155
112
|
|
156
113
|
if (extModule == runtime.getSymbol() && !packerProc.isNil()) {
|
157
114
|
hasSymbolExtType = true;
|
@@ -93,28 +93,11 @@ public class Packer extends RubyObject {
|
|
93
93
|
return registry.toInternalPackerRegistry(ctx);
|
94
94
|
}
|
95
95
|
|
96
|
-
@JRubyMethod(name = "
|
97
|
-
public IRubyObject registerType(ThreadContext ctx, IRubyObject
|
96
|
+
@JRubyMethod(name = "register_type_internal", required = 3, visibility = PRIVATE)
|
97
|
+
public IRubyObject registerType(ThreadContext ctx, IRubyObject type, IRubyObject mod, IRubyObject proc) {
|
98
98
|
testFrozen("MessagePack::Packer");
|
99
99
|
|
100
100
|
Ruby runtime = ctx.runtime;
|
101
|
-
IRubyObject type = args[0];
|
102
|
-
IRubyObject mod = args[1];
|
103
|
-
|
104
|
-
IRubyObject arg;
|
105
|
-
IRubyObject proc;
|
106
|
-
if (args.length == 2) {
|
107
|
-
if (! block.isGiven()) {
|
108
|
-
throw runtime.newLocalJumpErrorNoBlock();
|
109
|
-
}
|
110
|
-
proc = block.getProcObject();
|
111
|
-
arg = proc;
|
112
|
-
} else if (args.length == 3) {
|
113
|
-
arg = args[2];
|
114
|
-
proc = arg.callMethod(ctx, "to_proc");
|
115
|
-
} else {
|
116
|
-
throw runtime.newArgumentError(String.format("wrong number of arguments (%d for 2..3)", 2 + args.length));
|
117
|
-
}
|
118
101
|
|
119
102
|
long typeId = ((RubyFixnum) type).getLongValue();
|
120
103
|
if (typeId < -128 || typeId > 127) {
|
@@ -126,7 +109,7 @@ public class Packer extends RubyObject {
|
|
126
109
|
}
|
127
110
|
RubyModule extModule = (RubyModule) mod;
|
128
111
|
|
129
|
-
registry.put(extModule, (int) typeId, false, proc,
|
112
|
+
registry.put(extModule, (int) typeId, false, proc, null);
|
130
113
|
|
131
114
|
if (extModule == runtime.getSymbol() && !proc.isNil()) {
|
132
115
|
encoder.hasSymbolExtType = true;
|
@@ -126,39 +126,23 @@ public class Unpacker extends RubyObject {
|
|
126
126
|
return registry.toInternalUnpackerRegistry(ctx);
|
127
127
|
}
|
128
128
|
|
129
|
-
@JRubyMethod(name = "
|
130
|
-
public IRubyObject
|
129
|
+
@JRubyMethod(name = "register_type_internal", required = 3, visibility = PRIVATE)
|
130
|
+
public IRubyObject registerTypeInternal(ThreadContext ctx, IRubyObject type, IRubyObject mod, IRubyObject proc) {
|
131
131
|
testFrozen("MessagePack::Unpacker");
|
132
132
|
|
133
133
|
Ruby runtime = ctx.runtime;
|
134
|
-
IRubyObject type = args[0];
|
135
|
-
|
136
|
-
RubyModule extModule;
|
137
|
-
IRubyObject arg;
|
138
|
-
IRubyObject proc;
|
139
|
-
if (args.length == 1) {
|
140
|
-
if (! block.isGiven()) {
|
141
|
-
throw runtime.newLocalJumpErrorNoBlock();
|
142
|
-
}
|
143
|
-
proc = RubyProc.newProc(runtime, block, block.type);
|
144
|
-
if (proc == null)
|
145
|
-
System.err.println("proc from Block is null");
|
146
|
-
arg = proc;
|
147
|
-
extModule = null;
|
148
|
-
} else if (args.length == 3) {
|
149
|
-
extModule = (RubyModule) args[1];
|
150
|
-
arg = args[2];
|
151
|
-
proc = extModule.method(arg);
|
152
|
-
} else {
|
153
|
-
throw runtime.newArgumentError(String.format("wrong number of arguments (%d for 1 or 3)", 2 + args.length));
|
154
|
-
}
|
155
134
|
|
156
135
|
long typeId = ((RubyFixnum) type).getLongValue();
|
157
136
|
if (typeId < -128 || typeId > 127) {
|
158
137
|
throw runtime.newRangeError(String.format("integer %d too big to convert to `signed char'", typeId));
|
159
138
|
}
|
160
139
|
|
161
|
-
|
140
|
+
RubyModule extModule = null;
|
141
|
+
if (mod != runtime.getNil()) {
|
142
|
+
extModule = (RubyModule)mod;
|
143
|
+
}
|
144
|
+
|
145
|
+
registry.put(extModule, (int) typeId, false, null, proc);
|
162
146
|
return runtime.getNil();
|
163
147
|
}
|
164
148
|
|
data/ext/msgpack/buffer.c
CHANGED
@@ -251,12 +251,14 @@ bool _msgpack_buffer_read_all2(msgpack_buffer_t* b, char* buffer, size_t length)
|
|
251
251
|
|
252
252
|
static inline msgpack_buffer_chunk_t* _msgpack_buffer_alloc_new_chunk(msgpack_buffer_t* b)
|
253
253
|
{
|
254
|
-
msgpack_buffer_chunk_t*
|
255
|
-
if(
|
256
|
-
|
254
|
+
msgpack_buffer_chunk_t* chunk = b->free_list;
|
255
|
+
if (chunk) {
|
256
|
+
b->free_list = b->free_list->next;
|
257
|
+
} else {
|
258
|
+
chunk = xmalloc(sizeof(msgpack_buffer_chunk_t));
|
257
259
|
}
|
258
|
-
|
259
|
-
return
|
260
|
+
memset(chunk, 0, sizeof(msgpack_buffer_chunk_t));
|
261
|
+
return chunk;
|
260
262
|
}
|
261
263
|
|
262
264
|
static inline void _msgpack_buffer_add_new_chunk(msgpack_buffer_t* b)
|
data/ext/msgpack/buffer.h
CHANGED
@@ -268,7 +268,9 @@ static inline size_t msgpack_buffer_append_string(msgpack_buffer_t* b, VALUE str
|
|
268
268
|
static inline size_t msgpack_buffer_append_string_reference(msgpack_buffer_t* b, VALUE string)
|
269
269
|
{
|
270
270
|
size_t length = RSTRING_LEN(string);
|
271
|
-
|
271
|
+
if (length > 0) {
|
272
|
+
_msgpack_buffer_append_long_string(b, string);
|
273
|
+
}
|
272
274
|
return length;
|
273
275
|
}
|
274
276
|
|
data/ext/msgpack/buffer_class.c
CHANGED
@@ -21,7 +21,8 @@
|
|
21
21
|
#include "buffer.h"
|
22
22
|
#include "buffer_class.h"
|
23
23
|
|
24
|
-
VALUE cMessagePack_Buffer;
|
24
|
+
VALUE cMessagePack_Buffer = Qnil;
|
25
|
+
VALUE cMessagePack_HeldBuffer = Qnil;
|
25
26
|
|
26
27
|
static ID s_read;
|
27
28
|
static ID s_readpartial;
|
@@ -34,6 +35,73 @@ static VALUE sym_read_reference_threshold;
|
|
34
35
|
static VALUE sym_write_reference_threshold;
|
35
36
|
static VALUE sym_io_buffer_size;
|
36
37
|
|
38
|
+
typedef struct msgpack_held_buffer_t msgpack_held_buffer_t;
|
39
|
+
struct msgpack_held_buffer_t {
|
40
|
+
size_t size;
|
41
|
+
VALUE mapped_strings[];
|
42
|
+
};
|
43
|
+
|
44
|
+
static void HeldBuffer_mark(void *data)
|
45
|
+
{
|
46
|
+
msgpack_held_buffer_t* held_buffer = (msgpack_held_buffer_t*)data;
|
47
|
+
for (size_t index = 0; index < held_buffer->size; index++) {
|
48
|
+
rb_gc_mark(held_buffer->mapped_strings[index]);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
static size_t HeldBuffer_memsize(const void *data)
|
53
|
+
{
|
54
|
+
const msgpack_held_buffer_t* held_buffer = (msgpack_held_buffer_t*)data;
|
55
|
+
return sizeof(size_t) + sizeof(VALUE) * held_buffer->size;
|
56
|
+
}
|
57
|
+
|
58
|
+
static const rb_data_type_t held_buffer_data_type = {
|
59
|
+
.wrap_struct_name = "msgpack:held_buffer",
|
60
|
+
.function = {
|
61
|
+
.dmark = HeldBuffer_mark,
|
62
|
+
.dfree = RUBY_TYPED_DEFAULT_FREE,
|
63
|
+
.dsize = HeldBuffer_memsize,
|
64
|
+
},
|
65
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
66
|
+
};
|
67
|
+
|
68
|
+
VALUE MessagePack_Buffer_hold(msgpack_buffer_t* buffer)
|
69
|
+
{
|
70
|
+
size_t mapped_strings_count = 0;
|
71
|
+
msgpack_buffer_chunk_t* c = buffer->head;
|
72
|
+
while (c != &buffer->tail) {
|
73
|
+
if (c->mapped_string != NO_MAPPED_STRING) {
|
74
|
+
mapped_strings_count++;
|
75
|
+
}
|
76
|
+
c = c->next;
|
77
|
+
}
|
78
|
+
if (c->mapped_string != NO_MAPPED_STRING) {
|
79
|
+
mapped_strings_count++;
|
80
|
+
}
|
81
|
+
|
82
|
+
if (mapped_strings_count == 0) {
|
83
|
+
return Qnil;
|
84
|
+
}
|
85
|
+
|
86
|
+
msgpack_held_buffer_t* held_buffer = xmalloc(sizeof(msgpack_held_buffer_t) + mapped_strings_count * sizeof(VALUE));
|
87
|
+
|
88
|
+
c = buffer->head;
|
89
|
+
mapped_strings_count = 0;
|
90
|
+
while (c != &buffer->tail) {
|
91
|
+
if (c->mapped_string != NO_MAPPED_STRING) {
|
92
|
+
held_buffer->mapped_strings[mapped_strings_count] = c->mapped_string;
|
93
|
+
mapped_strings_count++;
|
94
|
+
}
|
95
|
+
c = c->next;
|
96
|
+
}
|
97
|
+
if (c->mapped_string != NO_MAPPED_STRING) {
|
98
|
+
held_buffer->mapped_strings[mapped_strings_count] = c->mapped_string;
|
99
|
+
mapped_strings_count++;
|
100
|
+
}
|
101
|
+
held_buffer->size = mapped_strings_count;
|
102
|
+
return TypedData_Wrap_Struct(cMessagePack_HeldBuffer, &held_buffer_data_type, held_buffer);
|
103
|
+
}
|
104
|
+
|
37
105
|
|
38
106
|
#define CHECK_STRING_TYPE(value) \
|
39
107
|
value = rb_check_string_type(value); \
|
@@ -520,6 +588,9 @@ void MessagePack_Buffer_module_init(VALUE mMessagePack)
|
|
520
588
|
|
521
589
|
msgpack_buffer_static_init();
|
522
590
|
|
591
|
+
cMessagePack_HeldBuffer = rb_define_class_under(mMessagePack, "HeldBuffer", rb_cBasicObject);
|
592
|
+
rb_undef_alloc_func(cMessagePack_HeldBuffer);
|
593
|
+
|
523
594
|
cMessagePack_Buffer = rb_define_class_under(mMessagePack, "Buffer", rb_cObject);
|
524
595
|
|
525
596
|
rb_define_alloc_func(cMessagePack_Buffer, Buffer_alloc);
|
data/ext/msgpack/buffer_class.h
CHANGED
@@ -25,6 +25,7 @@ extern VALUE cMessagePack_Buffer;
|
|
25
25
|
void MessagePack_Buffer_module_init(VALUE mMessagePack);
|
26
26
|
|
27
27
|
VALUE MessagePack_Buffer_wrap(msgpack_buffer_t* b, VALUE owner);
|
28
|
+
VALUE MessagePack_Buffer_hold(msgpack_buffer_t* b);
|
28
29
|
|
29
30
|
void MessagePack_Buffer_set_options(msgpack_buffer_t* b, VALUE io, VALUE options);
|
30
31
|
|
data/ext/msgpack/extconf.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
|
3
|
-
have_header("ruby/st.h")
|
4
|
-
have_header("st.h")
|
5
3
|
have_func("rb_enc_interned_str", "ruby.h") # Ruby 3.0+
|
6
4
|
have_func("rb_hash_new_capa", "ruby.h") # Ruby 3.2+
|
5
|
+
have_func("rb_proc_call_with_block", "ruby.h") # CRuby (TruffleRuby doesn't have it)
|
7
6
|
|
8
7
|
append_cflags([
|
9
8
|
"-fvisibility=hidden",
|
data/ext/msgpack/factory_class.c
CHANGED
@@ -75,7 +75,7 @@ static const rb_data_type_t factory_data_type = {
|
|
75
75
|
.dfree = Factory_free,
|
76
76
|
.dsize = Factory_memsize,
|
77
77
|
},
|
78
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
78
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
79
79
|
};
|
80
80
|
|
81
81
|
static inline msgpack_factory_t *Factory_get(VALUE object)
|
@@ -98,7 +98,7 @@ static VALUE Factory_initialize(int argc, VALUE* argv, VALUE self)
|
|
98
98
|
{
|
99
99
|
msgpack_factory_t *fc = Factory_get(self);
|
100
100
|
|
101
|
-
msgpack_packer_ext_registry_init(&fc->pkrg);
|
101
|
+
msgpack_packer_ext_registry_init(self, &fc->pkrg);
|
102
102
|
// fc->ukrg is lazily initialized
|
103
103
|
|
104
104
|
fc->has_symbol_ext_type = false;
|
@@ -124,7 +124,7 @@ static VALUE Factory_dup(VALUE self)
|
|
124
124
|
cloned_fc->has_symbol_ext_type = fc->has_symbol_ext_type;
|
125
125
|
cloned_fc->pkrg = fc->pkrg;
|
126
126
|
msgpack_unpacker_ext_registry_borrow(fc->ukrg, &cloned_fc->ukrg);
|
127
|
-
msgpack_packer_ext_registry_dup(&fc->pkrg, &cloned_fc->pkrg);
|
127
|
+
msgpack_packer_ext_registry_dup(clone, &fc->pkrg, &cloned_fc->pkrg);
|
128
128
|
|
129
129
|
return clone;
|
130
130
|
}
|
@@ -139,7 +139,7 @@ static VALUE Factory_freeze(VALUE self) {
|
|
139
139
|
// If the factory is frozen, we can safely share the packer cache between
|
140
140
|
// all packers. So we eagerly create it now so it's available when #packer
|
141
141
|
// is called.
|
142
|
-
fc->pkrg.cache
|
142
|
+
RB_OBJ_WRITE(self, &fc->pkrg.cache, rb_hash_new());
|
143
143
|
}
|
144
144
|
}
|
145
145
|
|
@@ -158,7 +158,7 @@ VALUE MessagePack_Factory_packer(int argc, VALUE* argv, VALUE self)
|
|
158
158
|
|
159
159
|
msgpack_packer_t* pk = MessagePack_Packer_get(packer);
|
160
160
|
msgpack_packer_ext_registry_destroy(&pk->ext_registry);
|
161
|
-
|
161
|
+
msgpack_packer_ext_registry_borrow(packer, &fc->pkrg, &pk->ext_registry);
|
162
162
|
pk->has_bigint_ext_type = fc->has_bigint_ext_type;
|
163
163
|
pk->has_symbol_ext_type = fc->has_symbol_ext_type;
|
164
164
|
|
@@ -187,7 +187,7 @@ static VALUE Factory_registered_types_internal(VALUE self)
|
|
187
187
|
VALUE uk_mapping = rb_hash_new();
|
188
188
|
if (fc->ukrg) {
|
189
189
|
for(int i=0; i < 256; i++) {
|
190
|
-
if(fc->ukrg->array[i]
|
190
|
+
if(!NIL_P(fc->ukrg->array[i])) {
|
191
191
|
rb_hash_aset(uk_mapping, INT2FIX(i - 128), fc->ukrg->array[i]);
|
192
192
|
}
|
193
193
|
}
|
@@ -200,72 +200,35 @@ static VALUE Factory_registered_types_internal(VALUE self)
|
|
200
200
|
);
|
201
201
|
}
|
202
202
|
|
203
|
-
static VALUE
|
203
|
+
static VALUE Factory_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE options)
|
204
204
|
{
|
205
205
|
msgpack_factory_t *fc = Factory_get(self);
|
206
206
|
|
207
|
-
|
208
|
-
int flags = 0;
|
209
|
-
VALUE ext_module;
|
210
|
-
VALUE options = Qnil;
|
211
|
-
VALUE packer_arg, unpacker_arg;
|
212
|
-
VALUE packer_proc, unpacker_proc;
|
207
|
+
Check_Type(rb_ext_type, T_FIXNUM);
|
213
208
|
|
214
|
-
if
|
215
|
-
rb_raise(
|
209
|
+
if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
|
210
|
+
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
216
211
|
}
|
217
212
|
|
218
|
-
|
219
|
-
case 2:
|
220
|
-
/* register_type(0x7f, Time) */
|
221
|
-
packer_arg = ID2SYM(rb_intern("to_msgpack_ext"));
|
222
|
-
unpacker_arg = ID2SYM(rb_intern("from_msgpack_ext"));
|
223
|
-
break;
|
224
|
-
case 3:
|
225
|
-
/* register_type(0x7f, Time, packer: proc-like, unpacker: proc-like) */
|
226
|
-
options = argv[2];
|
227
|
-
if(rb_type(options) != T_HASH) {
|
228
|
-
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
|
229
|
-
}
|
213
|
+
int flags = 0;
|
230
214
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
215
|
+
VALUE packer_proc = Qnil;
|
216
|
+
VALUE unpacker_proc = Qnil;
|
217
|
+
if(!NIL_P(options)) {
|
218
|
+
Check_Type(options, T_HASH);
|
219
|
+
packer_proc = rb_hash_aref(options, ID2SYM(rb_intern("packer")));
|
220
|
+
unpacker_proc = rb_hash_aref(options, ID2SYM(rb_intern("unpacker")));
|
236
221
|
}
|
237
222
|
|
238
|
-
if (
|
239
|
-
|
223
|
+
if (OBJ_FROZEN(self)) {
|
224
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Factory");
|
240
225
|
}
|
241
226
|
|
242
|
-
ext_type = NUM2INT(
|
227
|
+
int ext_type = NUM2INT(rb_ext_type);
|
243
228
|
if(ext_type < -128 || ext_type > 127) {
|
244
229
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
245
230
|
}
|
246
231
|
|
247
|
-
ext_module = argv[1];
|
248
|
-
if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
|
249
|
-
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
250
|
-
}
|
251
|
-
|
252
|
-
packer_proc = Qnil;
|
253
|
-
unpacker_proc = Qnil;
|
254
|
-
|
255
|
-
if(packer_arg != Qnil) {
|
256
|
-
packer_proc = rb_funcall(packer_arg, rb_intern("to_proc"), 0);
|
257
|
-
}
|
258
|
-
|
259
|
-
if(unpacker_arg != Qnil) {
|
260
|
-
if(rb_type(unpacker_arg) == T_SYMBOL || rb_type(unpacker_arg) == T_STRING) {
|
261
|
-
unpacker_proc = rb_obj_method(ext_module, unpacker_arg);
|
262
|
-
} else if (rb_respond_to(unpacker_arg, rb_intern("call"))) {
|
263
|
-
unpacker_proc = unpacker_arg;
|
264
|
-
} else {
|
265
|
-
unpacker_proc = rb_funcall(unpacker_arg, rb_intern("method"), 1, ID2SYM(rb_intern("call")));
|
266
|
-
}
|
267
|
-
}
|
268
|
-
|
269
232
|
if(ext_module == rb_cSymbol) {
|
270
233
|
if(NIL_P(options) || RTEST(rb_hash_aref(options, ID2SYM(rb_intern("packer"))))) {
|
271
234
|
fc->has_symbol_ext_type = true;
|
@@ -289,8 +252,8 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
289
252
|
}
|
290
253
|
}
|
291
254
|
|
292
|
-
msgpack_packer_ext_registry_put(&fc->pkrg, ext_module, ext_type, flags, packer_proc
|
293
|
-
msgpack_unpacker_ext_registry_put(&fc->ukrg, ext_module, ext_type, flags, unpacker_proc
|
255
|
+
msgpack_packer_ext_registry_put(self, &fc->pkrg, ext_module, ext_type, flags, packer_proc);
|
256
|
+
msgpack_unpacker_ext_registry_put(self, &fc->ukrg, ext_module, ext_type, flags, unpacker_proc);
|
294
257
|
|
295
258
|
return Qnil;
|
296
259
|
}
|
@@ -309,5 +272,5 @@ void MessagePack_Factory_module_init(VALUE mMessagePack)
|
|
309
272
|
rb_define_method(cMessagePack_Factory, "unpacker", MessagePack_Factory_unpacker, -1);
|
310
273
|
|
311
274
|
rb_define_private_method(cMessagePack_Factory, "registered_types_internal", Factory_registered_types_internal, 0);
|
312
|
-
|
275
|
+
rb_define_private_method(cMessagePack_Factory, "register_type_internal", Factory_register_type_internal, 3);
|
313
276
|
}
|
data/ext/msgpack/packer.c
CHANGED
@@ -17,16 +17,11 @@
|
|
17
17
|
*/
|
18
18
|
|
19
19
|
#include "packer.h"
|
20
|
+
#include "buffer_class.h"
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
{
|
25
|
-
s_call = rb_intern("call");
|
26
|
-
}
|
27
|
-
|
28
|
-
void msgpack_packer_static_destroy(void)
|
29
|
-
{ }
|
22
|
+
#if !defined(HAVE_RB_PROC_CALL_WITH_BLOCK)
|
23
|
+
#define rb_proc_call_with_block(recv, argc, argv, block) rb_funcallv(recv, rb_intern("call"), argc, argv)
|
24
|
+
#endif
|
30
25
|
|
31
26
|
void msgpack_packer_init(msgpack_packer_t* pk)
|
32
27
|
{
|
@@ -100,14 +95,13 @@ struct msgpack_call_proc_args_t;
|
|
100
95
|
typedef struct msgpack_call_proc_args_t msgpack_call_proc_args_t;
|
101
96
|
struct msgpack_call_proc_args_t {
|
102
97
|
VALUE proc;
|
103
|
-
VALUE
|
104
|
-
VALUE packer;
|
98
|
+
VALUE args[2];
|
105
99
|
};
|
106
100
|
|
107
101
|
VALUE msgpack_packer_try_calling_proc(VALUE value)
|
108
102
|
{
|
109
103
|
msgpack_call_proc_args_t *args = (msgpack_call_proc_args_t *)value;
|
110
|
-
return
|
104
|
+
return rb_proc_call_with_block(args->proc, 2, args->args, Qnil);
|
111
105
|
}
|
112
106
|
|
113
107
|
bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v)
|
@@ -121,11 +115,13 @@ bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v
|
|
121
115
|
}
|
122
116
|
|
123
117
|
if(ext_flags & MSGPACK_EXT_RECURSIVE) {
|
118
|
+
VALUE held_buffer = MessagePack_Buffer_hold(&pk->buffer);
|
119
|
+
|
124
120
|
msgpack_buffer_t parent_buffer = pk->buffer;
|
125
121
|
msgpack_buffer_init(PACKER_BUFFER_(pk));
|
126
122
|
|
127
123
|
int exception_occured = 0;
|
128
|
-
msgpack_call_proc_args_t args = { proc, v, pk->to_msgpack_arg };
|
124
|
+
msgpack_call_proc_args_t args = { proc, { v, pk->to_msgpack_arg } };
|
129
125
|
rb_protect(msgpack_packer_try_calling_proc, (VALUE)&args, &exception_occured);
|
130
126
|
|
131
127
|
if (exception_occured) {
|
@@ -139,8 +135,10 @@ bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v
|
|
139
135
|
pk->buffer = parent_buffer;
|
140
136
|
msgpack_packer_write_ext(pk, ext_type, payload);
|
141
137
|
}
|
138
|
+
|
139
|
+
RB_GC_GUARD(held_buffer);
|
142
140
|
} else {
|
143
|
-
VALUE payload =
|
141
|
+
VALUE payload = rb_proc_call_with_block(proc, 1, &v, Qnil);
|
144
142
|
StringValue(payload);
|
145
143
|
msgpack_packer_write_ext(pk, ext_type, payload);
|
146
144
|
}
|
data/ext/msgpack/packer.h
CHANGED
@@ -47,10 +47,6 @@ struct msgpack_packer_t {
|
|
47
47
|
|
48
48
|
#define PACKER_BUFFER_(pk) (&(pk)->buffer)
|
49
49
|
|
50
|
-
void msgpack_packer_static_init(void);
|
51
|
-
|
52
|
-
void msgpack_packer_static_destroy(void);
|
53
|
-
|
54
50
|
void msgpack_packer_init(msgpack_packer_t* pk);
|
55
51
|
|
56
52
|
void msgpack_packer_destroy(msgpack_packer_t* pk);
|
data/ext/msgpack/packer_class.c
CHANGED
@@ -106,8 +106,8 @@ VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
|
|
106
106
|
|
107
107
|
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
108
108
|
|
109
|
-
msgpack_packer_ext_registry_init(&pk->ext_registry);
|
110
|
-
pk->buffer_ref =
|
109
|
+
msgpack_packer_ext_registry_init(self, &pk->ext_registry);
|
110
|
+
pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self);
|
111
111
|
|
112
112
|
MessagePack_Buffer_set_options(PACKER_BUFFER_(pk), io, options);
|
113
113
|
|
@@ -352,7 +352,7 @@ static VALUE Packer_registered_types_internal(VALUE self)
|
|
352
352
|
return rb_hash_new();
|
353
353
|
}
|
354
354
|
|
355
|
-
static VALUE
|
355
|
+
static VALUE Packer_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
|
356
356
|
{
|
357
357
|
if (OBJ_FROZEN(self)) {
|
358
358
|
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Packer");
|
@@ -360,38 +360,12 @@ static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
|
|
360
360
|
|
361
361
|
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
362
362
|
|
363
|
-
int ext_type;
|
364
|
-
VALUE ext_module;
|
365
|
-
VALUE proc;
|
366
|
-
VALUE arg;
|
367
|
-
|
368
|
-
switch (argc) {
|
369
|
-
case 2:
|
370
|
-
/* register_type(0x7f, Time) {|obj| block... } */
|
371
|
-
rb_need_block();
|
372
|
-
proc = rb_block_lambda();
|
373
|
-
arg = proc;
|
374
|
-
break;
|
375
|
-
case 3:
|
376
|
-
/* register_type(0x7f, Time, :to_msgpack_ext) */
|
377
|
-
arg = argv[2];
|
378
|
-
proc = rb_funcall(arg, rb_intern("to_proc"), 0);
|
379
|
-
break;
|
380
|
-
default:
|
381
|
-
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2..3)", argc);
|
382
|
-
}
|
383
|
-
|
384
|
-
ext_type = NUM2INT(argv[0]);
|
363
|
+
int ext_type = NUM2INT(rb_ext_type);
|
385
364
|
if(ext_type < -128 || ext_type > 127) {
|
386
365
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
387
366
|
}
|
388
367
|
|
389
|
-
ext_module
|
390
|
-
if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
|
391
|
-
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
392
|
-
}
|
393
|
-
|
394
|
-
msgpack_packer_ext_registry_put(&pk->ext_registry, ext_module, ext_type, 0, proc, arg);
|
368
|
+
msgpack_packer_ext_registry_put(self, &pk->ext_registry, ext_module, ext_type, 0, proc);
|
395
369
|
|
396
370
|
if (ext_module == rb_cSymbol) {
|
397
371
|
pk->has_symbol_ext_type = true;
|
@@ -424,10 +398,6 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
|
|
424
398
|
s_write = rb_intern("write");
|
425
399
|
|
426
400
|
sym_compatibility_mode = ID2SYM(rb_intern("compatibility_mode"));
|
427
|
-
|
428
|
-
msgpack_packer_static_init();
|
429
|
-
msgpack_packer_ext_registry_static_init();
|
430
|
-
|
431
401
|
cMessagePack_Packer = rb_define_class_under(mMessagePack, "Packer", rb_cObject);
|
432
402
|
|
433
403
|
rb_define_alloc_func(cMessagePack_Packer, MessagePack_Packer_alloc);
|
@@ -466,7 +436,7 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
|
|
466
436
|
rb_define_method(cMessagePack_Packer, "to_a", Packer_to_a, 0);
|
467
437
|
|
468
438
|
rb_define_private_method(cMessagePack_Packer, "registered_types_internal", Packer_registered_types_internal, 0);
|
469
|
-
rb_define_method(cMessagePack_Packer, "
|
439
|
+
rb_define_method(cMessagePack_Packer, "register_type_internal", Packer_register_type_internal, 3);
|
470
440
|
|
471
441
|
rb_define_method(cMessagePack_Packer, "full_pack", Packer_full_pack, 0);
|
472
442
|
}
|
@@ -18,20 +18,10 @@
|
|
18
18
|
|
19
19
|
#include "packer_ext_registry.h"
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
void msgpack_packer_ext_registry_static_init(void)
|
24
|
-
{
|
25
|
-
s_call = rb_intern("call");
|
26
|
-
}
|
27
|
-
|
28
|
-
void msgpack_packer_ext_registry_static_destroy(void)
|
29
|
-
{ }
|
30
|
-
|
31
|
-
void msgpack_packer_ext_registry_init(msgpack_packer_ext_registry_t* pkrg)
|
21
|
+
void msgpack_packer_ext_registry_init(VALUE owner, msgpack_packer_ext_registry_t* pkrg)
|
32
22
|
{
|
33
|
-
pkrg->hash
|
34
|
-
pkrg->cache
|
23
|
+
RB_OBJ_WRITE(owner, &pkrg->hash, Qnil);
|
24
|
+
RB_OBJ_WRITE(owner, &pkrg->cache, Qnil);
|
35
25
|
}
|
36
26
|
|
37
27
|
void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
|
@@ -40,32 +30,45 @@ void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
|
|
40
30
|
rb_gc_mark(pkrg->cache);
|
41
31
|
}
|
42
32
|
|
43
|
-
void
|
33
|
+
void msgpack_packer_ext_registry_borrow(VALUE owner, msgpack_packer_ext_registry_t* src,
|
44
34
|
msgpack_packer_ext_registry_t* dst)
|
45
35
|
{
|
46
|
-
if(RTEST(src->hash)
|
47
|
-
|
48
|
-
|
36
|
+
if(RTEST(src->hash)) {
|
37
|
+
if(rb_obj_frozen_p(src->hash)) {
|
38
|
+
// If the type registry is frozen we can safely share it, and share the cache as well.
|
39
|
+
RB_OBJ_WRITE(owner, &dst->hash, src->hash);
|
40
|
+
RB_OBJ_WRITE(owner, &dst->cache, src->cache);
|
41
|
+
} else {
|
42
|
+
RB_OBJ_WRITE(owner, &dst->hash, rb_hash_dup(src->hash));
|
43
|
+
RB_OBJ_WRITE(owner, &dst->cache, NIL_P(src->cache) ? Qnil : rb_hash_dup(src->cache));
|
44
|
+
}
|
49
45
|
} else {
|
50
|
-
|
51
|
-
dst->
|
52
|
-
dst->cache = src->cache;
|
46
|
+
RB_OBJ_WRITE(owner, &dst->hash, Qnil);
|
47
|
+
RB_OBJ_WRITE(owner, &dst->cache, Qnil);
|
53
48
|
}
|
54
49
|
}
|
55
50
|
|
56
|
-
VALUE
|
57
|
-
|
51
|
+
void msgpack_packer_ext_registry_dup(VALUE owner, msgpack_packer_ext_registry_t* src,
|
52
|
+
msgpack_packer_ext_registry_t* dst)
|
58
53
|
{
|
59
|
-
|
60
|
-
|
54
|
+
RB_OBJ_WRITE(owner, &dst->hash, NIL_P(src->hash) ? Qnil : rb_hash_dup(src->hash));
|
55
|
+
RB_OBJ_WRITE(owner, &dst->cache, NIL_P(src->cache) ? Qnil : rb_hash_dup(src->cache));
|
56
|
+
}
|
57
|
+
|
58
|
+
void msgpack_packer_ext_registry_put(VALUE owner, msgpack_packer_ext_registry_t* pkrg,
|
59
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc)
|
60
|
+
{
|
61
|
+
if(NIL_P(pkrg->hash)) {
|
62
|
+
RB_OBJ_WRITE(owner, &pkrg->hash, rb_hash_new());
|
61
63
|
}
|
62
64
|
|
63
|
-
if
|
65
|
+
if(NIL_P(pkrg->cache)) {
|
66
|
+
RB_OBJ_WRITE(owner, &pkrg->cache, rb_hash_new());
|
67
|
+
} else {
|
64
68
|
/* clear lookup cache not to miss added type */
|
65
69
|
rb_hash_clear(pkrg->cache);
|
66
70
|
}
|
67
71
|
|
68
|
-
|
69
|
-
|
70
|
-
return rb_hash_aset(pkrg->hash, ext_module, entry);
|
72
|
+
VALUE entry = rb_ary_new3(3, INT2FIX(ext_type), proc, INT2FIX(flags));
|
73
|
+
rb_hash_aset(pkrg->hash, ext_module, entry);
|
71
74
|
}
|
@@ -31,22 +31,21 @@ struct msgpack_packer_ext_registry_t {
|
|
31
31
|
VALUE cache; // lookup cache for ext types inherited from a super class
|
32
32
|
};
|
33
33
|
|
34
|
-
void
|
35
|
-
|
36
|
-
void msgpack_packer_ext_registry_static_destroy(void);
|
37
|
-
|
38
|
-
void msgpack_packer_ext_registry_init(msgpack_packer_ext_registry_t* pkrg);
|
34
|
+
void msgpack_packer_ext_registry_init(VALUE owner, msgpack_packer_ext_registry_t* pkrg);
|
39
35
|
|
40
36
|
static inline void msgpack_packer_ext_registry_destroy(msgpack_packer_ext_registry_t* pkrg)
|
41
37
|
{ }
|
42
38
|
|
43
39
|
void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg);
|
44
40
|
|
45
|
-
void
|
41
|
+
void msgpack_packer_ext_registry_borrow(VALUE owner, msgpack_packer_ext_registry_t* src,
|
46
42
|
msgpack_packer_ext_registry_t* dst);
|
47
43
|
|
48
|
-
VALUE
|
49
|
-
|
44
|
+
void msgpack_packer_ext_registry_dup(VALUE owner, msgpack_packer_ext_registry_t* src,
|
45
|
+
msgpack_packer_ext_registry_t* dst);
|
46
|
+
|
47
|
+
void msgpack_packer_ext_registry_put(VALUE owner, msgpack_packer_ext_registry_t* pkrg,
|
48
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc);
|
50
49
|
|
51
50
|
static int msgpack_packer_ext_find_superclass(VALUE key, VALUE value, VALUE arg)
|
52
51
|
{
|
@@ -68,7 +67,7 @@ static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registr
|
|
68
67
|
VALUE type = rb_hash_lookup(pkrg->hash, lookup_class);
|
69
68
|
if(type != Qnil) {
|
70
69
|
*ext_type_result = FIX2INT(rb_ary_entry(type, 0));
|
71
|
-
*ext_flags_result = FIX2INT(rb_ary_entry(type,
|
70
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(type, 2));
|
72
71
|
return rb_ary_entry(type, 1);
|
73
72
|
}
|
74
73
|
|
@@ -77,7 +76,7 @@ static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registr
|
|
77
76
|
VALUE type_inht = rb_hash_lookup(pkrg->cache, lookup_class);
|
78
77
|
if(type_inht != Qnil) {
|
79
78
|
*ext_type_result = FIX2INT(rb_ary_entry(type_inht, 0));
|
80
|
-
*ext_flags_result = FIX2INT(rb_ary_entry(type_inht,
|
79
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(type_inht, 2));
|
81
80
|
return rb_ary_entry(type_inht, 1);
|
82
81
|
}
|
83
82
|
}
|
@@ -129,12 +128,9 @@ static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_regist
|
|
129
128
|
VALUE superclass = args[1];
|
130
129
|
if(superclass != Qnil) {
|
131
130
|
VALUE superclass_type = rb_hash_lookup(pkrg->hash, superclass);
|
132
|
-
if (!RTEST(pkrg->cache)) {
|
133
|
-
pkrg->cache = rb_hash_new();
|
134
|
-
}
|
135
131
|
rb_hash_aset(pkrg->cache, lookup_class, superclass_type);
|
136
132
|
*ext_type_result = FIX2INT(rb_ary_entry(superclass_type, 0));
|
137
|
-
*ext_flags_result = FIX2INT(rb_ary_entry(superclass_type,
|
133
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(superclass_type, 2));
|
138
134
|
return rb_ary_entry(superclass_type, 1);
|
139
135
|
}
|
140
136
|
|
data/ext/msgpack/unpacker.c
CHANGED
@@ -21,11 +21,13 @@
|
|
21
21
|
#include "extension_value_class.h"
|
22
22
|
#include <assert.h>
|
23
23
|
|
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
|
+
#endif
|
27
|
+
|
24
28
|
static int RAW_TYPE_STRING = 256;
|
25
29
|
static int RAW_TYPE_BINARY = 257;
|
26
30
|
|
27
|
-
static ID s_call;
|
28
|
-
|
29
31
|
static msgpack_rmem_t s_stack_rmem;
|
30
32
|
|
31
33
|
#if !defined(HAVE_RB_HASH_NEW_CAPA)
|
@@ -40,8 +42,6 @@ void msgpack_unpacker_static_init(void)
|
|
40
42
|
assert(sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE);
|
41
43
|
|
42
44
|
msgpack_rmem_init(&s_stack_rmem);
|
43
|
-
|
44
|
-
s_call = rb_intern("call");
|
45
45
|
}
|
46
46
|
|
47
47
|
void msgpack_unpacker_static_destroy(void)
|
@@ -178,7 +178,8 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
178
178
|
|
179
179
|
if(proc != Qnil) {
|
180
180
|
VALUE obj;
|
181
|
-
|
181
|
+
VALUE arg = (str == Qnil ? rb_str_buf_new(0) : str);
|
182
|
+
obj = rb_proc_call_with_block(proc, 1, &arg, Qnil);
|
182
183
|
return object_complete(uk, obj);
|
183
184
|
}
|
184
185
|
|
@@ -308,7 +309,7 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
308
309
|
child_stack->parent = uk->stack;
|
309
310
|
uk->stack = child_stack;
|
310
311
|
|
311
|
-
obj =
|
312
|
+
obj = rb_proc_call_with_block(proc, 1, &uk->self, Qnil);
|
312
313
|
|
313
314
|
uk->stack = child_stack->parent;
|
314
315
|
_msgpack_unpacker_free_stack(child_stack);
|
@@ -346,43 +346,19 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
|
|
346
346
|
return mapping;
|
347
347
|
}
|
348
348
|
|
349
|
-
static VALUE
|
349
|
+
static VALUE Unpacker_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
|
350
350
|
{
|
351
351
|
if (OBJ_FROZEN(self)) {
|
352
352
|
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Unpacker");
|
353
353
|
}
|
354
354
|
|
355
|
-
|
356
|
-
|
357
|
-
int ext_type;
|
358
|
-
VALUE proc;
|
359
|
-
VALUE arg;
|
360
|
-
VALUE ext_module;
|
361
|
-
|
362
|
-
switch (argc) {
|
363
|
-
case 1:
|
364
|
-
/* register_type(0x7f) {|data| block... } */
|
365
|
-
rb_need_block();
|
366
|
-
proc = rb_block_lambda();
|
367
|
-
arg = proc;
|
368
|
-
ext_module = Qnil;
|
369
|
-
break;
|
370
|
-
case 3:
|
371
|
-
/* register_type(0x7f, Time, :from_msgpack_ext) */
|
372
|
-
ext_module = argv[1];
|
373
|
-
arg = argv[2];
|
374
|
-
proc = rb_obj_method(ext_module, arg);
|
375
|
-
break;
|
376
|
-
default:
|
377
|
-
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 3)", argc);
|
378
|
-
}
|
379
|
-
|
380
|
-
ext_type = NUM2INT(argv[0]);
|
355
|
+
int ext_type = NUM2INT(rb_ext_type);
|
381
356
|
if(ext_type < -128 || ext_type > 127) {
|
382
357
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
383
358
|
}
|
384
359
|
|
385
|
-
|
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);
|
386
362
|
|
387
363
|
return Qnil;
|
388
364
|
}
|
@@ -415,7 +391,6 @@ VALUE MessagePack_Unpacker_new(int argc, VALUE* argv)
|
|
415
391
|
void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
416
392
|
{
|
417
393
|
msgpack_unpacker_static_init();
|
418
|
-
msgpack_unpacker_ext_registry_static_init();
|
419
394
|
|
420
395
|
mTypeError = rb_define_module_under(mMessagePack, "TypeError");
|
421
396
|
|
@@ -456,7 +431,7 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
456
431
|
rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
|
457
432
|
|
458
433
|
rb_define_private_method(cMessagePack_Unpacker, "registered_types_internal", Unpacker_registered_types_internal, 0);
|
459
|
-
|
434
|
+
rb_define_private_method(cMessagePack_Unpacker, "register_type_internal", Unpacker_register_type_internal, 3);
|
460
435
|
|
461
436
|
rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
|
462
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
|
data/lib/msgpack/packer.rb
CHANGED
@@ -6,11 +6,16 @@ module MessagePack
|
|
6
6
|
undef_method :dup
|
7
7
|
undef_method :clone
|
8
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
|
+
|
9
14
|
def registered_types
|
10
15
|
list = []
|
11
16
|
|
12
17
|
registered_types_internal.each_pair do |klass, ary|
|
13
|
-
list << {type: ary[0], class: klass, packer: ary[
|
18
|
+
list << {type: ary[0], class: klass, packer: ary[1]}
|
14
19
|
end
|
15
20
|
|
16
21
|
list.sort{|a, b| a[:type] <=> b[:type] }
|
data/lib/msgpack/unpacker.rb
CHANGED
@@ -6,11 +6,20 @@ module MessagePack
|
|
6
6
|
undef_method :dup
|
7
7
|
undef_method :clone
|
8
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
|
+
|
9
18
|
def registered_types
|
10
19
|
list = []
|
11
20
|
|
12
21
|
registered_types_internal.each_pair do |type, ary|
|
13
|
-
list << {type: type, class: ary[0], unpacker: ary[
|
22
|
+
list << {type: type, class: ary[0], unpacker: ary[1]}
|
14
23
|
end
|
15
24
|
|
16
25
|
list.sort{|a, b| a[:type] <=> b[:type] }
|
data/lib/msgpack/version.rb
CHANGED
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.7.
|
4
|
+
version: 1.7.2
|
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: 2023-
|
13
|
+
date: 2023-07-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
@@ -208,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
208
208
|
- !ruby/object:Gem::Version
|
209
209
|
version: '0'
|
210
210
|
requirements: []
|
211
|
-
rubygems_version: 3.
|
211
|
+
rubygems_version: 3.3.7
|
212
212
|
signing_key:
|
213
213
|
specification_version: 4
|
214
214
|
summary: MessagePack, a binary-based efficient data interchange format.
|