msgpack 0.7.4 → 1.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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) {
|