msgpack 0.6.0-x86-mswin32-60
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 +7 -0
- data/.gitignore +20 -0
- data/.travis.yml +26 -0
- data/ChangeLog +129 -0
- data/Dockerfile +62 -0
- data/LICENSE +177 -0
- data/README.rdoc +141 -0
- data/Rakefile +68 -0
- data/bench/pack.rb +23 -0
- data/bench/pack_log.rb +33 -0
- data/bench/pack_log_long.rb +65 -0
- data/bench/run.sh +14 -0
- data/bench/run_long.sh +35 -0
- data/bench/unpack.rb +21 -0
- data/bench/unpack_log.rb +34 -0
- data/bench/unpack_log_long.rb +67 -0
- data/doclib/msgpack.rb +77 -0
- data/doclib/msgpack/buffer.rb +193 -0
- data/doclib/msgpack/core_ext.rb +101 -0
- data/doclib/msgpack/error.rb +14 -0
- data/doclib/msgpack/packer.rb +134 -0
- data/doclib/msgpack/unpacker.rb +146 -0
- data/ext/java/org/msgpack/jruby/Buffer.java +221 -0
- data/ext/java/org/msgpack/jruby/Decoder.java +201 -0
- data/ext/java/org/msgpack/jruby/Encoder.java +308 -0
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +136 -0
- data/ext/java/org/msgpack/jruby/MessagePackLibrary.java +107 -0
- data/ext/java/org/msgpack/jruby/Packer.java +78 -0
- data/ext/java/org/msgpack/jruby/Types.java +37 -0
- data/ext/java/org/msgpack/jruby/Unpacker.java +170 -0
- data/ext/msgpack/buffer.c +695 -0
- data/ext/msgpack/buffer.h +447 -0
- data/ext/msgpack/buffer_class.c +507 -0
- data/ext/msgpack/buffer_class.h +32 -0
- data/ext/msgpack/compat.h +114 -0
- data/ext/msgpack/core_ext.c +129 -0
- data/ext/msgpack/core_ext.h +26 -0
- data/ext/msgpack/extconf.rb +30 -0
- data/ext/msgpack/packer.c +168 -0
- data/ext/msgpack/packer.h +441 -0
- data/ext/msgpack/packer_class.c +302 -0
- data/ext/msgpack/packer_class.h +30 -0
- data/ext/msgpack/rbinit.c +33 -0
- data/ext/msgpack/rmem.c +94 -0
- data/ext/msgpack/rmem.h +109 -0
- data/ext/msgpack/sysdep.h +115 -0
- data/ext/msgpack/sysdep_endian.h +50 -0
- data/ext/msgpack/sysdep_types.h +46 -0
- data/ext/msgpack/unpacker.c +771 -0
- data/ext/msgpack/unpacker.h +122 -0
- data/ext/msgpack/unpacker_class.c +405 -0
- data/ext/msgpack/unpacker_class.h +32 -0
- data/lib/msgpack.rb +13 -0
- data/lib/msgpack/version.rb +3 -0
- data/msgpack.gemspec +31 -0
- data/msgpack.org.md +46 -0
- data/spec/cases.json +1 -0
- data/spec/cases.msg +0 -0
- data/spec/cases_compact.msg +0 -0
- data/spec/cases_spec.rb +39 -0
- data/spec/cruby/buffer_io_spec.rb +256 -0
- data/spec/cruby/buffer_packer.rb +29 -0
- data/spec/cruby/buffer_spec.rb +572 -0
- data/spec/cruby/buffer_unpacker.rb +19 -0
- data/spec/cruby/packer_spec.rb +120 -0
- data/spec/cruby/unpacker_spec.rb +305 -0
- data/spec/format_spec.rb +282 -0
- data/spec/jruby/benchmarks/shootout_bm.rb +73 -0
- data/spec/jruby/benchmarks/symbolize_keys_bm.rb +25 -0
- data/spec/jruby/msgpack/unpacker_spec.rb +290 -0
- data/spec/jruby/msgpack_spec.rb +142 -0
- data/spec/pack_spec.rb +67 -0
- data/spec/random_compat.rb +24 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/unpack_spec.rb +60 -0
- metadata +208 -0
@@ -0,0 +1,136 @@
|
|
1
|
+
package org.msgpack.jruby;
|
2
|
+
|
3
|
+
|
4
|
+
import java.util.Arrays;
|
5
|
+
import java.nio.ByteBuffer;
|
6
|
+
|
7
|
+
import org.jruby.Ruby;
|
8
|
+
import org.jruby.RubyClass;
|
9
|
+
import org.jruby.RubyObject;
|
10
|
+
import org.jruby.RubyFixnum;
|
11
|
+
import org.jruby.RubyString;
|
12
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
13
|
+
import org.jruby.runtime.ObjectAllocator;
|
14
|
+
import org.jruby.runtime.ThreadContext;
|
15
|
+
import org.jruby.anno.JRubyClass;
|
16
|
+
import org.jruby.anno.JRubyMethod;
|
17
|
+
import org.jruby.util.ByteList;
|
18
|
+
|
19
|
+
import static org.jruby.runtime.Visibility.PRIVATE;
|
20
|
+
|
21
|
+
import org.jcodings.Encoding;
|
22
|
+
|
23
|
+
import static org.msgpack.jruby.Types.*;
|
24
|
+
|
25
|
+
|
26
|
+
@JRubyClass(name="MessagePack::ExtensionValue")
|
27
|
+
public class ExtensionValue extends RubyObject {
|
28
|
+
private final Encoding binaryEncoding;
|
29
|
+
|
30
|
+
private RubyFixnum type;
|
31
|
+
private RubyString payload;
|
32
|
+
|
33
|
+
public ExtensionValue(Ruby runtime, RubyClass type) {
|
34
|
+
super(runtime, type);
|
35
|
+
this.binaryEncoding = runtime.getEncodingService().getAscii8bitEncoding();
|
36
|
+
}
|
37
|
+
|
38
|
+
public static class ExtensionValueAllocator implements ObjectAllocator {
|
39
|
+
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
|
40
|
+
return new ExtensionValue(runtime, klass);
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
public static ExtensionValue newExtensionValue(Ruby runtime, int type, byte[] payload) {
|
45
|
+
ExtensionValue v = new ExtensionValue(runtime, runtime.getModule("MessagePack").getClass("ExtensionValue"));
|
46
|
+
ByteList byteList = new ByteList(payload, runtime.getEncodingService().getAscii8bitEncoding());
|
47
|
+
v.initialize(runtime.getCurrentContext(), runtime.newFixnum(type), runtime.newString(byteList));
|
48
|
+
return v;
|
49
|
+
}
|
50
|
+
|
51
|
+
@JRubyMethod(name = "initialize", required = 2, visibility = PRIVATE)
|
52
|
+
public IRubyObject initialize(ThreadContext ctx, IRubyObject type, IRubyObject payload) {
|
53
|
+
this.type = (RubyFixnum) type;
|
54
|
+
this.payload = (RubyString) payload;
|
55
|
+
return this;
|
56
|
+
}
|
57
|
+
|
58
|
+
@JRubyMethod(name = "to_msgpack")
|
59
|
+
public IRubyObject toMsgpack() {
|
60
|
+
ByteList payloadBytes = payload.getByteList();
|
61
|
+
int payloadSize = payloadBytes.length();
|
62
|
+
int outputSize = 0;
|
63
|
+
boolean fixSize = payloadSize == 1 || payloadSize == 2 || payloadSize == 4 || payloadSize == 8 || payloadSize == 16;
|
64
|
+
if (fixSize) {
|
65
|
+
outputSize = 2 + payloadSize;
|
66
|
+
} else if (payloadSize < 0x100) {
|
67
|
+
outputSize = 3 + payloadSize;
|
68
|
+
} else if (payloadSize < 0x10000) {
|
69
|
+
outputSize = 4 + payloadSize;
|
70
|
+
} else {
|
71
|
+
outputSize = 6 + payloadSize;
|
72
|
+
}
|
73
|
+
byte[] bytes = new byte[outputSize];
|
74
|
+
ByteBuffer buffer = ByteBuffer.wrap(bytes);
|
75
|
+
if (payloadSize == 1) {
|
76
|
+
buffer.put(FIXEXT1);
|
77
|
+
buffer.put((byte) type.getLongValue());
|
78
|
+
buffer.put((byte) payloadBytes.get(0));
|
79
|
+
} else if (payloadSize == 2) {
|
80
|
+
buffer.put(FIXEXT2);
|
81
|
+
buffer.put((byte) type.getLongValue());
|
82
|
+
buffer.put(payloadBytes.unsafeBytes(), payloadBytes.begin(), 2);
|
83
|
+
} else if (payloadSize == 4) {
|
84
|
+
buffer.put(FIXEXT4);
|
85
|
+
buffer.put((byte) type.getLongValue());
|
86
|
+
buffer.put(payloadBytes.unsafeBytes(), payloadBytes.begin(), 4);
|
87
|
+
} else if (payloadSize == 8) {
|
88
|
+
buffer.put(FIXEXT8);
|
89
|
+
buffer.put((byte) type.getLongValue());
|
90
|
+
buffer.put(payloadBytes.unsafeBytes(), payloadBytes.begin(), 8);
|
91
|
+
} else if (payloadSize == 16) {
|
92
|
+
buffer.put(FIXEXT16);
|
93
|
+
buffer.put((byte) type.getLongValue());
|
94
|
+
buffer.put(payloadBytes.unsafeBytes(), payloadBytes.begin(), 16);
|
95
|
+
} else if (payloadSize < 0x100) {
|
96
|
+
buffer.put(VAREXT8);
|
97
|
+
buffer.put((byte) payloadSize);
|
98
|
+
buffer.put((byte) type.getLongValue());
|
99
|
+
buffer.put(payloadBytes.unsafeBytes(), payloadBytes.begin(), payloadSize);
|
100
|
+
} else if (payloadSize < 0x10000) {
|
101
|
+
buffer.put(VAREXT16);
|
102
|
+
buffer.putShort((short) payloadSize);
|
103
|
+
buffer.put((byte) type.getLongValue());
|
104
|
+
buffer.put(payloadBytes.unsafeBytes(), payloadBytes.begin(), payloadSize);
|
105
|
+
} else {
|
106
|
+
buffer.put(VAREXT32);
|
107
|
+
buffer.putInt(payloadSize);
|
108
|
+
buffer.put((byte) type.getLongValue());
|
109
|
+
buffer.put(payloadBytes.unsafeBytes(), payloadBytes.begin(), payloadSize);
|
110
|
+
}
|
111
|
+
return getRuntime().newString(new ByteList(bytes, binaryEncoding, false));
|
112
|
+
}
|
113
|
+
|
114
|
+
@JRubyMethod(name = {"to_s", "inspect"})
|
115
|
+
@Override
|
116
|
+
public IRubyObject to_s() {
|
117
|
+
IRubyObject payloadStr = payload.callMethod(getRuntime().getCurrentContext(), "inspect");
|
118
|
+
return getRuntime().newString(String.format("#<MessagePack::ExtensionValue @type=%d, @payload=%s>", type.getLongValue(), payloadStr));
|
119
|
+
}
|
120
|
+
|
121
|
+
@JRubyMethod(name = "hash")
|
122
|
+
@Override
|
123
|
+
public RubyFixnum hash() {
|
124
|
+
long hash = payload.hashCode() & (type.getLongValue() << 56);
|
125
|
+
return RubyFixnum.newFixnum(getRuntime(), hash);
|
126
|
+
}
|
127
|
+
|
128
|
+
@JRubyMethod(name = "eql?")
|
129
|
+
public IRubyObject eql_p(ThreadContext ctx, IRubyObject o) {
|
130
|
+
if (o instanceof ExtensionValue) {
|
131
|
+
ExtensionValue other = (ExtensionValue) o;
|
132
|
+
return getRuntime().newBoolean(this.type.callMethod(ctx, "eql?", other.type).isTrue() && this.payload.callMethod(ctx, "eql?", other.payload).isTrue());
|
133
|
+
}
|
134
|
+
return getRuntime().getFalse();
|
135
|
+
}
|
136
|
+
}
|
@@ -0,0 +1,107 @@
|
|
1
|
+
package org.msgpack.jruby;
|
2
|
+
|
3
|
+
|
4
|
+
import org.jruby.Ruby;
|
5
|
+
import org.jruby.RubyModule;
|
6
|
+
import org.jruby.RubyClass;
|
7
|
+
import org.jruby.RubyString;
|
8
|
+
import org.jruby.RubyNil;
|
9
|
+
import org.jruby.RubyBoolean;
|
10
|
+
import org.jruby.RubyHash;
|
11
|
+
import org.jruby.runtime.load.Library;
|
12
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
13
|
+
import org.jruby.runtime.ThreadContext;
|
14
|
+
import org.jruby.runtime.Block;
|
15
|
+
import org.jruby.runtime.Visibility;
|
16
|
+
import org.jruby.anno.JRubyModule;
|
17
|
+
import org.jruby.anno.JRubyMethod;
|
18
|
+
import org.jruby.internal.runtime.methods.CallConfiguration;
|
19
|
+
import org.jruby.internal.runtime.methods.DynamicMethod;
|
20
|
+
|
21
|
+
|
22
|
+
public class MessagePackLibrary implements Library {
|
23
|
+
public void load(Ruby runtime, boolean wrap) {
|
24
|
+
RubyModule msgpackModule = runtime.defineModule("MessagePack");
|
25
|
+
msgpackModule.defineAnnotatedMethods(MessagePackModule.class);
|
26
|
+
RubyClass standardErrorClass = runtime.getStandardError();
|
27
|
+
RubyClass unpackErrorClass = msgpackModule.defineClassUnder("UnpackError", standardErrorClass, standardErrorClass.getAllocator());
|
28
|
+
RubyClass underflowErrorClass = msgpackModule.defineClassUnder("UnderflowError", unpackErrorClass, unpackErrorClass.getAllocator());
|
29
|
+
RubyClass extensionValueClass = msgpackModule.defineClassUnder("ExtensionValue", runtime.getObject(), new ExtensionValue.ExtensionValueAllocator());
|
30
|
+
extensionValueClass.defineAnnotatedMethods(ExtensionValue.class);
|
31
|
+
RubyClass packerClass = msgpackModule.defineClassUnder("Packer", runtime.getObject(), new Packer.PackerAllocator());
|
32
|
+
packerClass.defineAnnotatedMethods(Packer.class);
|
33
|
+
RubyClass unpackerClass = msgpackModule.defineClassUnder("Unpacker", runtime.getObject(), new Unpacker.UnpackerAllocator());
|
34
|
+
unpackerClass.defineAnnotatedMethods(Unpacker.class);
|
35
|
+
RubyClass bufferClass = msgpackModule.defineClassUnder("Buffer", runtime.getObject(), new Buffer.BufferAllocator());
|
36
|
+
bufferClass.defineAnnotatedMethods(Buffer.class);
|
37
|
+
installCoreExtensions(runtime);
|
38
|
+
}
|
39
|
+
|
40
|
+
private void installCoreExtensions(Ruby runtime) {
|
41
|
+
installCoreExtensions(
|
42
|
+
runtime,
|
43
|
+
runtime.getNilClass(),
|
44
|
+
runtime.getTrueClass(),
|
45
|
+
runtime.getFalseClass(),
|
46
|
+
runtime.getFixnum(),
|
47
|
+
runtime.getBignum(),
|
48
|
+
runtime.getFloat(),
|
49
|
+
runtime.getString(),
|
50
|
+
runtime.getArray(),
|
51
|
+
runtime.getHash(),
|
52
|
+
runtime.getSymbol()
|
53
|
+
);
|
54
|
+
}
|
55
|
+
|
56
|
+
private void installCoreExtensions(Ruby runtime, RubyClass... classes) {
|
57
|
+
for (RubyClass cls : classes) {
|
58
|
+
cls.addMethod("to_msgpack", createToMsgpackMethod(runtime, cls));
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
private DynamicMethod createToMsgpackMethod(final Ruby runtime, RubyClass cls) {
|
63
|
+
return new DynamicMethod(cls, Visibility.PUBLIC, CallConfiguration.FrameNoneScopeNone) {
|
64
|
+
@Override
|
65
|
+
public IRubyObject call(ThreadContext context, IRubyObject recv, RubyModule clazz, String name, IRubyObject[] args, Block block) {
|
66
|
+
IRubyObject[] allArgs = new IRubyObject[1 + args.length];
|
67
|
+
allArgs[0] = recv;
|
68
|
+
System.arraycopy(args, 0, allArgs, 1, args.length);
|
69
|
+
return MessagePackModule.pack(runtime.getCurrentContext(), null, allArgs);
|
70
|
+
}
|
71
|
+
|
72
|
+
@Override
|
73
|
+
public DynamicMethod dup() {
|
74
|
+
return this;
|
75
|
+
}
|
76
|
+
};
|
77
|
+
}
|
78
|
+
|
79
|
+
@JRubyModule(name = "MessagePack")
|
80
|
+
public static class MessagePackModule {
|
81
|
+
@JRubyMethod(module = true, required = 1, optional = 1, alias = {"dump"})
|
82
|
+
public static IRubyObject pack(ThreadContext ctx, IRubyObject recv, IRubyObject[] args) {
|
83
|
+
IRubyObject[] extraArgs = null;
|
84
|
+
if (args.length == 0) {
|
85
|
+
extraArgs = new IRubyObject[] {};
|
86
|
+
} else {
|
87
|
+
extraArgs = new IRubyObject[args.length - 1];
|
88
|
+
System.arraycopy(args, 1, extraArgs, 0, args.length - 1);
|
89
|
+
}
|
90
|
+
Packer packer = new Packer(ctx.getRuntime(), ctx.getRuntime().getModule("MessagePack").getClass("Packer"));
|
91
|
+
packer.initialize(ctx, extraArgs);
|
92
|
+
packer.write(ctx, args[0]);
|
93
|
+
return packer.toS(ctx);
|
94
|
+
}
|
95
|
+
|
96
|
+
@JRubyMethod(module = true, required = 1, optional = 1, alias = {"load"})
|
97
|
+
public static IRubyObject unpack(ThreadContext ctx, IRubyObject recv, IRubyObject[] args) {
|
98
|
+
Decoder decoder = new Decoder(ctx.getRuntime(), args[0].asString().getBytes());
|
99
|
+
if (args.length > 1 && !args[args.length - 1].isNil()) {
|
100
|
+
RubyHash hash = args[args.length - 1].convertToHash();
|
101
|
+
IRubyObject symbolizeKeys = hash.fastARef(ctx.getRuntime().newSymbol("symbolize_keys"));
|
102
|
+
decoder.symbolizeKeys(symbolizeKeys != null && symbolizeKeys.isTrue());
|
103
|
+
}
|
104
|
+
return decoder.next();
|
105
|
+
}
|
106
|
+
}
|
107
|
+
}
|
@@ -0,0 +1,78 @@
|
|
1
|
+
package org.msgpack.jruby;
|
2
|
+
|
3
|
+
|
4
|
+
import org.jruby.Ruby;
|
5
|
+
import org.jruby.RubyClass;
|
6
|
+
import org.jruby.RubyObject;
|
7
|
+
import org.jruby.RubyHash;
|
8
|
+
import org.jruby.RubyIO;
|
9
|
+
import org.jruby.RubyInteger;
|
10
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
11
|
+
import org.jruby.anno.JRubyClass;
|
12
|
+
import org.jruby.anno.JRubyMethod;
|
13
|
+
import org.jruby.runtime.ThreadContext;
|
14
|
+
import org.jruby.runtime.ObjectAllocator;
|
15
|
+
import org.jruby.util.ByteList;
|
16
|
+
|
17
|
+
|
18
|
+
@JRubyClass(name="MessagePack::Packer")
|
19
|
+
public class Packer extends RubyObject {
|
20
|
+
private Buffer buffer;
|
21
|
+
private Encoder encoder;
|
22
|
+
|
23
|
+
public Packer(Ruby runtime, RubyClass type) {
|
24
|
+
super(runtime, type);
|
25
|
+
}
|
26
|
+
|
27
|
+
static class PackerAllocator implements ObjectAllocator {
|
28
|
+
public IRubyObject allocate(Ruby runtime, RubyClass type) {
|
29
|
+
return new Packer(runtime, type);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
@JRubyMethod(name = "initialize", optional = 2)
|
34
|
+
public IRubyObject initialize(ThreadContext ctx, IRubyObject[] args) {
|
35
|
+
this.encoder = new Encoder(ctx.getRuntime());
|
36
|
+
this.buffer = new Buffer(ctx.getRuntime(), ctx.getRuntime().getModule("MessagePack").getClass("Buffer"));
|
37
|
+
this.buffer.initialize(ctx, args);
|
38
|
+
return this;
|
39
|
+
}
|
40
|
+
|
41
|
+
@JRubyMethod(name = "write")
|
42
|
+
public IRubyObject write(ThreadContext ctx, IRubyObject obj) {
|
43
|
+
return buffer.write(ctx, encoder.encode(obj, this));
|
44
|
+
}
|
45
|
+
|
46
|
+
@JRubyMethod(name = "write_nil")
|
47
|
+
public IRubyObject writeNil(ThreadContext ctx) {
|
48
|
+
return write(ctx, null);
|
49
|
+
}
|
50
|
+
|
51
|
+
@JRubyMethod(name = "write_array_header")
|
52
|
+
public IRubyObject writeArrayHeader(ThreadContext ctx, IRubyObject size) {
|
53
|
+
int s = (int) size.convertToInteger().getLongValue();
|
54
|
+
return buffer.write(ctx, encoder.encodeArrayHeader(s));
|
55
|
+
}
|
56
|
+
|
57
|
+
@JRubyMethod(name = "write_map_header")
|
58
|
+
public IRubyObject writeMapHeader(ThreadContext ctx, IRubyObject size) {
|
59
|
+
int s = (int) size.convertToInteger().getLongValue();
|
60
|
+
return buffer.write(ctx, encoder.encodeMapHeader(s));
|
61
|
+
}
|
62
|
+
|
63
|
+
@JRubyMethod(name = "to_s")
|
64
|
+
public IRubyObject toS(ThreadContext ctx) {
|
65
|
+
return buffer.toS(ctx);
|
66
|
+
}
|
67
|
+
|
68
|
+
@JRubyMethod(name = "buffer")
|
69
|
+
public IRubyObject buffer(ThreadContext ctx) {
|
70
|
+
return buffer;
|
71
|
+
}
|
72
|
+
|
73
|
+
@JRubyMethod(name = "flush")
|
74
|
+
public IRubyObject flush(ThreadContext ctx) {
|
75
|
+
return buffer.flush(ctx);
|
76
|
+
}
|
77
|
+
|
78
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
package org.msgpack.jruby;
|
2
|
+
|
3
|
+
|
4
|
+
public interface Types {
|
5
|
+
public static final byte FIXSTR = (byte) 0xa0; // This is actually not header byte, but prefix bit mask
|
6
|
+
public static final byte NIL = (byte) 0xc0;
|
7
|
+
public static final byte FALSE = (byte) 0xc2;
|
8
|
+
public static final byte TRUE = (byte) 0xc3;
|
9
|
+
public static final byte BIN8 = (byte) 0xc4;
|
10
|
+
public static final byte BIN16 = (byte) 0xc5;
|
11
|
+
public static final byte BIN32 = (byte) 0xc6;
|
12
|
+
public static final byte VAREXT8 = (byte) 0xc7;
|
13
|
+
public static final byte VAREXT16 = (byte) 0xc8;
|
14
|
+
public static final byte VAREXT32 = (byte) 0xc9;
|
15
|
+
public static final byte FLOAT32 = (byte) 0xca;
|
16
|
+
public static final byte FLOAT64 = (byte) 0xcb;
|
17
|
+
public static final byte UINT8 = (byte) 0xcc;
|
18
|
+
public static final byte UINT16 = (byte) 0xcd;
|
19
|
+
public static final byte UINT32 = (byte) 0xce;
|
20
|
+
public static final byte UINT64 = (byte) 0xcf;
|
21
|
+
public static final byte INT8 = (byte) 0xd0;
|
22
|
+
public static final byte INT16 = (byte) 0xd1;
|
23
|
+
public static final byte INT32 = (byte) 0xd2;
|
24
|
+
public static final byte INT64 = (byte) 0xd3;
|
25
|
+
public static final byte FIXEXT1 = (byte) 0xd4;
|
26
|
+
public static final byte FIXEXT2 = (byte) 0xd5;
|
27
|
+
public static final byte FIXEXT4 = (byte) 0xd6;
|
28
|
+
public static final byte FIXEXT8 = (byte) 0xd7;
|
29
|
+
public static final byte FIXEXT16 = (byte) 0xd8;
|
30
|
+
public static final byte STR8 = (byte) 0xd9;
|
31
|
+
public static final byte STR16 = (byte) 0xda;
|
32
|
+
public static final byte STR32 = (byte) 0xdb;
|
33
|
+
public static final byte ARY16 = (byte) 0xdc;
|
34
|
+
public static final byte ARY32 = (byte) 0xdd;
|
35
|
+
public static final byte MAP16 = (byte) 0xde;
|
36
|
+
public static final byte MAP32 = (byte) 0xdf;
|
37
|
+
}
|
@@ -0,0 +1,170 @@
|
|
1
|
+
package org.msgpack.jruby;
|
2
|
+
|
3
|
+
|
4
|
+
import org.jruby.Ruby;
|
5
|
+
import org.jruby.RubyClass;
|
6
|
+
import org.jruby.RubyString;
|
7
|
+
import org.jruby.RubyObject;
|
8
|
+
import org.jruby.RubyHash;
|
9
|
+
import org.jruby.RubyNumeric;
|
10
|
+
import org.jruby.RubyIO;
|
11
|
+
import org.jruby.exceptions.RaiseException;
|
12
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
13
|
+
import org.jruby.runtime.Block;
|
14
|
+
import org.jruby.runtime.ObjectAllocator;
|
15
|
+
import org.jruby.runtime.ThreadContext;
|
16
|
+
import org.jruby.anno.JRubyClass;
|
17
|
+
import org.jruby.anno.JRubyMethod;
|
18
|
+
import org.jruby.util.ByteList;
|
19
|
+
import org.jruby.ext.stringio.StringIO;
|
20
|
+
|
21
|
+
import static org.jruby.runtime.Visibility.PRIVATE;
|
22
|
+
|
23
|
+
|
24
|
+
@JRubyClass(name="MessagePack::Unpacker")
|
25
|
+
public class Unpacker extends RubyObject {
|
26
|
+
private IRubyObject stream;
|
27
|
+
private IRubyObject data;
|
28
|
+
private Decoder decoder;
|
29
|
+
private final RubyClass underflowErrorClass;
|
30
|
+
|
31
|
+
public Unpacker(Ruby runtime, RubyClass type) {
|
32
|
+
super(runtime, type);
|
33
|
+
this.underflowErrorClass = runtime.getModule("MessagePack").getClass("UnderflowError");
|
34
|
+
}
|
35
|
+
|
36
|
+
static class UnpackerAllocator implements ObjectAllocator {
|
37
|
+
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
|
38
|
+
return new Unpacker(runtime, klass);
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
@JRubyMethod(name = "initialize", optional = 1, visibility = PRIVATE)
|
43
|
+
public IRubyObject initialize(ThreadContext ctx, IRubyObject[] args) {
|
44
|
+
if (args.length > 0) {
|
45
|
+
if (args[args.length - 1] instanceof RubyHash) {
|
46
|
+
//TODO: symbolize_keys
|
47
|
+
} else if (!(args[0] instanceof RubyHash)) {
|
48
|
+
setStream(ctx, args[0]);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
return this;
|
52
|
+
}
|
53
|
+
|
54
|
+
@JRubyMethod(required = 2)
|
55
|
+
public IRubyObject execute(ThreadContext ctx, IRubyObject data, IRubyObject offset) {
|
56
|
+
return executeLimit(ctx, data, offset, null);
|
57
|
+
}
|
58
|
+
|
59
|
+
@JRubyMethod(name = "execute_limit", required = 3)
|
60
|
+
public IRubyObject executeLimit(ThreadContext ctx, IRubyObject str, IRubyObject off, IRubyObject lim) {
|
61
|
+
RubyString input = str.asString();
|
62
|
+
int offset = RubyNumeric.fix2int(off);
|
63
|
+
int limit = lim == null || lim.isNil() ? -1 : RubyNumeric.fix2int(lim);
|
64
|
+
ByteList byteList = input.getByteList();
|
65
|
+
if (limit == -1) {
|
66
|
+
limit = byteList.length() - offset;
|
67
|
+
}
|
68
|
+
Decoder decoder = new Decoder(ctx.getRuntime(), byteList.unsafeBytes(), byteList.begin() + offset, limit);
|
69
|
+
try {
|
70
|
+
this.data = null;
|
71
|
+
this.data = decoder.next();
|
72
|
+
} catch (RaiseException re) {
|
73
|
+
if (re.getException().getType() != underflowErrorClass) {
|
74
|
+
throw re;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
return ctx.getRuntime().newFixnum(decoder.offset());
|
78
|
+
}
|
79
|
+
|
80
|
+
@JRubyMethod(name = "data")
|
81
|
+
public IRubyObject getData(ThreadContext ctx) {
|
82
|
+
if (data == null) {
|
83
|
+
return ctx.getRuntime().getNil();
|
84
|
+
} else {
|
85
|
+
return data;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
@JRubyMethod(name = "finished?")
|
90
|
+
public IRubyObject finished_p(ThreadContext ctx) {
|
91
|
+
return data == null ? ctx.getRuntime().getFalse() : ctx.getRuntime().getTrue();
|
92
|
+
}
|
93
|
+
|
94
|
+
@JRubyMethod(required = 1)
|
95
|
+
public IRubyObject feed(ThreadContext ctx, IRubyObject data) {
|
96
|
+
ByteList byteList = data.asString().getByteList();
|
97
|
+
if (decoder == null) {
|
98
|
+
decoder = new Decoder(ctx.getRuntime(), byteList.unsafeBytes(), byteList.begin(), byteList.length());
|
99
|
+
} else {
|
100
|
+
decoder.feed(byteList.unsafeBytes(), byteList.begin(), byteList.length());
|
101
|
+
}
|
102
|
+
return ctx.getRuntime().getNil();
|
103
|
+
}
|
104
|
+
|
105
|
+
@JRubyMethod(name = "feed_each", required = 1)
|
106
|
+
public IRubyObject feedEach(ThreadContext ctx, IRubyObject data, Block block) {
|
107
|
+
feed(ctx, data);
|
108
|
+
each(ctx, block);
|
109
|
+
return ctx.getRuntime().getNil();
|
110
|
+
}
|
111
|
+
|
112
|
+
@JRubyMethod
|
113
|
+
public IRubyObject each(ThreadContext ctx, Block block) {
|
114
|
+
if (block.isGiven()) {
|
115
|
+
if (decoder != null) {
|
116
|
+
try {
|
117
|
+
while (decoder.hasNext()) {
|
118
|
+
block.yield(ctx, decoder.next());
|
119
|
+
}
|
120
|
+
} catch (RaiseException re) {
|
121
|
+
if (re.getException().getType() != underflowErrorClass) {
|
122
|
+
throw re;
|
123
|
+
}
|
124
|
+
}
|
125
|
+
}
|
126
|
+
return this;
|
127
|
+
} else {
|
128
|
+
return callMethod(ctx, "to_enum");
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
@JRubyMethod
|
133
|
+
public IRubyObject fill(ThreadContext ctx) {
|
134
|
+
return ctx.getRuntime().getNil();
|
135
|
+
}
|
136
|
+
|
137
|
+
@JRubyMethod
|
138
|
+
public IRubyObject reset(ThreadContext ctx) {
|
139
|
+
if (decoder != null) {
|
140
|
+
decoder.reset();
|
141
|
+
}
|
142
|
+
return ctx.getRuntime().getNil();
|
143
|
+
}
|
144
|
+
|
145
|
+
@JRubyMethod(name = "stream")
|
146
|
+
public IRubyObject getStream(ThreadContext ctx) {
|
147
|
+
if (stream == null) {
|
148
|
+
return ctx.getRuntime().getNil();
|
149
|
+
} else {
|
150
|
+
return stream;
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
@JRubyMethod(name = "stream=", required = 1)
|
155
|
+
public IRubyObject setStream(ThreadContext ctx, IRubyObject stream) {
|
156
|
+
RubyString str;
|
157
|
+
if (stream instanceof StringIO) {
|
158
|
+
str = stream.callMethod(ctx, "string").asString();
|
159
|
+
} else if (stream instanceof RubyIO) {
|
160
|
+
str = stream.callMethod(ctx, "read").asString();
|
161
|
+
} else {
|
162
|
+
throw ctx.getRuntime().newTypeError(stream, "IO");
|
163
|
+
}
|
164
|
+
ByteList byteList = str.getByteList();
|
165
|
+
this.stream = stream;
|
166
|
+
this.decoder = null;
|
167
|
+
this.decoder = new Decoder(ctx.getRuntime(), byteList.unsafeBytes(), byteList.begin(), byteList.length());
|
168
|
+
return getStream(ctx);
|
169
|
+
}
|
170
|
+
}
|