msgpack 0.7.4 → 1.3.3
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 +5 -5
- data/.gitignore +3 -1
- data/.rubocop.yml +3 -0
- data/.travis.yml +27 -14
- data/ChangeLog +89 -1
- data/Gemfile +6 -1
- data/README.rdoc +55 -1
- data/Rakefile +5 -1
- data/bench/pack_symbols.rb +28 -0
- data/bench/run_symbols.sh +26 -0
- data/doclib/msgpack.rb +2 -2
- data/doclib/msgpack/core_ext.rb +20 -20
- data/doclib/msgpack/factory.rb +33 -0
- data/doclib/msgpack/packer.rb +20 -0
- data/doclib/msgpack/time.rb +22 -0
- data/doclib/msgpack/timestamp.rb +44 -0
- data/ext/java/org/msgpack/jruby/Buffer.java +4 -0
- data/ext/java/org/msgpack/jruby/Encoder.java +48 -18
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +67 -38
- data/ext/java/org/msgpack/jruby/Factory.java +20 -8
- data/ext/java/org/msgpack/jruby/MessagePackLibrary.java +0 -92
- data/ext/java/org/msgpack/jruby/Packer.java +114 -11
- data/ext/java/org/msgpack/jruby/Unpacker.java +15 -8
- data/ext/msgpack/buffer.h +14 -0
- data/ext/msgpack/buffer_class.c +1 -1
- data/ext/msgpack/compat.h +10 -0
- data/ext/msgpack/factory_class.c +24 -17
- data/ext/msgpack/factory_class.h +0 -2
- data/ext/msgpack/packer.c +5 -4
- data/ext/msgpack/packer.h +13 -1
- data/ext/msgpack/packer_class.c +130 -43
- data/ext/msgpack/packer_class.h +0 -2
- data/ext/msgpack/packer_ext_registry.c +2 -2
- data/ext/msgpack/packer_ext_registry.h +64 -25
- data/ext/msgpack/rbinit.c +0 -2
- data/ext/msgpack/unpacker.c +3 -3
- data/ext/msgpack/unpacker_class.c +25 -56
- data/ext/msgpack/unpacker_class.h +0 -2
- data/ext/msgpack/unpacker_ext_registry.c +2 -2
- data/ext/msgpack/unpacker_ext_registry.h +3 -3
- data/lib/msgpack.rb +36 -0
- data/lib/msgpack/core_ext.rb +139 -0
- data/lib/msgpack/factory.rb +21 -0
- data/lib/msgpack/symbol.rb +9 -0
- data/lib/msgpack/time.rb +29 -0
- data/lib/msgpack/timestamp.rb +76 -0
- data/lib/msgpack/version.rb +8 -1
- data/msgpack.gemspec +6 -7
- data/spec/cruby/buffer_spec.rb +6 -1
- data/spec/factory_spec.rb +134 -0
- data/spec/msgpack_spec.rb +52 -0
- data/spec/packer_spec.rb +200 -0
- data/spec/timestamp_spec.rb +121 -0
- data/spec/unpacker_spec.rb +29 -0
- metadata +29 -23
- data/ext/msgpack/core_ext.c +0 -144
- data/ext/msgpack/core_ext.h +0 -26
data/doclib/msgpack/factory.rb
CHANGED
@@ -19,6 +19,22 @@ module MessagePack
|
|
19
19
|
def packer(*args)
|
20
20
|
end
|
21
21
|
|
22
|
+
#
|
23
|
+
# Serialize the passed value
|
24
|
+
#
|
25
|
+
# If it could not serialize the object, it raises
|
26
|
+
# NoMethodError: undefined method `to_msgpack' for #<the_object>.
|
27
|
+
#
|
28
|
+
# @param obj [Object] object to serialize
|
29
|
+
# @param options [Hash]
|
30
|
+
# @return [String] serialized object
|
31
|
+
#
|
32
|
+
# See Packer#initialize for supported options.
|
33
|
+
#
|
34
|
+
def dump(obj, options={})
|
35
|
+
end
|
36
|
+
alias pack dump
|
37
|
+
|
22
38
|
#
|
23
39
|
# Creates a MessagePack::Unpacker instance, which has ext types already registered.
|
24
40
|
# Options are passed to MessagePack::Unpacker#initialized.
|
@@ -28,6 +44,23 @@ module MessagePack
|
|
28
44
|
def unpacker(*args)
|
29
45
|
end
|
30
46
|
|
47
|
+
#
|
48
|
+
# Deserializes an object from the string or io and returns it.
|
49
|
+
#
|
50
|
+
# If there're not enough data to deserialize one object, this method raises EOFError.
|
51
|
+
# If data format is invalid, this method raises MessagePack::MalformedFormatError.
|
52
|
+
# If the object nests too deeply, this method raises MessagePack::StackError.
|
53
|
+
#
|
54
|
+
# @param data [String]
|
55
|
+
# @param options [Hash]
|
56
|
+
# @return [Object] deserialized object
|
57
|
+
#
|
58
|
+
# See Unpacker#initialize for supported options.
|
59
|
+
#
|
60
|
+
def load(data, options={})
|
61
|
+
end
|
62
|
+
alias unpack load
|
63
|
+
|
31
64
|
#
|
32
65
|
# Register a type and Class to be registered for packer and/or unpacker.
|
33
66
|
# If options are not speicified, factory will use :to_msgpack_ext for packer, and
|
data/doclib/msgpack/packer.rb
CHANGED
@@ -91,6 +91,12 @@ module MessagePack
|
|
91
91
|
def write_nil
|
92
92
|
end
|
93
93
|
|
94
|
+
#
|
95
|
+
# Serializes a string object as binary data. Same as write("string".encode(Encoding::BINARY)).
|
96
|
+
#
|
97
|
+
def write_bin(obj)
|
98
|
+
end
|
99
|
+
|
94
100
|
#
|
95
101
|
# Write a header of an array whose size is _n_.
|
96
102
|
# For example, write_array_header(1).write(true) is same as write([ true ]).
|
@@ -109,6 +115,20 @@ module MessagePack
|
|
109
115
|
def write_map_header(n)
|
110
116
|
end
|
111
117
|
|
118
|
+
#
|
119
|
+
# Write a header of a binary string whose size is _n_. Useful if you want to append large binary data without loading it into memory at once.
|
120
|
+
# For example,
|
121
|
+
# MessagePack::Packer.new(io).write_bin_header(12).flush
|
122
|
+
# io.write('chunk1')
|
123
|
+
# io.write('chunk2')
|
124
|
+
# is the same as
|
125
|
+
# write('chunk1chunk2'.encode(Encoding::BINARY)).
|
126
|
+
#
|
127
|
+
# @return [Packer] self
|
128
|
+
#
|
129
|
+
def write_bin_header(n)
|
130
|
+
end
|
131
|
+
|
112
132
|
#
|
113
133
|
# Serializes _value_ as 32-bit single precision float into internal buffer.
|
114
134
|
# _value_ will be approximated with the nearest possible single precision float, thus
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module MessagePack
|
2
|
+
|
3
|
+
# MessagePack::Time provides packer and unpacker functions for a timestamp type.
|
4
|
+
# @example Setup for DefaultFactory
|
5
|
+
# MessagePack::DefaultFactory.register_type(
|
6
|
+
# MessagePack::Timestamp::TYPE,
|
7
|
+
# Time,
|
8
|
+
# packer: MessagePack::Time::Packer,
|
9
|
+
# unpacker: MessagePack::Time::Unpacker
|
10
|
+
# )
|
11
|
+
class Time
|
12
|
+
# A packer function that packs a Time instance to a MessagePack timestamp.
|
13
|
+
Packer = lambda { |payload|
|
14
|
+
# ...
|
15
|
+
}
|
16
|
+
|
17
|
+
# An unpacker function that unpacks a MessagePack timestamp to a Time instance.
|
18
|
+
Unpacker = lambda { |time|
|
19
|
+
# ...
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module MessagePack
|
2
|
+
# A utility class for MessagePack timestamp type
|
3
|
+
class Timestamp
|
4
|
+
#
|
5
|
+
# The timestamp extension type defined in the MessagePack spec.
|
6
|
+
#
|
7
|
+
# See https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type for details.
|
8
|
+
#
|
9
|
+
TYPE = -1
|
10
|
+
|
11
|
+
# @return [Integer] Second part of the timestamp.
|
12
|
+
attr_reader :sec
|
13
|
+
|
14
|
+
# @return [Integer] Nanosecond part of the timestamp.
|
15
|
+
attr_reader :nsec
|
16
|
+
|
17
|
+
# @param [Integer] sec
|
18
|
+
# @param [Integer] nsec
|
19
|
+
def initialize(sec, nsec)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @example An unpacker implementation for the Time class
|
23
|
+
# lambda do |payload|
|
24
|
+
# tv = MessagePack::Timestamp.from_msgpack_ext(payload)
|
25
|
+
# Time.at(tv.sec, tv.nsec, :nanosecond)
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# @param [String] data
|
29
|
+
# @return [MessagePack::Timestamp]
|
30
|
+
def self.from_msgpack_ext(data)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @example A packer implementation for the Time class
|
34
|
+
# unpacker = lambda do |time|
|
35
|
+
# MessagePack::Timestamp.to_msgpack_ext(time.tv_sec, time.tv_nsec)
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# @param [Integer] sec
|
39
|
+
# @param [Integer] nsec
|
40
|
+
# @return [String]
|
41
|
+
def self.to_msgpack_ext(sec, nsec)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -179,6 +179,10 @@ public class Buffer extends RubyObject {
|
|
179
179
|
return skipCommon(ctx, length, true);
|
180
180
|
}
|
181
181
|
|
182
|
+
public boolean hasIo() {
|
183
|
+
return io != null;
|
184
|
+
}
|
185
|
+
|
182
186
|
@JRubyMethod(name = "to_s", alias = {"to_str"})
|
183
187
|
public IRubyObject toS(ThreadContext ctx) {
|
184
188
|
ensureReadMode();
|
@@ -3,9 +3,11 @@ package org.msgpack.jruby;
|
|
3
3
|
|
4
4
|
import java.math.BigInteger;
|
5
5
|
import java.nio.ByteBuffer;
|
6
|
+
import java.util.Arrays;
|
6
7
|
|
7
8
|
import org.jruby.Ruby;
|
8
9
|
import org.jruby.RubyObject;
|
10
|
+
import org.jruby.RubyModule;
|
9
11
|
import org.jruby.RubyNil;
|
10
12
|
import org.jruby.RubyBoolean;
|
11
13
|
import org.jruby.RubyNumeric;
|
@@ -37,15 +39,18 @@ public class Encoder {
|
|
37
39
|
private final boolean compatibilityMode;
|
38
40
|
private final ExtensionRegistry registry;
|
39
41
|
|
42
|
+
public boolean hasSymbolExtType;
|
43
|
+
|
40
44
|
private ByteBuffer buffer;
|
41
45
|
|
42
|
-
public Encoder(Ruby runtime, boolean compatibilityMode, ExtensionRegistry registry) {
|
46
|
+
public Encoder(Ruby runtime, boolean compatibilityMode, ExtensionRegistry registry, boolean hasSymbolExtType) {
|
43
47
|
this.runtime = runtime;
|
44
48
|
this.buffer = ByteBuffer.allocate(CACHE_LINE_SIZE - ARRAY_HEADER_SIZE);
|
45
49
|
this.binaryEncoding = runtime.getEncodingService().getAscii8bitEncoding();
|
46
50
|
this.utf8Encoding = UTF8Encoding.INSTANCE;
|
47
51
|
this.compatibilityMode = compatibilityMode;
|
48
52
|
this.registry = registry;
|
53
|
+
this.hasSymbolExtType = hasSymbolExtType;
|
49
54
|
}
|
50
55
|
|
51
56
|
public boolean isCompatibilityMode() {
|
@@ -86,6 +91,11 @@ public class Encoder {
|
|
86
91
|
return readRubyString();
|
87
92
|
}
|
88
93
|
|
94
|
+
public IRubyObject encodeBinHeader(int size) {
|
95
|
+
appendStringHeader(size, true);
|
96
|
+
return readRubyString();
|
97
|
+
}
|
98
|
+
|
89
99
|
public IRubyObject encodeFloat32(RubyNumeric numeric) {
|
90
100
|
appendFloat32(numeric);
|
91
101
|
return readRubyString();
|
@@ -111,7 +121,11 @@ public class Encoder {
|
|
111
121
|
} else if (object instanceof RubyString) {
|
112
122
|
appendString((RubyString) object);
|
113
123
|
} else if (object instanceof RubySymbol) {
|
114
|
-
|
124
|
+
if (hasSymbolExtType) {
|
125
|
+
appendOther(object, destination);
|
126
|
+
} else {
|
127
|
+
appendString(((RubySymbol) object).asString());
|
128
|
+
}
|
115
129
|
} else if (object instanceof RubyArray) {
|
116
130
|
appendArray((RubyArray) object);
|
117
131
|
} else if (object instanceof RubyHash) {
|
@@ -124,14 +138,18 @@ public class Encoder {
|
|
124
138
|
}
|
125
139
|
|
126
140
|
private void appendBignum(RubyBignum object) {
|
127
|
-
BigInteger value =
|
128
|
-
if (value.
|
129
|
-
|
141
|
+
BigInteger value = object.getBigIntegerValue();
|
142
|
+
if (value.compareTo(RubyBignum.LONG_MIN) < 0 || value.compareTo(RubyBignum.LONG_MAX) > 0) {
|
143
|
+
if (value.bitLength() > 64 || (value.bitLength() > 63 && value.signum() < 0)) {
|
144
|
+
throw runtime.newArgumentError(String.format("Cannot pack big integer: %s", value));
|
145
|
+
}
|
146
|
+
ensureRemainingCapacity(9);
|
147
|
+
buffer.put(value.signum() < 0 ? INT64 : UINT64);
|
148
|
+
byte[] b = value.toByteArray();
|
149
|
+
buffer.put(b, b.length - 8, 8);
|
150
|
+
} else {
|
151
|
+
appendInteger(object);
|
130
152
|
}
|
131
|
-
ensureRemainingCapacity(9);
|
132
|
-
buffer.put(value.signum() < 0 ? INT64 : UINT64);
|
133
|
-
byte[] b = value.toByteArray();
|
134
|
-
buffer.put(b, b.length - 8, 8);
|
135
153
|
}
|
136
154
|
|
137
155
|
private void appendInteger(RubyInteger object) {
|
@@ -208,14 +226,7 @@ public class Encoder {
|
|
208
226
|
buffer.putFloat(value);
|
209
227
|
}
|
210
228
|
|
211
|
-
private void
|
212
|
-
Encoding encoding = object.getEncoding();
|
213
|
-
boolean binary = !compatibilityMode && encoding == binaryEncoding;
|
214
|
-
if (encoding != utf8Encoding && encoding != binaryEncoding) {
|
215
|
-
object = (RubyString) ((RubyString) object).encode(runtime.getCurrentContext(), runtime.getEncodingService().getEncoding(utf8Encoding));
|
216
|
-
}
|
217
|
-
ByteList bytes = object.getByteList();
|
218
|
-
int length = bytes.length();
|
229
|
+
private void appendStringHeader(int length, boolean binary) {
|
219
230
|
if (length < 32 && !binary) {
|
220
231
|
ensureRemainingCapacity(1 + length);
|
221
232
|
buffer.put((byte) (length | FIXSTR));
|
@@ -232,6 +243,17 @@ public class Encoder {
|
|
232
243
|
buffer.put(binary ? BIN32 : STR32);
|
233
244
|
buffer.putInt((int) length);
|
234
245
|
}
|
246
|
+
}
|
247
|
+
|
248
|
+
private void appendString(RubyString object) {
|
249
|
+
Encoding encoding = object.getEncoding();
|
250
|
+
boolean binary = !compatibilityMode && encoding == binaryEncoding;
|
251
|
+
if (encoding != utf8Encoding && encoding != binaryEncoding) {
|
252
|
+
object = (RubyString) ((RubyString) object).encode(runtime.getCurrentContext(), runtime.getEncodingService().getEncoding(utf8Encoding));
|
253
|
+
}
|
254
|
+
ByteList bytes = object.getByteList();
|
255
|
+
int length = bytes.length();
|
256
|
+
appendStringHeader(length, binary);
|
235
257
|
buffer.put(bytes.unsafeBytes(), bytes.begin(), length);
|
236
258
|
}
|
237
259
|
|
@@ -363,7 +385,15 @@ public class Encoder {
|
|
363
385
|
|
364
386
|
private void appendOther(IRubyObject object, IRubyObject destination) {
|
365
387
|
if (registry != null) {
|
366
|
-
|
388
|
+
RubyModule lookupClass;
|
389
|
+
|
390
|
+
if (object.getType() == runtime.getSymbol()) {
|
391
|
+
lookupClass = object.getType();
|
392
|
+
} else {
|
393
|
+
lookupClass = object.getSingletonClass();
|
394
|
+
}
|
395
|
+
|
396
|
+
IRubyObject[] pair = registry.lookupPackerForObject(object);
|
367
397
|
if (pair != null) {
|
368
398
|
RubyString bytes = pair[0].callMethod(runtime.getCurrentContext(), "call", object).asString();
|
369
399
|
int type = (int) ((RubyFixnum) pair[1]).getLongValue();
|
@@ -3,8 +3,9 @@ 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
|
+
import org.jruby.RubySymbol;
|
8
9
|
import org.jruby.runtime.ThreadContext;
|
9
10
|
import org.jruby.runtime.builtin.IRubyObject;
|
10
11
|
|
@@ -12,19 +13,19 @@ import java.util.Map;
|
|
12
13
|
import java.util.HashMap;
|
13
14
|
|
14
15
|
public class ExtensionRegistry {
|
15
|
-
private final Map<
|
16
|
-
private final Map<
|
16
|
+
private final Map<RubyModule, ExtensionEntry> extensionsByModule;
|
17
|
+
private final Map<RubyModule, ExtensionEntry> extensionsByAncestor;
|
17
18
|
private final ExtensionEntry[] extensionsByTypeId;
|
18
19
|
|
19
20
|
public ExtensionRegistry() {
|
20
|
-
this(new HashMap<
|
21
|
+
this(new HashMap<RubyModule, ExtensionEntry>());
|
21
22
|
}
|
22
23
|
|
23
|
-
private ExtensionRegistry(Map<
|
24
|
-
this.
|
25
|
-
this.extensionsByAncestor = new HashMap<
|
24
|
+
private ExtensionRegistry(Map<RubyModule, ExtensionEntry> extensionsByModule) {
|
25
|
+
this.extensionsByModule = new HashMap<RubyModule, ExtensionEntry>(extensionsByModule);
|
26
|
+
this.extensionsByAncestor = new HashMap<RubyModule, ExtensionEntry>();
|
26
27
|
this.extensionsByTypeId = new ExtensionEntry[256];
|
27
|
-
for (ExtensionEntry entry :
|
28
|
+
for (ExtensionEntry entry : extensionsByModule.values()) {
|
28
29
|
if (entry.hasUnpacker()) {
|
29
30
|
extensionsByTypeId[entry.getTypeId() + 128] = entry;
|
30
31
|
}
|
@@ -32,15 +33,15 @@ public class ExtensionRegistry {
|
|
32
33
|
}
|
33
34
|
|
34
35
|
public ExtensionRegistry dup() {
|
35
|
-
return new ExtensionRegistry(
|
36
|
+
return new ExtensionRegistry(extensionsByModule);
|
36
37
|
}
|
37
38
|
|
38
39
|
public IRubyObject toInternalPackerRegistry(ThreadContext ctx) {
|
39
40
|
RubyHash hash = RubyHash.newHash(ctx.getRuntime());
|
40
|
-
for (
|
41
|
-
ExtensionEntry entry =
|
41
|
+
for (RubyModule extensionModule : extensionsByModule.keySet()) {
|
42
|
+
ExtensionEntry entry = extensionsByModule.get(extensionModule);
|
42
43
|
if (entry.hasPacker()) {
|
43
|
-
hash.put(
|
44
|
+
hash.put(extensionModule, entry.toPackerTuple(ctx));
|
44
45
|
}
|
45
46
|
}
|
46
47
|
return hash;
|
@@ -58,9 +59,9 @@ public class ExtensionRegistry {
|
|
58
59
|
return hash;
|
59
60
|
}
|
60
61
|
|
61
|
-
public void put(
|
62
|
-
ExtensionEntry entry = new ExtensionEntry(
|
63
|
-
|
62
|
+
public void put(RubyModule mod, int typeId, IRubyObject packerProc, IRubyObject packerArg, IRubyObject unpackerProc, IRubyObject unpackerArg) {
|
63
|
+
ExtensionEntry entry = new ExtensionEntry(mod, typeId, packerProc, packerArg, unpackerProc, unpackerArg);
|
64
|
+
extensionsByModule.put(mod, entry);
|
64
65
|
extensionsByTypeId[typeId + 128] = entry;
|
65
66
|
extensionsByAncestor.clear();
|
66
67
|
}
|
@@ -74,45 +75,73 @@ public class ExtensionRegistry {
|
|
74
75
|
}
|
75
76
|
}
|
76
77
|
|
77
|
-
public IRubyObject[]
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
public IRubyObject[] lookupPackerForObject(IRubyObject object) {
|
79
|
+
RubyModule lookupClass = null;
|
80
|
+
IRubyObject[] pair;
|
81
|
+
/*
|
82
|
+
* Objects of type Integer (Fixnum, Bignum), Float, Symbol and frozen
|
83
|
+
* String have no singleton class and raise a TypeError when trying to get
|
84
|
+
* it.
|
85
|
+
*
|
86
|
+
* Since all but symbols are already filtered out when reaching this code
|
87
|
+
* only symbols are checked here.
|
88
|
+
*/
|
89
|
+
if (!(object instanceof RubySymbol)) {
|
90
|
+
lookupClass = object.getSingletonClass();
|
91
|
+
pair = fetchEntryByModule(lookupClass);
|
92
|
+
if (pair != null) {
|
93
|
+
return pair;
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
pair = fetchEntryByModule(object.getType());
|
98
|
+
if (pair != null) {
|
99
|
+
return pair;
|
100
|
+
}
|
101
|
+
|
102
|
+
if (lookupClass == null) {
|
103
|
+
lookupClass = object.getType(); // only for Symbol
|
104
|
+
}
|
105
|
+
ExtensionEntry e = findEntryByModuleOrAncestor(lookupClass);
|
106
|
+
if (e != null && e.hasPacker()) {
|
107
|
+
extensionsByAncestor.put(e.getExtensionModule(), e);
|
108
|
+
return e.toPackerProcTypeIdPair(lookupClass.getRuntime().getCurrentContext());
|
81
109
|
}
|
110
|
+
return null;
|
111
|
+
}
|
112
|
+
|
113
|
+
private IRubyObject[] fetchEntryByModule(final RubyModule mod) {
|
114
|
+
ExtensionEntry e = extensionsByModule.get(mod);
|
82
115
|
if (e == null) {
|
83
|
-
e =
|
84
|
-
if (e != null) {
|
85
|
-
extensionsByAncestor.put(e.getExtensionClass(), e);
|
86
|
-
}
|
116
|
+
e = extensionsByAncestor.get(mod);
|
87
117
|
}
|
88
118
|
if (e != null && e.hasPacker()) {
|
89
|
-
return e.toPackerProcTypeIdPair(
|
90
|
-
} else {
|
91
|
-
return null;
|
119
|
+
return e.toPackerProcTypeIdPair(mod.getRuntime().getCurrentContext());
|
92
120
|
}
|
121
|
+
return null;
|
93
122
|
}
|
94
123
|
|
95
|
-
private ExtensionEntry
|
96
|
-
ThreadContext ctx =
|
97
|
-
for (
|
98
|
-
RubyArray ancestors = (RubyArray)
|
99
|
-
if (ancestors.callMethod(ctx, "include?",
|
100
|
-
return
|
124
|
+
private ExtensionEntry findEntryByModuleOrAncestor(final RubyModule mod) {
|
125
|
+
ThreadContext ctx = mod.getRuntime().getCurrentContext();
|
126
|
+
for (RubyModule extensionModule : extensionsByModule.keySet()) {
|
127
|
+
RubyArray ancestors = (RubyArray) mod.callMethod(ctx, "ancestors");
|
128
|
+
if (ancestors.callMethod(ctx, "include?", extensionModule).isTrue()) {
|
129
|
+
return extensionsByModule.get(extensionModule);
|
101
130
|
}
|
102
131
|
}
|
103
132
|
return null;
|
104
133
|
}
|
105
134
|
|
106
135
|
private static class ExtensionEntry {
|
107
|
-
private final
|
136
|
+
private final RubyModule mod;
|
108
137
|
private final int typeId;
|
109
138
|
private final IRubyObject packerProc;
|
110
139
|
private final IRubyObject packerArg;
|
111
140
|
private final IRubyObject unpackerProc;
|
112
141
|
private final IRubyObject unpackerArg;
|
113
142
|
|
114
|
-
public ExtensionEntry(
|
115
|
-
this.
|
143
|
+
public ExtensionEntry(RubyModule mod, int typeId, IRubyObject packerProc, IRubyObject packerArg, IRubyObject unpackerProc, IRubyObject unpackerArg) {
|
144
|
+
this.mod = mod;
|
116
145
|
this.typeId = typeId;
|
117
146
|
this.packerProc = packerProc;
|
118
147
|
this.packerArg = packerArg;
|
@@ -120,8 +149,8 @@ public class ExtensionRegistry {
|
|
120
149
|
this.unpackerArg = unpackerArg;
|
121
150
|
}
|
122
151
|
|
123
|
-
public
|
124
|
-
return
|
152
|
+
public RubyModule getExtensionModule() {
|
153
|
+
return mod;
|
125
154
|
}
|
126
155
|
|
127
156
|
public int getTypeId() {
|
@@ -149,7 +178,7 @@ public class ExtensionRegistry {
|
|
149
178
|
}
|
150
179
|
|
151
180
|
public RubyArray toUnpackerTuple(ThreadContext ctx) {
|
152
|
-
return RubyArray.newArray(ctx.getRuntime(), new IRubyObject[] {
|
181
|
+
return RubyArray.newArray(ctx.getRuntime(), new IRubyObject[] {mod, unpackerProc, unpackerArg});
|
153
182
|
}
|
154
183
|
|
155
184
|
public IRubyObject[] toPackerProcTypeIdPair(ThreadContext ctx) {
|