msgpack 1.0.3-x64-mingw32 → 1.1.0-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +4 -0
- data/ext/java/org/msgpack/jruby/Encoder.java +10 -1
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +33 -33
- data/ext/java/org/msgpack/jruby/Factory.java +8 -7
- data/ext/java/org/msgpack/jruby/Packer.java +7 -6
- data/ext/java/org/msgpack/jruby/Unpacker.java +6 -5
- data/ext/msgpack/factory_class.c +8 -8
- data/ext/msgpack/packer.c +21 -2
- data/ext/msgpack/packer_class.c +6 -6
- data/ext/msgpack/packer_ext_registry.c +2 -2
- data/ext/msgpack/packer_ext_registry.h +7 -7
- data/ext/msgpack/unpacker_class.c +5 -5
- data/ext/msgpack/unpacker_ext_registry.c +2 -2
- data/ext/msgpack/unpacker_ext_registry.h +1 -1
- data/lib/msgpack/version.rb +1 -1
- data/spec/factory_spec.rb +35 -0
- data/spec/packer_spec.rb +36 -0
- data/spec/unpacker_spec.rb +18 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f722e0fe7d02ec2e454031e7aa2dc06f3e5eeee
|
4
|
+
data.tar.gz: 7bef2c2750435586e5b8cac216f074637961641a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa0d2c135f58d2ab6374b4708d693fee835f19273676c9c988a97a10f3973d393cf2ec7a7382accd7d08075d1fb7a338b48bc3e256b153e718f76c56d9f85d0e
|
7
|
+
data.tar.gz: ad5ef92718a2f2e84457686c6a08c7ed7f865a3ea776f31d12a671ef3712790cb3955764ece20e88ba0b877bb093c6fcc512dc92fe66ba31b1cd45ad57369a86
|
data/ChangeLog
CHANGED
@@ -7,6 +7,7 @@ import java.util.Arrays;
|
|
7
7
|
|
8
8
|
import org.jruby.Ruby;
|
9
9
|
import org.jruby.RubyObject;
|
10
|
+
import org.jruby.RubyModule;
|
10
11
|
import org.jruby.RubyNil;
|
11
12
|
import org.jruby.RubyBoolean;
|
12
13
|
import org.jruby.RubyNumeric;
|
@@ -375,7 +376,15 @@ public class Encoder {
|
|
375
376
|
|
376
377
|
private void appendOther(IRubyObject object, IRubyObject destination) {
|
377
378
|
if (registry != null) {
|
378
|
-
|
379
|
+
RubyModule lookupClass;
|
380
|
+
|
381
|
+
if (object.getType() == runtime.getSymbol()) {
|
382
|
+
lookupClass = object.getType();
|
383
|
+
} else {
|
384
|
+
lookupClass = object.getSingletonClass();
|
385
|
+
}
|
386
|
+
|
387
|
+
IRubyObject[] pair = registry.lookupPackerByModule(lookupClass);
|
379
388
|
if (pair != null) {
|
380
389
|
RubyString bytes = pair[0].callMethod(runtime.getCurrentContext(), "call", object).asString();
|
381
390
|
int type = (int) ((RubyFixnum) pair[1]).getLongValue();
|
@@ -3,7 +3,7 @@ package org.msgpack.jruby;
|
|
3
3
|
import org.jruby.Ruby;
|
4
4
|
import org.jruby.RubyHash;
|
5
5
|
import org.jruby.RubyArray;
|
6
|
-
import org.jruby.
|
6
|
+
import org.jruby.RubyModule;
|
7
7
|
import org.jruby.RubyFixnum;
|
8
8
|
import org.jruby.runtime.ThreadContext;
|
9
9
|
import org.jruby.runtime.builtin.IRubyObject;
|
@@ -12,19 +12,19 @@ import java.util.Map;
|
|
12
12
|
import java.util.HashMap;
|
13
13
|
|
14
14
|
public class ExtensionRegistry {
|
15
|
-
private final Map<
|
16
|
-
private final Map<
|
15
|
+
private final Map<RubyModule, ExtensionEntry> extensionsByModule;
|
16
|
+
private final Map<RubyModule, ExtensionEntry> extensionsByAncestor;
|
17
17
|
private final ExtensionEntry[] extensionsByTypeId;
|
18
18
|
|
19
19
|
public ExtensionRegistry() {
|
20
|
-
this(new HashMap<
|
20
|
+
this(new HashMap<RubyModule, ExtensionEntry>());
|
21
21
|
}
|
22
22
|
|
23
|
-
private ExtensionRegistry(Map<
|
24
|
-
this.
|
25
|
-
this.extensionsByAncestor = new HashMap<
|
23
|
+
private ExtensionRegistry(Map<RubyModule, ExtensionEntry> extensionsByModule) {
|
24
|
+
this.extensionsByModule = new HashMap<RubyModule, ExtensionEntry>(extensionsByModule);
|
25
|
+
this.extensionsByAncestor = new HashMap<RubyModule, ExtensionEntry>();
|
26
26
|
this.extensionsByTypeId = new ExtensionEntry[256];
|
27
|
-
for (ExtensionEntry entry :
|
27
|
+
for (ExtensionEntry entry : extensionsByModule.values()) {
|
28
28
|
if (entry.hasUnpacker()) {
|
29
29
|
extensionsByTypeId[entry.getTypeId() + 128] = entry;
|
30
30
|
}
|
@@ -32,15 +32,15 @@ public class ExtensionRegistry {
|
|
32
32
|
}
|
33
33
|
|
34
34
|
public ExtensionRegistry dup() {
|
35
|
-
return new ExtensionRegistry(
|
35
|
+
return new ExtensionRegistry(extensionsByModule);
|
36
36
|
}
|
37
37
|
|
38
38
|
public IRubyObject toInternalPackerRegistry(ThreadContext ctx) {
|
39
39
|
RubyHash hash = RubyHash.newHash(ctx.getRuntime());
|
40
|
-
for (
|
41
|
-
ExtensionEntry entry =
|
40
|
+
for (RubyModule extensionModule : extensionsByModule.keySet()) {
|
41
|
+
ExtensionEntry entry = extensionsByModule.get(extensionModule);
|
42
42
|
if (entry.hasPacker()) {
|
43
|
-
hash.put(
|
43
|
+
hash.put(extensionModule, entry.toPackerTuple(ctx));
|
44
44
|
}
|
45
45
|
}
|
46
46
|
return hash;
|
@@ -58,9 +58,9 @@ public class ExtensionRegistry {
|
|
58
58
|
return hash;
|
59
59
|
}
|
60
60
|
|
61
|
-
public void put(
|
62
|
-
ExtensionEntry entry = new ExtensionEntry(
|
63
|
-
|
61
|
+
public void put(RubyModule mod, int typeId, IRubyObject packerProc, IRubyObject packerArg, IRubyObject unpackerProc, IRubyObject unpackerArg) {
|
62
|
+
ExtensionEntry entry = new ExtensionEntry(mod, typeId, packerProc, packerArg, unpackerProc, unpackerArg);
|
63
|
+
extensionsByModule.put(mod, entry);
|
64
64
|
extensionsByTypeId[typeId + 128] = entry;
|
65
65
|
extensionsByAncestor.clear();
|
66
66
|
}
|
@@ -74,45 +74,45 @@ public class ExtensionRegistry {
|
|
74
74
|
}
|
75
75
|
}
|
76
76
|
|
77
|
-
public IRubyObject[]
|
78
|
-
ExtensionEntry e =
|
77
|
+
public IRubyObject[] lookupPackerByModule(RubyModule mod) {
|
78
|
+
ExtensionEntry e = extensionsByModule.get(mod);
|
79
79
|
if (e == null) {
|
80
|
-
e = extensionsByAncestor.get(
|
80
|
+
e = extensionsByAncestor.get(mod);
|
81
81
|
}
|
82
82
|
if (e == null) {
|
83
|
-
e =
|
83
|
+
e = findEntryByModuleOrAncestor(mod);
|
84
84
|
if (e != null) {
|
85
|
-
extensionsByAncestor.put(e.
|
85
|
+
extensionsByAncestor.put(e.getExtensionModule(), e);
|
86
86
|
}
|
87
87
|
}
|
88
88
|
if (e != null && e.hasPacker()) {
|
89
|
-
return e.toPackerProcTypeIdPair(
|
89
|
+
return e.toPackerProcTypeIdPair(mod.getRuntime().getCurrentContext());
|
90
90
|
} else {
|
91
91
|
return null;
|
92
92
|
}
|
93
93
|
}
|
94
94
|
|
95
|
-
private ExtensionEntry
|
96
|
-
ThreadContext ctx =
|
97
|
-
for (
|
98
|
-
RubyArray ancestors = (RubyArray)
|
99
|
-
if (ancestors.callMethod(ctx, "include?",
|
100
|
-
return
|
95
|
+
private ExtensionEntry findEntryByModuleOrAncestor(final RubyModule mod) {
|
96
|
+
ThreadContext ctx = mod.getRuntime().getCurrentContext();
|
97
|
+
for (RubyModule extensionModule : extensionsByModule.keySet()) {
|
98
|
+
RubyArray ancestors = (RubyArray) mod.callMethod(ctx, "ancestors");
|
99
|
+
if (ancestors.callMethod(ctx, "include?", extensionModule).isTrue()) {
|
100
|
+
return extensionsByModule.get(extensionModule);
|
101
101
|
}
|
102
102
|
}
|
103
103
|
return null;
|
104
104
|
}
|
105
105
|
|
106
106
|
private static class ExtensionEntry {
|
107
|
-
private final
|
107
|
+
private final RubyModule mod;
|
108
108
|
private final int typeId;
|
109
109
|
private final IRubyObject packerProc;
|
110
110
|
private final IRubyObject packerArg;
|
111
111
|
private final IRubyObject unpackerProc;
|
112
112
|
private final IRubyObject unpackerArg;
|
113
113
|
|
114
|
-
public ExtensionEntry(
|
115
|
-
this.
|
114
|
+
public ExtensionEntry(RubyModule mod, int typeId, IRubyObject packerProc, IRubyObject packerArg, IRubyObject unpackerProc, IRubyObject unpackerArg) {
|
115
|
+
this.mod = mod;
|
116
116
|
this.typeId = typeId;
|
117
117
|
this.packerProc = packerProc;
|
118
118
|
this.packerArg = packerArg;
|
@@ -120,8 +120,8 @@ public class ExtensionRegistry {
|
|
120
120
|
this.unpackerArg = unpackerArg;
|
121
121
|
}
|
122
122
|
|
123
|
-
public
|
124
|
-
return
|
123
|
+
public RubyModule getExtensionModule() {
|
124
|
+
return mod;
|
125
125
|
}
|
126
126
|
|
127
127
|
public int getTypeId() {
|
@@ -149,7 +149,7 @@ public class ExtensionRegistry {
|
|
149
149
|
}
|
150
150
|
|
151
151
|
public RubyArray toUnpackerTuple(ThreadContext ctx) {
|
152
|
-
return RubyArray.newArray(ctx.getRuntime(), new IRubyObject[] {
|
152
|
+
return RubyArray.newArray(ctx.getRuntime(), new IRubyObject[] {mod, unpackerProc, unpackerArg});
|
153
153
|
}
|
154
154
|
|
155
155
|
public IRubyObject[] toPackerProcTypeIdPair(ThreadContext ctx) {
|
@@ -2,6 +2,7 @@ package org.msgpack.jruby;
|
|
2
2
|
|
3
3
|
|
4
4
|
import org.jruby.Ruby;
|
5
|
+
import org.jruby.RubyModule;
|
5
6
|
import org.jruby.RubyClass;
|
6
7
|
import org.jruby.RubyObject;
|
7
8
|
import org.jruby.RubyArray;
|
@@ -70,7 +71,7 @@ public class Factory extends RubyObject {
|
|
70
71
|
public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args) {
|
71
72
|
Ruby runtime = ctx.getRuntime();
|
72
73
|
IRubyObject type = args[0];
|
73
|
-
IRubyObject
|
74
|
+
IRubyObject mod = args[1];
|
74
75
|
|
75
76
|
IRubyObject packerArg;
|
76
77
|
IRubyObject unpackerArg;
|
@@ -94,10 +95,10 @@ public class Factory extends RubyObject {
|
|
94
95
|
throw runtime.newRangeError(String.format("integer %d too big to convert to `signed char'", typeId));
|
95
96
|
}
|
96
97
|
|
97
|
-
if (!(
|
98
|
-
throw runtime.newArgumentError(String.format("expected Class but found %s.",
|
98
|
+
if (!(mod instanceof RubyModule)) {
|
99
|
+
throw runtime.newArgumentError(String.format("expected Module/Class but found %s.", mod.getType().getName()));
|
99
100
|
}
|
100
|
-
|
101
|
+
RubyModule extModule = (RubyModule) mod;
|
101
102
|
|
102
103
|
IRubyObject packerProc = runtime.getNil();
|
103
104
|
IRubyObject unpackerProc = runtime.getNil();
|
@@ -106,15 +107,15 @@ public class Factory extends RubyObject {
|
|
106
107
|
}
|
107
108
|
if (unpackerArg != null) {
|
108
109
|
if (unpackerArg instanceof RubyString || unpackerArg instanceof RubySymbol) {
|
109
|
-
unpackerProc =
|
110
|
+
unpackerProc = extModule.method(unpackerArg.callMethod(ctx, "to_sym"));
|
110
111
|
} else {
|
111
112
|
unpackerProc = unpackerArg.callMethod(ctx, "method", runtime.newSymbol("call"));
|
112
113
|
}
|
113
114
|
}
|
114
115
|
|
115
|
-
extensionRegistry.put(
|
116
|
+
extensionRegistry.put(extModule, (int) typeId, packerProc, packerArg, unpackerProc, unpackerArg);
|
116
117
|
|
117
|
-
if (
|
118
|
+
if (extModule == runtime.getSymbol()) {
|
118
119
|
hasSymbolExtType = true;
|
119
120
|
}
|
120
121
|
|
@@ -2,6 +2,7 @@ package org.msgpack.jruby;
|
|
2
2
|
|
3
3
|
|
4
4
|
import org.jruby.Ruby;
|
5
|
+
import org.jruby.RubyModule;
|
5
6
|
import org.jruby.RubyClass;
|
6
7
|
import org.jruby.RubyObject;
|
7
8
|
import org.jruby.RubyArray;
|
@@ -78,7 +79,7 @@ public class Packer extends RubyObject {
|
|
78
79
|
public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Block block) {
|
79
80
|
Ruby runtime = ctx.getRuntime();
|
80
81
|
IRubyObject type = args[0];
|
81
|
-
IRubyObject
|
82
|
+
IRubyObject mod = args[1];
|
82
83
|
|
83
84
|
IRubyObject arg;
|
84
85
|
IRubyObject proc;
|
@@ -100,14 +101,14 @@ public class Packer extends RubyObject {
|
|
100
101
|
throw runtime.newRangeError(String.format("integer %d too big to convert to `signed char'", typeId));
|
101
102
|
}
|
102
103
|
|
103
|
-
if (!(
|
104
|
-
throw runtime.newArgumentError(String.format("expected Class but found %s.",
|
104
|
+
if (!(mod instanceof RubyModule)) {
|
105
|
+
throw runtime.newArgumentError(String.format("expected Module/Class but found %s.", mod.getType().getName()));
|
105
106
|
}
|
106
|
-
|
107
|
+
RubyModule extModule = (RubyModule) mod;
|
107
108
|
|
108
|
-
registry.put(
|
109
|
+
registry.put(extModule, (int) typeId, proc, arg, null, null);
|
109
110
|
|
110
|
-
if (
|
111
|
+
if (extModule == runtime.getSymbol()) {
|
111
112
|
encoder.hasSymbolExtType = true;
|
112
113
|
}
|
113
114
|
|
@@ -3,6 +3,7 @@ package org.msgpack.jruby;
|
|
3
3
|
import java.util.Arrays;
|
4
4
|
|
5
5
|
import org.jruby.Ruby;
|
6
|
+
import org.jruby.RubyModule;
|
6
7
|
import org.jruby.RubyClass;
|
7
8
|
import org.jruby.RubyString;
|
8
9
|
import org.jruby.RubyObject;
|
@@ -100,7 +101,7 @@ public class Unpacker extends RubyObject {
|
|
100
101
|
Ruby runtime = ctx.getRuntime();
|
101
102
|
IRubyObject type = args[0];
|
102
103
|
|
103
|
-
|
104
|
+
RubyModule extModule;
|
104
105
|
IRubyObject arg;
|
105
106
|
IRubyObject proc;
|
106
107
|
if (args.length == 1) {
|
@@ -111,11 +112,11 @@ public class Unpacker extends RubyObject {
|
|
111
112
|
if (proc == null)
|
112
113
|
System.err.println("proc from Block is null");
|
113
114
|
arg = proc;
|
114
|
-
|
115
|
+
extModule = null;
|
115
116
|
} else if (args.length == 3) {
|
116
|
-
|
117
|
+
extModule = (RubyModule) args[1];
|
117
118
|
arg = args[2];
|
118
|
-
proc =
|
119
|
+
proc = extModule.method(arg);
|
119
120
|
} else {
|
120
121
|
throw runtime.newArgumentError(String.format("wrong number of arguments (%d for 1 or 3)", 2 + args.length));
|
121
122
|
}
|
@@ -125,7 +126,7 @@ public class Unpacker extends RubyObject {
|
|
125
126
|
throw runtime.newRangeError(String.format("integer %d too big to convert to `signed char'", typeId));
|
126
127
|
}
|
127
128
|
|
128
|
-
registry.put(
|
129
|
+
registry.put(extModule, (int) typeId, null, null, proc, arg);
|
129
130
|
return runtime.getNil();
|
130
131
|
}
|
131
132
|
|
data/ext/msgpack/factory_class.c
CHANGED
@@ -141,7 +141,7 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
141
141
|
FACTORY(self, fc);
|
142
142
|
|
143
143
|
int ext_type;
|
144
|
-
VALUE
|
144
|
+
VALUE ext_module;
|
145
145
|
VALUE options;
|
146
146
|
VALUE packer_arg, unpacker_arg;
|
147
147
|
VALUE packer_proc, unpacker_proc;
|
@@ -170,9 +170,9 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
170
170
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
171
171
|
}
|
172
172
|
|
173
|
-
|
174
|
-
if(rb_type(
|
175
|
-
rb_raise(rb_eArgError, "expected Class but found %s.", rb_obj_classname(
|
173
|
+
ext_module = argv[1];
|
174
|
+
if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
|
175
|
+
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
176
176
|
}
|
177
177
|
|
178
178
|
packer_proc = Qnil;
|
@@ -184,19 +184,19 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
184
184
|
|
185
185
|
if(unpacker_arg != Qnil) {
|
186
186
|
if(rb_type(unpacker_arg) == T_SYMBOL || rb_type(unpacker_arg) == T_STRING) {
|
187
|
-
unpacker_proc = rb_obj_method(
|
187
|
+
unpacker_proc = rb_obj_method(ext_module, unpacker_arg);
|
188
188
|
} else {
|
189
189
|
unpacker_proc = rb_funcall(unpacker_arg, rb_intern("method"), 1, ID2SYM(rb_intern("call")));
|
190
190
|
}
|
191
191
|
}
|
192
192
|
|
193
|
-
msgpack_packer_ext_registry_put(&fc->pkrg,
|
193
|
+
msgpack_packer_ext_registry_put(&fc->pkrg, ext_module, ext_type, packer_proc, packer_arg);
|
194
194
|
|
195
|
-
if (
|
195
|
+
if (ext_module == rb_cSymbol) {
|
196
196
|
fc->has_symbol_ext_type = true;
|
197
197
|
}
|
198
198
|
|
199
|
-
msgpack_unpacker_ext_registry_put(&fc->ukrg,
|
199
|
+
msgpack_unpacker_ext_registry_put(&fc->ukrg, ext_module, ext_type, unpacker_proc, unpacker_arg);
|
200
200
|
|
201
201
|
return Qnil;
|
202
202
|
}
|
data/ext/msgpack/packer.c
CHANGED
@@ -124,8 +124,27 @@ void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v)
|
|
124
124
|
void msgpack_packer_write_other_value(msgpack_packer_t* pk, VALUE v)
|
125
125
|
{
|
126
126
|
int ext_type;
|
127
|
-
|
128
|
-
|
127
|
+
|
128
|
+
VALUE lookup_class;
|
129
|
+
|
130
|
+
/*
|
131
|
+
* Objects of type Integer (Fixnum, Bignum), Float, Symbol and frozen
|
132
|
+
* String have no singleton class and raise a TypeError when trying to get
|
133
|
+
* it. See implementation of #singleton_class in ruby's source code:
|
134
|
+
* VALUE rb_singleton_class(VALUE obj);
|
135
|
+
*
|
136
|
+
* Since all but symbols are already filtered out when reaching this code
|
137
|
+
* only symbols are checked here.
|
138
|
+
*/
|
139
|
+
if (SYMBOL_P(v)) {
|
140
|
+
lookup_class = rb_obj_class(v);
|
141
|
+
} else {
|
142
|
+
lookup_class = rb_singleton_class(v);
|
143
|
+
}
|
144
|
+
|
145
|
+
VALUE proc = msgpack_packer_ext_registry_lookup(&pk->ext_registry, lookup_class,
|
146
|
+
&ext_type);
|
147
|
+
|
129
148
|
if(proc != Qnil) {
|
130
149
|
VALUE payload = rb_funcall(proc, s_call, 1, v);
|
131
150
|
StringValue(payload);
|
data/ext/msgpack/packer_class.c
CHANGED
@@ -249,7 +249,7 @@ static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
|
|
249
249
|
PACKER(self, pk);
|
250
250
|
|
251
251
|
int ext_type;
|
252
|
-
VALUE
|
252
|
+
VALUE ext_module;
|
253
253
|
VALUE proc;
|
254
254
|
VALUE arg;
|
255
255
|
|
@@ -279,14 +279,14 @@ static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
|
|
279
279
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
280
280
|
}
|
281
281
|
|
282
|
-
|
283
|
-
if(rb_type(
|
284
|
-
rb_raise(rb_eArgError, "expected Class but found %s.", rb_obj_classname(
|
282
|
+
ext_module = argv[1];
|
283
|
+
if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
|
284
|
+
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
285
285
|
}
|
286
286
|
|
287
|
-
msgpack_packer_ext_registry_put(&pk->ext_registry,
|
287
|
+
msgpack_packer_ext_registry_put(&pk->ext_registry, ext_module, ext_type, proc, arg);
|
288
288
|
|
289
|
-
if (
|
289
|
+
if (ext_module == rb_cSymbol) {
|
290
290
|
pk->has_symbol_ext_type = true;
|
291
291
|
}
|
292
292
|
|
@@ -64,7 +64,7 @@ __rb_hash_clear_clear_i(key, value, dummy)
|
|
64
64
|
#endif
|
65
65
|
|
66
66
|
VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
|
67
|
-
VALUE
|
67
|
+
VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
|
68
68
|
{
|
69
69
|
VALUE e = rb_ary_new3(3, INT2FIX(ext_type), proc, arg);
|
70
70
|
/* clear lookup cache not to miss added type */
|
@@ -75,5 +75,5 @@ VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
|
|
75
75
|
rb_hash_foreach(pkrg->cache, __rb_hash_clear_clear_i, 0);
|
76
76
|
}
|
77
77
|
#endif
|
78
|
-
return rb_hash_aset(pkrg->hash,
|
78
|
+
return rb_hash_aset(pkrg->hash, ext_module, e);
|
79
79
|
}
|
@@ -44,7 +44,7 @@ void msgpack_packer_ext_registry_dup(msgpack_packer_ext_registry_t* src,
|
|
44
44
|
msgpack_packer_ext_registry_t* dst);
|
45
45
|
|
46
46
|
VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
|
47
|
-
VALUE
|
47
|
+
VALUE ext_module, int ext_type, VALUE proc, VALUE arg);
|
48
48
|
|
49
49
|
static int msgpack_packer_ext_find_superclass(VALUE key, VALUE value, VALUE arg)
|
50
50
|
{
|
@@ -61,32 +61,32 @@ static int msgpack_packer_ext_find_superclass(VALUE key, VALUE value, VALUE arg)
|
|
61
61
|
|
62
62
|
|
63
63
|
static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_registry_t* pkrg,
|
64
|
-
VALUE
|
64
|
+
VALUE lookup_class, int* ext_type_result)
|
65
65
|
{
|
66
|
-
VALUE type = rb_hash_lookup(pkrg->hash,
|
66
|
+
VALUE type = rb_hash_lookup(pkrg->hash, lookup_class);
|
67
67
|
if(type != Qnil) {
|
68
68
|
*ext_type_result = FIX2INT(rb_ary_entry(type, 0));
|
69
69
|
return rb_ary_entry(type, 1);
|
70
70
|
}
|
71
71
|
|
72
|
-
VALUE type_inht = rb_hash_lookup(pkrg->cache,
|
72
|
+
VALUE type_inht = rb_hash_lookup(pkrg->cache, lookup_class);
|
73
73
|
if(type_inht != Qnil) {
|
74
74
|
*ext_type_result = FIX2INT(rb_ary_entry(type_inht, 0));
|
75
75
|
return rb_ary_entry(type_inht, 1);
|
76
76
|
}
|
77
77
|
|
78
78
|
/*
|
79
|
-
* check all keys whether it is
|
79
|
+
* check all keys whether it is an ancestor of lookup_class, or not
|
80
80
|
*/
|
81
81
|
VALUE args[2];
|
82
|
-
args[0] =
|
82
|
+
args[0] = lookup_class;
|
83
83
|
args[1] = Qnil;
|
84
84
|
rb_hash_foreach(pkrg->hash, msgpack_packer_ext_find_superclass, (VALUE) args);
|
85
85
|
|
86
86
|
VALUE superclass = args[1];
|
87
87
|
if(superclass != Qnil) {
|
88
88
|
VALUE superclass_type = rb_hash_lookup(pkrg->hash, superclass);
|
89
|
-
rb_hash_aset(pkrg->cache,
|
89
|
+
rb_hash_aset(pkrg->cache, lookup_class, superclass_type);
|
90
90
|
*ext_type_result = FIX2INT(rb_ary_entry(superclass_type, 0));
|
91
91
|
return rb_ary_entry(superclass_type, 1);
|
92
92
|
}
|
@@ -348,7 +348,7 @@ static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
|
348
348
|
int ext_type;
|
349
349
|
VALUE proc;
|
350
350
|
VALUE arg;
|
351
|
-
VALUE
|
351
|
+
VALUE ext_module;
|
352
352
|
|
353
353
|
switch (argc) {
|
354
354
|
case 1:
|
@@ -361,13 +361,13 @@ static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
|
361
361
|
proc = rb_block_proc();
|
362
362
|
#endif
|
363
363
|
arg = proc;
|
364
|
-
|
364
|
+
ext_module = Qnil;
|
365
365
|
break;
|
366
366
|
case 3:
|
367
367
|
/* register_type(0x7f, Time, :from_msgpack_ext) */
|
368
|
-
|
368
|
+
ext_module = argv[1];
|
369
369
|
arg = argv[2];
|
370
|
-
proc = rb_obj_method(
|
370
|
+
proc = rb_obj_method(ext_module, arg);
|
371
371
|
break;
|
372
372
|
default:
|
373
373
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 3)", argc);
|
@@ -378,7 +378,7 @@ static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
|
378
378
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
379
379
|
}
|
380
380
|
|
381
|
-
msgpack_unpacker_ext_registry_put(&uk->ext_registry,
|
381
|
+
msgpack_unpacker_ext_registry_put(&uk->ext_registry, ext_module, ext_type, proc, arg);
|
382
382
|
|
383
383
|
return Qnil;
|
384
384
|
}
|
@@ -53,9 +53,9 @@ void msgpack_unpacker_ext_registry_dup(msgpack_unpacker_ext_registry_t* src,
|
|
53
53
|
}
|
54
54
|
|
55
55
|
VALUE msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t* ukrg,
|
56
|
-
VALUE
|
56
|
+
VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
|
57
57
|
{
|
58
|
-
VALUE e = rb_ary_new3(3,
|
58
|
+
VALUE e = rb_ary_new3(3, ext_module, proc, arg);
|
59
59
|
VALUE before = ukrg->array[ext_type + 128];
|
60
60
|
ukrg->array[ext_type + 128] = e;
|
61
61
|
return before;
|
@@ -44,7 +44,7 @@ void msgpack_unpacker_ext_registry_dup(msgpack_unpacker_ext_registry_t* src,
|
|
44
44
|
msgpack_unpacker_ext_registry_t* dst);
|
45
45
|
|
46
46
|
VALUE msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t* ukrg,
|
47
|
-
VALUE
|
47
|
+
VALUE ext_module, int ext_type, VALUE proc, VALUE arg);
|
48
48
|
|
49
49
|
static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_registry_t* ukrg,
|
50
50
|
int ext_type)
|
data/lib/msgpack/version.rb
CHANGED
data/spec/factory_spec.rb
CHANGED
@@ -208,6 +208,41 @@ describe MessagePack::Factory do
|
|
208
208
|
my.a.should == 1
|
209
209
|
my.b.should == 2
|
210
210
|
end
|
211
|
+
|
212
|
+
describe "registering an ext type for a module" do
|
213
|
+
before do
|
214
|
+
mod = Module.new do
|
215
|
+
def self.from_msgpack_ext(data)
|
216
|
+
"unpacked #{data}"
|
217
|
+
end
|
218
|
+
|
219
|
+
def to_msgpack_ext
|
220
|
+
'value_msgpacked'
|
221
|
+
end
|
222
|
+
end
|
223
|
+
stub_const('Mod', mod)
|
224
|
+
end
|
225
|
+
let(:factory) { described_class.new }
|
226
|
+
before { factory.register_type(0x01, Mod) }
|
227
|
+
|
228
|
+
describe "packing an object whose class included the module" do
|
229
|
+
subject { factory.packer.pack(value).to_s }
|
230
|
+
before { stub_const('Value', Class.new{ include Mod }) }
|
231
|
+
let(:value) { Value.new }
|
232
|
+
it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
|
233
|
+
end
|
234
|
+
|
235
|
+
describe "packing an object which has been extended by the module" do
|
236
|
+
subject { factory.packer.pack(object).to_s }
|
237
|
+
let(:object) { Object.new.extend Mod }
|
238
|
+
it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
|
239
|
+
end
|
240
|
+
|
241
|
+
describe "unpacking with the module" do
|
242
|
+
subject { factory.unpacker.feed("\xC7\x06\x01module").unpack }
|
243
|
+
it { is_expected.to eq "unpacked module" }
|
244
|
+
end
|
245
|
+
end
|
211
246
|
end
|
212
247
|
|
213
248
|
describe 'the special treatment of symbols with ext type' do
|
data/spec/packer_spec.rb
CHANGED
@@ -350,6 +350,42 @@ describe MessagePack::Packer do
|
|
350
350
|
end
|
351
351
|
end
|
352
352
|
|
353
|
+
context 'when it has no ext type but an included module has' do
|
354
|
+
subject { packer.pack(Value.new).to_s }
|
355
|
+
|
356
|
+
before do
|
357
|
+
mod = Module.new do
|
358
|
+
def to_msgpack_ext
|
359
|
+
'value_msgpacked'
|
360
|
+
end
|
361
|
+
end
|
362
|
+
stub_const('Mod', mod)
|
363
|
+
end
|
364
|
+
before { packer.register_type(0x01, Mod, :to_msgpack_ext) }
|
365
|
+
|
366
|
+
before { stub_const('Value', Class.new{ include Mod }) }
|
367
|
+
|
368
|
+
it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
|
369
|
+
end
|
370
|
+
|
371
|
+
context 'when it has no ext type but it was extended by a module which has one' do
|
372
|
+
subject { packer.pack(object).to_s }
|
373
|
+
let(:object) { Object.new.extend Mod }
|
374
|
+
|
375
|
+
before do
|
376
|
+
mod = Module.new do
|
377
|
+
def to_msgpack_ext
|
378
|
+
'value_msgpacked'
|
379
|
+
end
|
380
|
+
end
|
381
|
+
stub_const('Mod', mod)
|
382
|
+
end
|
383
|
+
before { packer.register_type(0x01, Mod, :to_msgpack_ext) }
|
384
|
+
|
385
|
+
|
386
|
+
it { is_expected.to eq "\xC7\x0F\x01value_msgpacked" }
|
387
|
+
end
|
388
|
+
|
353
389
|
context 'when registering a type for symbols' do
|
354
390
|
before { packer.register_type(0x00, ::Symbol, :to_msgpack_ext) }
|
355
391
|
|
data/spec/unpacker_spec.rb
CHANGED
@@ -477,6 +477,24 @@ describe MessagePack::Unpacker do
|
|
477
477
|
expect(two[:class]).to be_nil
|
478
478
|
expect(two[:unpacker]).to be_instance_of(Proc)
|
479
479
|
end
|
480
|
+
|
481
|
+
describe "registering an ext type for a module" do
|
482
|
+
subject { unpacker.feed("\xc7\x06\x00module").unpack }
|
483
|
+
|
484
|
+
let(:unpacker) { MessagePack::Unpacker.new }
|
485
|
+
|
486
|
+
before do
|
487
|
+
mod = Module.new do
|
488
|
+
def self.from_msgpack_ext(data)
|
489
|
+
"unpacked #{data}"
|
490
|
+
end
|
491
|
+
end
|
492
|
+
stub_const('Mod', mod)
|
493
|
+
end
|
494
|
+
|
495
|
+
before { unpacker.register_type(0x00, Mod, :from_msgpack_ext) }
|
496
|
+
it { is_expected.to eq "unpacked module" }
|
497
|
+
end
|
480
498
|
end
|
481
499
|
|
482
500
|
def flatten(struct, results = [])
|
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.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: x64-mingw32
|
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: 2017-
|
13
|
+
date: 2017-02-28 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|