msgpack-jruby 1.3.1-java → 1.3.2-java
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/ext/msgpack_jruby.jar +0 -0
- data/lib/msgpack/version.rb +1 -1
- metadata +5 -23
- data/.gitignore +0 -5
- data/.rspec +0 -4
- data/.rvmrc +0 -3
- data/.travis.yml +0 -11
- data/Gemfile +0 -19
- data/Gemfile.lock +0 -60
- data/README.mdown +0 -26
- data/Rakefile +0 -64
- data/ext/.gitignore +0 -1
- data/ext/java/MsgpackJrubyService.java +0 -15
- data/ext/java/org/msgpack/jruby/MessagePackLibrary.java +0 -245
- data/ext/java/org/msgpack/jruby/RubyObjectPacker.java +0 -110
- data/ext/java/org/msgpack/jruby/RubyObjectUnpacker.java +0 -158
- data/msgpack-jruby.gemspec +0 -24
- data/spec/benchmarks/shootout_bm.rb +0 -73
- data/spec/benchmarks/symbolize_keys_bm.rb +0 -25
- data/spec/msgpack/unpacker_spec.rb +0 -254
- data/spec/msgpack_spec.rb +0 -95
- data/spec/spec_helper.rb +0 -10
Binary file
|
data/lib/msgpack/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: msgpack-jruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: java
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02-
|
12
|
+
date: 2013-02-21 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: JRuby compatible MessagePack implementation that does not use FFI
|
15
15
|
email:
|
@@ -18,29 +18,11 @@ executables: []
|
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
-
- ".gitignore"
|
22
|
-
- ".rspec"
|
23
|
-
- ".rvmrc"
|
24
|
-
- ".travis.yml"
|
25
|
-
- Gemfile
|
26
|
-
- Gemfile.lock
|
27
|
-
- README.mdown
|
28
|
-
- Rakefile
|
29
|
-
- ext/.gitignore
|
30
|
-
- ext/java/MsgpackJrubyService.java
|
31
|
-
- ext/java/org/msgpack/jruby/MessagePackLibrary.java
|
32
|
-
- ext/java/org/msgpack/jruby/RubyObjectPacker.java
|
33
|
-
- ext/java/org/msgpack/jruby/RubyObjectUnpacker.java
|
34
|
-
- lib/ext/javassist-3.15.0-GA.jar
|
35
|
-
- lib/ext/msgpack-0.6.6.jar
|
36
21
|
- lib/msgpack.rb
|
37
22
|
- lib/msgpack/version.rb
|
38
|
-
-
|
39
|
-
-
|
40
|
-
-
|
41
|
-
- spec/msgpack/unpacker_spec.rb
|
42
|
-
- spec/msgpack_spec.rb
|
43
|
-
- spec/spec_helper.rb
|
23
|
+
- lib/ext/javassist-3.15.0-GA.jar
|
24
|
+
- lib/ext/msgpack-0.6.6.jar
|
25
|
+
- lib/ext/msgpack_jruby.jar
|
44
26
|
homepage: http://github.com/iconara/msgpack-jruby
|
45
27
|
licenses: []
|
46
28
|
post_install_message:
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/.rvmrc
DELETED
data/.travis.yml
DELETED
data/Gemfile
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
source :rubygems
|
2
|
-
|
3
|
-
gemspec
|
4
|
-
|
5
|
-
gem 'rake'
|
6
|
-
|
7
|
-
group :development do
|
8
|
-
gem 'jruby-openssl'
|
9
|
-
gem 'viiite'
|
10
|
-
gem 'ffi-ncurses'
|
11
|
-
gem 'bson'
|
12
|
-
gem 'bson_ext', :platforms => :mri
|
13
|
-
gem 'json'
|
14
|
-
gem 'msgpack', :platforms => :mri
|
15
|
-
end
|
16
|
-
|
17
|
-
group :test do
|
18
|
-
gem 'rspec'
|
19
|
-
end
|
data/Gemfile.lock
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
msgpack-jruby (1.3.1-java)
|
5
|
-
|
6
|
-
GEM
|
7
|
-
remote: http://rubygems.org/
|
8
|
-
specs:
|
9
|
-
alf (0.10.1)
|
10
|
-
highline (~> 1.6.2)
|
11
|
-
myrrha (~> 1.2.1)
|
12
|
-
quickl (~> 0.4.1)
|
13
|
-
bouncy-castle-java (1.5.0146.1)
|
14
|
-
bson (1.5.2)
|
15
|
-
bson (1.5.2-java)
|
16
|
-
bson_ext (1.5.2)
|
17
|
-
bson (= 1.5.2)
|
18
|
-
diff-lcs (1.1.3)
|
19
|
-
ffi (1.0.9)
|
20
|
-
ffi (1.0.9-java)
|
21
|
-
ffi-ncurses (0.3.3)
|
22
|
-
ffi (>= 0.6.3)
|
23
|
-
gnuplot (2.3.6)
|
24
|
-
highline (1.6.2)
|
25
|
-
jruby-openssl (0.7.4)
|
26
|
-
bouncy-castle-java
|
27
|
-
json (1.5.0)
|
28
|
-
json (1.5.0-java)
|
29
|
-
msgpack (0.4.6)
|
30
|
-
myrrha (1.2.1)
|
31
|
-
quickl (0.4.1)
|
32
|
-
rake (10.0.2)
|
33
|
-
rspec (2.6.0)
|
34
|
-
rspec-core (~> 2.6.0)
|
35
|
-
rspec-expectations (~> 2.6.0)
|
36
|
-
rspec-mocks (~> 2.6.0)
|
37
|
-
rspec-core (2.6.4)
|
38
|
-
rspec-expectations (2.6.0)
|
39
|
-
diff-lcs (~> 1.1.2)
|
40
|
-
rspec-mocks (2.6.0)
|
41
|
-
viiite (0.1.0)
|
42
|
-
alf (~> 0.10.0)
|
43
|
-
gnuplot (~> 2.3.6)
|
44
|
-
quickl (~> 0.4.0)
|
45
|
-
|
46
|
-
PLATFORMS
|
47
|
-
java
|
48
|
-
ruby
|
49
|
-
|
50
|
-
DEPENDENCIES
|
51
|
-
bson
|
52
|
-
bson_ext
|
53
|
-
ffi-ncurses
|
54
|
-
jruby-openssl
|
55
|
-
json
|
56
|
-
msgpack
|
57
|
-
msgpack-jruby!
|
58
|
-
rake
|
59
|
-
rspec
|
60
|
-
viiite
|
data/README.mdown
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
# MessagePack for JRuby
|
2
|
-
|
3
|
-
A MessagePack implementation for JRuby, built on top of the MessagePack Java libraries. Faster and easier to use than using the C MessagePack gem in JRuby.
|
4
|
-
|
5
|
-
## Installation
|
6
|
-
|
7
|
-
gem install msgpack-jruby
|
8
|
-
|
9
|
-
or with Bundler
|
10
|
-
|
11
|
-
gem 'msgpack-jruby', :require => 'msgpack'
|
12
|
-
|
13
|
-
## Extra features
|
14
|
-
|
15
|
-
* Decode keys as symbols by passing `:symbolize_keys => true` to `#unpack`.
|
16
|
-
* Decode strings with their right encoding by passing `:encoding => Encoding::UTF_8` to `#unpack`.
|
17
|
-
|
18
|
-
## Copyright
|
19
|
-
|
20
|
-
Copyright 2012 Theo Hultberg
|
21
|
-
|
22
|
-
_Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License You may obtain a copy of the License at_
|
23
|
-
|
24
|
-
[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
25
|
-
|
26
|
-
_Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License._
|
data/Rakefile
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
$: << 'lib'
|
2
|
-
|
3
|
-
require 'bundler/setup'
|
4
|
-
require 'rspec/core/rake_task'
|
5
|
-
require 'msgpack/version'
|
6
|
-
|
7
|
-
|
8
|
-
task :default => :spec
|
9
|
-
|
10
|
-
RSpec::Core::RakeTask.new(:spec)
|
11
|
-
|
12
|
-
task :spec => :package
|
13
|
-
|
14
|
-
task :clean do
|
15
|
-
rm Dir['ext/java/**/*.class']
|
16
|
-
end
|
17
|
-
|
18
|
-
task :compile do
|
19
|
-
classpath = (Dir["lib/ext/*.jar"] + ["#{ENV['MY_RUBY_HOME']}/lib/jruby.jar"]).join(':')
|
20
|
-
system %(javac -Xlint:-options -source 1.6 -target 1.6 -cp #{classpath} ext/java/*.java ext/java/org/msgpack/jruby/*.java)
|
21
|
-
exit($?.exitstatus) unless $?.success?
|
22
|
-
end
|
23
|
-
|
24
|
-
task :package => :compile do
|
25
|
-
class_files = Dir['ext/java/**/*.class'].map { |path| path = path.sub('ext/java/', ''); "-C ext/java '#{path}'" }
|
26
|
-
system %(jar cf lib/ext/msgpack_jruby.jar #{class_files.join(' ')})
|
27
|
-
exit($?.exitstatus) unless $?.success?
|
28
|
-
end
|
29
|
-
|
30
|
-
task :release => :package do
|
31
|
-
version_string = "v#{MessagePack::VERSION}"
|
32
|
-
unless %x(git tag -l).include?(version_string)
|
33
|
-
system %(git tag -a #{version_string} -m #{version_string})
|
34
|
-
end
|
35
|
-
system %(gem build msgpack-jruby.gemspec && gem push msgpack-jruby-*.gem && mv msgpack-jruby-*.gem pkg)
|
36
|
-
end
|
37
|
-
|
38
|
-
namespace :benchmark do
|
39
|
-
BENCHMARK_RUBIES = ['1.9.2-p0', 'jruby-1.6.5', 'jruby-head']
|
40
|
-
BENCHMARK_GEMSET = 'msgpack-jruby-benchmarking'
|
41
|
-
BENCHMARK_FILE = 'spec/benchmarks/shootout_bm.rb'
|
42
|
-
|
43
|
-
task :run do
|
44
|
-
rubies = BENCHMARK_RUBIES.map { |rb| "#{rb}@#{BENCHMARK_GEMSET}" }
|
45
|
-
cmd = %(rvm #{rubies.join(',')} exec viiite run #{BENCHMARK_FILE} | tee benchmark | viiite report --hierarchy --regroup=bench,lib,ruby)
|
46
|
-
puts cmd
|
47
|
-
system cmd
|
48
|
-
end
|
49
|
-
|
50
|
-
task :quick do
|
51
|
-
cmd = %(IMPLEMENTATIONS=msgpack viiite run #{BENCHMARK_FILE} | viiite report --hierarchy --regroup=bench)
|
52
|
-
puts cmd
|
53
|
-
system cmd
|
54
|
-
end
|
55
|
-
|
56
|
-
task :setup do
|
57
|
-
rubies = BENCHMARK_RUBIES.map { |rb| "#{rb}@#{BENCHMARK_GEMSET}" }
|
58
|
-
rubies.each do |ruby_version|
|
59
|
-
cmd = %(rvm-shell #{ruby_version} -c 'bundle check || bundle install')
|
60
|
-
puts cmd
|
61
|
-
system cmd
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
data/ext/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
*.class
|
@@ -1,15 +0,0 @@
|
|
1
|
-
import java.io.IOException;
|
2
|
-
|
3
|
-
import org.jruby.Ruby;
|
4
|
-
import org.jruby.runtime.load.BasicLibraryService;
|
5
|
-
|
6
|
-
import org.msgpack.jruby.MessagePackLibrary;
|
7
|
-
|
8
|
-
|
9
|
-
public class MsgpackJrubyService implements BasicLibraryService {
|
10
|
-
public boolean basicLoad(final Ruby runtime) throws IOException {
|
11
|
-
new MessagePackLibrary().load(runtime, false);
|
12
|
-
return true;
|
13
|
-
}
|
14
|
-
}
|
15
|
-
|
@@ -1,245 +0,0 @@
|
|
1
|
-
package org.msgpack.jruby;
|
2
|
-
|
3
|
-
|
4
|
-
import java.io.InputStream;
|
5
|
-
import java.io.ByteArrayInputStream;
|
6
|
-
import java.io.IOException;
|
7
|
-
|
8
|
-
import org.jruby.Ruby;
|
9
|
-
import org.jruby.RubyModule;
|
10
|
-
import org.jruby.RubyClass;
|
11
|
-
import org.jruby.RubyString;
|
12
|
-
import org.jruby.RubyObject;
|
13
|
-
import org.jruby.RubyHash;
|
14
|
-
import org.jruby.RubyIO;
|
15
|
-
import org.jruby.RubyStringIO;
|
16
|
-
import org.jruby.RubyNumeric;
|
17
|
-
import org.jruby.RubyEnumerator;
|
18
|
-
import org.jruby.runtime.load.Library;
|
19
|
-
import org.jruby.runtime.callback.Callback;
|
20
|
-
import org.jruby.runtime.builtin.IRubyObject;
|
21
|
-
import org.jruby.runtime.Arity;
|
22
|
-
import org.jruby.runtime.Block;
|
23
|
-
import org.jruby.runtime.ObjectAllocator;
|
24
|
-
import org.jruby.runtime.ThreadContext;
|
25
|
-
import org.jruby.anno.JRubyClass;
|
26
|
-
import org.jruby.anno.JRubyModule;
|
27
|
-
import org.jruby.anno.JRubyMethod;
|
28
|
-
import org.jruby.util.IOInputStream;
|
29
|
-
|
30
|
-
import static org.jruby.runtime.Visibility.*;
|
31
|
-
|
32
|
-
import org.msgpack.MessagePack;
|
33
|
-
import org.msgpack.packer.BufferPacker;
|
34
|
-
import org.msgpack.packer.Packer;
|
35
|
-
import org.msgpack.unpacker.MessagePackBufferUnpacker;
|
36
|
-
import org.msgpack.unpacker.MessagePackUnpacker;
|
37
|
-
import org.msgpack.unpacker.UnpackerIterator;
|
38
|
-
import org.msgpack.type.Value;
|
39
|
-
import org.msgpack.io.Input;
|
40
|
-
import org.msgpack.io.LinkedBufferInput;
|
41
|
-
import org.msgpack.io.StreamInput;
|
42
|
-
|
43
|
-
|
44
|
-
public class MessagePackLibrary implements Library {
|
45
|
-
public void load(Ruby runtime, boolean wrap) throws IOException {
|
46
|
-
MessagePack msgPack = new MessagePack();
|
47
|
-
RubyModule msgpackModule = runtime.defineModule("MessagePack");
|
48
|
-
msgpackModule.defineAnnotatedMethods(MessagePackModule.class);
|
49
|
-
RubyClass standardErrorClass = runtime.getStandardError();
|
50
|
-
RubyClass unpackErrorClass = msgpackModule.defineClassUnder("UnpackError", standardErrorClass, standardErrorClass.getAllocator());
|
51
|
-
RubyClass unpackerClass = msgpackModule.defineClassUnder("Unpacker", runtime.getObject(), new UnpackerAllocator(msgPack));
|
52
|
-
unpackerClass.defineAnnotatedMethods(Unpacker.class);
|
53
|
-
}
|
54
|
-
|
55
|
-
@JRubyModule(name = "MessagePack")
|
56
|
-
public static class MessagePackModule {
|
57
|
-
private static MessagePack msgPack = new MessagePack();
|
58
|
-
private static RubyObjectPacker packer = new RubyObjectPacker(msgPack);
|
59
|
-
private static RubyObjectUnpacker unpacker = new RubyObjectUnpacker(msgPack);
|
60
|
-
|
61
|
-
@JRubyMethod(module = true, required = 1)
|
62
|
-
public static IRubyObject pack(ThreadContext ctx, IRubyObject recv, IRubyObject obj) throws IOException {
|
63
|
-
return packer.pack(obj);
|
64
|
-
}
|
65
|
-
|
66
|
-
@JRubyMethod(module = true, required = 1, optional = 1)
|
67
|
-
public static IRubyObject unpack(ThreadContext ctx, IRubyObject recv, IRubyObject[] args) throws IOException {
|
68
|
-
RubyHash options = (args.length == 2) ? (RubyHash) args[1] : null;
|
69
|
-
RubyString str = args[0].asString();
|
70
|
-
return unpacker.unpack(str, options);
|
71
|
-
}
|
72
|
-
}
|
73
|
-
|
74
|
-
private static class UnpackerAllocator implements ObjectAllocator {
|
75
|
-
private MessagePack msgPack;
|
76
|
-
|
77
|
-
public UnpackerAllocator(MessagePack msgPack) {
|
78
|
-
this.msgPack = msgPack;
|
79
|
-
}
|
80
|
-
|
81
|
-
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
|
82
|
-
return new Unpacker(runtime, klass, msgPack);
|
83
|
-
}
|
84
|
-
}
|
85
|
-
|
86
|
-
@JRubyClass(name="MessagePack::Unpacker")
|
87
|
-
public static class Unpacker extends RubyObject {
|
88
|
-
private MessagePack msgPack;
|
89
|
-
private RubyObjectUnpacker rubyObjectUnpacker;
|
90
|
-
private MessagePackBufferUnpacker bufferUnpacker;
|
91
|
-
private MessagePackUnpacker streamUnpacker;
|
92
|
-
private UnpackerIterator unpackerIterator;
|
93
|
-
private IRubyObject stream;
|
94
|
-
private IRubyObject data;
|
95
|
-
private RubyObjectUnpacker.CompiledOptions options;
|
96
|
-
|
97
|
-
public Unpacker(Ruby runtime, RubyClass type, MessagePack msgPack) {
|
98
|
-
super(runtime, type);
|
99
|
-
this.msgPack = msgPack;
|
100
|
-
this.rubyObjectUnpacker = new RubyObjectUnpacker(msgPack);
|
101
|
-
this.bufferUnpacker = null;
|
102
|
-
this.streamUnpacker = null;
|
103
|
-
this.stream = null;
|
104
|
-
this.data = null;
|
105
|
-
}
|
106
|
-
|
107
|
-
@JRubyMethod(name = "initialize", optional = 2, visibility = PRIVATE)
|
108
|
-
public IRubyObject initialize(ThreadContext ctx, IRubyObject[] args) {
|
109
|
-
if (args.length == 0) {
|
110
|
-
options = new RubyObjectUnpacker.CompiledOptions();
|
111
|
-
} else if (args.length == 1 && args[0] instanceof RubyHash) {
|
112
|
-
options = new RubyObjectUnpacker.CompiledOptions((RubyHash) args[0]);
|
113
|
-
} else if (args.length > 0) {
|
114
|
-
setStream(ctx, args[0]);
|
115
|
-
if (args.length > 2) {
|
116
|
-
options = new RubyObjectUnpacker.CompiledOptions((RubyHash) args[1]);
|
117
|
-
} else {
|
118
|
-
options = new RubyObjectUnpacker.CompiledOptions();
|
119
|
-
}
|
120
|
-
}
|
121
|
-
return this;
|
122
|
-
}
|
123
|
-
|
124
|
-
@JRubyMethod(required = 2)
|
125
|
-
public IRubyObject execute(ThreadContext ctx, IRubyObject data, IRubyObject offset) {
|
126
|
-
return executeLimit(ctx, data, offset, null);
|
127
|
-
}
|
128
|
-
|
129
|
-
@JRubyMethod(name = "execute_limit", required = 3)
|
130
|
-
public IRubyObject executeLimit(ThreadContext ctx, IRubyObject data, IRubyObject offset, IRubyObject limit) {
|
131
|
-
this.data = null;
|
132
|
-
try {
|
133
|
-
int jOffset = RubyNumeric.fix2int(offset);
|
134
|
-
int jLimit = -1;
|
135
|
-
if (limit != null) {
|
136
|
-
jLimit = RubyNumeric.fix2int(limit);
|
137
|
-
}
|
138
|
-
byte[] bytes = data.asString().getBytes();
|
139
|
-
MessagePackBufferUnpacker localBufferUnpacker = new MessagePackBufferUnpacker(msgPack, bytes.length);
|
140
|
-
localBufferUnpacker.wrap(bytes, jOffset, jLimit == -1 ? bytes.length - jOffset : jLimit);
|
141
|
-
this.data = rubyObjectUnpacker.valueToRubyObject(ctx.getRuntime(), localBufferUnpacker.readValue(), options);
|
142
|
-
return ctx.getRuntime().newFixnum(jOffset + localBufferUnpacker.getReadByteCount());
|
143
|
-
} catch (IOException ioe) {
|
144
|
-
// TODO: how to throw Ruby exceptions?
|
145
|
-
return ctx.getRuntime().getNil();
|
146
|
-
}
|
147
|
-
}
|
148
|
-
|
149
|
-
@JRubyMethod(name = "data")
|
150
|
-
public IRubyObject getData(ThreadContext ctx) {
|
151
|
-
if (data == null) {
|
152
|
-
return ctx.getRuntime().getNil();
|
153
|
-
} else {
|
154
|
-
return data;
|
155
|
-
}
|
156
|
-
}
|
157
|
-
|
158
|
-
@JRubyMethod(name = "finished?")
|
159
|
-
public IRubyObject finished_q(ThreadContext ctx) {
|
160
|
-
return data == null ? ctx.getRuntime().getFalse() : ctx.getRuntime().getTrue();
|
161
|
-
}
|
162
|
-
|
163
|
-
@JRubyMethod(required = 1)
|
164
|
-
public IRubyObject feed(ThreadContext ctx, IRubyObject data) {
|
165
|
-
streamUnpacker = null;
|
166
|
-
byte[] bytes = data.asString().getBytes();
|
167
|
-
if (bufferUnpacker == null) {
|
168
|
-
bufferUnpacker = new MessagePackBufferUnpacker(msgPack);
|
169
|
-
unpackerIterator = bufferUnpacker.iterator();
|
170
|
-
}
|
171
|
-
bufferUnpacker.feed(bytes);
|
172
|
-
return ctx.getRuntime().getNil();
|
173
|
-
}
|
174
|
-
|
175
|
-
@JRubyMethod(name = "feed_each", required = 1)
|
176
|
-
public IRubyObject feedEach(ThreadContext ctx, IRubyObject data, Block block) {
|
177
|
-
feed(ctx, data);
|
178
|
-
each(ctx, block);
|
179
|
-
return ctx.getRuntime().getNil();
|
180
|
-
}
|
181
|
-
|
182
|
-
@JRubyMethod
|
183
|
-
public IRubyObject each(ThreadContext ctx, Block block) {
|
184
|
-
MessagePackUnpacker localUnpacker = null;
|
185
|
-
if (bufferUnpacker == null && streamUnpacker != null) {
|
186
|
-
localUnpacker = streamUnpacker;
|
187
|
-
} else if (bufferUnpacker != null) {
|
188
|
-
localUnpacker = bufferUnpacker;
|
189
|
-
} else {
|
190
|
-
return ctx.getRuntime().getNil();
|
191
|
-
}
|
192
|
-
if (block.isGiven()) {
|
193
|
-
while (unpackerIterator.hasNext()) {
|
194
|
-
Value value = unpackerIterator.next();
|
195
|
-
IRubyObject rubyObject = rubyObjectUnpacker.valueToRubyObject(ctx.getRuntime(), value, options);
|
196
|
-
block.yield(ctx, rubyObject);
|
197
|
-
}
|
198
|
-
return ctx.getRuntime().getNil();
|
199
|
-
} else {
|
200
|
-
return RubyEnumerator.RubyEnumeratorKernel.obj_to_enum(ctx, this);
|
201
|
-
}
|
202
|
-
}
|
203
|
-
|
204
|
-
@JRubyMethod
|
205
|
-
public IRubyObject fill(ThreadContext ctx) {
|
206
|
-
return ctx.getRuntime().getNil();
|
207
|
-
}
|
208
|
-
|
209
|
-
@JRubyMethod
|
210
|
-
public IRubyObject reset(ThreadContext ctx) {
|
211
|
-
if (bufferUnpacker != null) {
|
212
|
-
bufferUnpacker.reset();
|
213
|
-
}
|
214
|
-
if (streamUnpacker != null) {
|
215
|
-
streamUnpacker.reset();
|
216
|
-
}
|
217
|
-
return ctx.getRuntime().getNil();
|
218
|
-
}
|
219
|
-
|
220
|
-
@JRubyMethod(name = "stream")
|
221
|
-
public IRubyObject getStream(ThreadContext ctx) {
|
222
|
-
if (stream == null) {
|
223
|
-
return ctx.getRuntime().getNil();
|
224
|
-
} else {
|
225
|
-
return stream;
|
226
|
-
}
|
227
|
-
}
|
228
|
-
|
229
|
-
@JRubyMethod(name = "stream=", required = 1)
|
230
|
-
public IRubyObject setStream(ThreadContext ctx, IRubyObject stream) {
|
231
|
-
bufferUnpacker = null;
|
232
|
-
this.stream = stream;
|
233
|
-
if (stream instanceof RubyStringIO) {
|
234
|
-
// TODO: RubyStringIO returns negative numbers when read through IOInputStream#read
|
235
|
-
IRubyObject str = ((RubyStringIO) stream).string();
|
236
|
-
byte[] bytes = ((RubyString) str).getBytes();
|
237
|
-
streamUnpacker = new MessagePackUnpacker(msgPack, new ByteArrayInputStream(bytes));
|
238
|
-
} else {
|
239
|
-
streamUnpacker = new MessagePackUnpacker(msgPack, new IOInputStream(stream));
|
240
|
-
}
|
241
|
-
unpackerIterator = streamUnpacker.iterator();
|
242
|
-
return getStream(ctx);
|
243
|
-
}
|
244
|
-
}
|
245
|
-
}
|
@@ -1,110 +0,0 @@
|
|
1
|
-
package org.msgpack.jruby;
|
2
|
-
|
3
|
-
|
4
|
-
import java.io.IOException;
|
5
|
-
|
6
|
-
import org.msgpack.MessagePack;
|
7
|
-
import org.msgpack.packer.BufferPacker;
|
8
|
-
|
9
|
-
import org.jruby.RubyObject;
|
10
|
-
import org.jruby.RubyNil;
|
11
|
-
import org.jruby.RubyBoolean;
|
12
|
-
import org.jruby.RubyBignum;
|
13
|
-
import org.jruby.RubyInteger;
|
14
|
-
import org.jruby.RubyFixnum;
|
15
|
-
import org.jruby.RubyFloat;
|
16
|
-
import org.jruby.RubyString;
|
17
|
-
import org.jruby.RubySymbol;
|
18
|
-
import org.jruby.RubyArray;
|
19
|
-
import org.jruby.RubyHash;
|
20
|
-
import org.jruby.runtime.builtin.IRubyObject;
|
21
|
-
|
22
|
-
|
23
|
-
public class RubyObjectPacker {
|
24
|
-
private final MessagePack msgPack;
|
25
|
-
|
26
|
-
public RubyObjectPacker(MessagePack msgPack) {
|
27
|
-
this.msgPack = msgPack;
|
28
|
-
}
|
29
|
-
|
30
|
-
public RubyString pack(IRubyObject o) throws IOException {
|
31
|
-
return RubyString.newString(o.getRuntime(), packRaw(o));
|
32
|
-
}
|
33
|
-
|
34
|
-
public byte[] packRaw(IRubyObject o) throws IOException {
|
35
|
-
BufferPacker packer = msgPack.createBufferPacker();
|
36
|
-
write(packer, o);
|
37
|
-
return packer.toByteArray();
|
38
|
-
}
|
39
|
-
|
40
|
-
private void write(BufferPacker packer, IRubyObject o) throws IOException {
|
41
|
-
if (o == null || o instanceof RubyNil) {
|
42
|
-
packer.writeNil();
|
43
|
-
} else if (o instanceof RubyBoolean) {
|
44
|
-
packer.write(((RubyBoolean) o).isTrue());
|
45
|
-
} else if (o instanceof RubyBignum) {
|
46
|
-
write(packer, (RubyBignum) o);
|
47
|
-
} else if (o instanceof RubyInteger) {
|
48
|
-
write(packer, (RubyInteger) o);
|
49
|
-
} else if (o instanceof RubyFixnum) {
|
50
|
-
write(packer, (RubyFixnum) o);
|
51
|
-
} else if (o instanceof RubyFloat) {
|
52
|
-
write(packer, (RubyFloat) o);
|
53
|
-
} else if (o instanceof RubyString) {
|
54
|
-
write(packer, (RubyString) o);
|
55
|
-
} else if (o instanceof RubySymbol) {
|
56
|
-
write(packer, (RubySymbol) o);
|
57
|
-
} else if (o instanceof RubyArray) {
|
58
|
-
write(packer, (RubyArray) o);
|
59
|
-
} else if (o instanceof RubyHash) {
|
60
|
-
write(packer, (RubyHash) o);
|
61
|
-
} else {
|
62
|
-
throw o.getRuntime().newArgumentError(String.format("Cannot pack type: %s", o.getClass().getName()));
|
63
|
-
}
|
64
|
-
}
|
65
|
-
|
66
|
-
private void write(BufferPacker packer, RubyBignum bignum) throws IOException {
|
67
|
-
packer.write(bignum.getBigIntegerValue());
|
68
|
-
}
|
69
|
-
|
70
|
-
private void write(BufferPacker packer, RubyInteger integer) throws IOException {
|
71
|
-
packer.write(integer.getLongValue());
|
72
|
-
}
|
73
|
-
|
74
|
-
private void write(BufferPacker packer, RubyFixnum fixnum) throws IOException {
|
75
|
-
packer.write(fixnum.getLongValue());
|
76
|
-
}
|
77
|
-
|
78
|
-
private void write(BufferPacker packer, RubyFloat flt) throws IOException {
|
79
|
-
packer.write(flt.getDoubleValue());
|
80
|
-
}
|
81
|
-
|
82
|
-
private void write(BufferPacker packer, RubyString str) throws IOException {
|
83
|
-
packer.write(str.getBytes());
|
84
|
-
}
|
85
|
-
|
86
|
-
private void write(BufferPacker packer, RubySymbol sym) throws IOException {
|
87
|
-
write(packer, (RubyString) sym.to_s());
|
88
|
-
}
|
89
|
-
|
90
|
-
private void write(BufferPacker packer, RubyArray array) throws IOException {
|
91
|
-
int count = array.size();
|
92
|
-
packer.writeArrayBegin(count);
|
93
|
-
for (int i = 0; i < count; i++) {
|
94
|
-
write(packer, (RubyObject) array.entry(i));
|
95
|
-
}
|
96
|
-
packer.writeArrayEnd();
|
97
|
-
}
|
98
|
-
|
99
|
-
private void write(BufferPacker packer, RubyHash hash) throws IOException {
|
100
|
-
int count = hash.size();
|
101
|
-
packer.writeMapBegin(count);
|
102
|
-
RubyArray keys = hash.keys();
|
103
|
-
RubyArray values = hash.rb_values();
|
104
|
-
for (int i = 0; i < count; i++) {
|
105
|
-
write(packer, (RubyObject) keys.entry(i));
|
106
|
-
write(packer, (RubyObject) values.entry(i));
|
107
|
-
}
|
108
|
-
packer.writeMapEnd();
|
109
|
-
}
|
110
|
-
}
|
@@ -1,158 +0,0 @@
|
|
1
|
-
package org.msgpack.jruby;
|
2
|
-
|
3
|
-
|
4
|
-
import java.io.IOException;
|
5
|
-
|
6
|
-
import org.msgpack.MessagePack;
|
7
|
-
import org.msgpack.MessageTypeException;
|
8
|
-
import org.msgpack.unpacker.MessagePackBufferUnpacker;
|
9
|
-
import org.msgpack.type.Value;
|
10
|
-
import org.msgpack.type.ValueType;
|
11
|
-
import org.msgpack.type.BooleanValue;
|
12
|
-
import org.msgpack.type.IntegerValue;
|
13
|
-
import org.msgpack.type.FloatValue;
|
14
|
-
import org.msgpack.type.ArrayValue;
|
15
|
-
import org.msgpack.type.MapValue;
|
16
|
-
import org.msgpack.type.RawValue;
|
17
|
-
|
18
|
-
import org.jruby.Ruby;
|
19
|
-
import org.jruby.RubyObject;
|
20
|
-
import org.jruby.RubyNil;
|
21
|
-
import org.jruby.RubyBoolean;
|
22
|
-
import org.jruby.RubyBignum;
|
23
|
-
import org.jruby.RubyInteger;
|
24
|
-
import org.jruby.RubyFixnum;
|
25
|
-
import org.jruby.RubyFloat;
|
26
|
-
import org.jruby.RubyString;
|
27
|
-
import org.jruby.RubySymbol;
|
28
|
-
import org.jruby.RubyArray;
|
29
|
-
import org.jruby.RubyHash;
|
30
|
-
import org.jruby.runtime.builtin.IRubyObject;
|
31
|
-
import org.jruby.runtime.ThreadContext;
|
32
|
-
|
33
|
-
import org.jcodings.Encoding;
|
34
|
-
|
35
|
-
|
36
|
-
public class RubyObjectUnpacker {
|
37
|
-
private final MessagePack msgPack;
|
38
|
-
|
39
|
-
public RubyObjectUnpacker(MessagePack msgPack) {
|
40
|
-
this.msgPack = msgPack;
|
41
|
-
}
|
42
|
-
|
43
|
-
public static class CompiledOptions {
|
44
|
-
public final boolean symbolizeKeys;
|
45
|
-
public final Encoding encoding;
|
46
|
-
|
47
|
-
public CompiledOptions() {
|
48
|
-
this(null);
|
49
|
-
}
|
50
|
-
|
51
|
-
public CompiledOptions(RubyHash options) {
|
52
|
-
if (options == null) {
|
53
|
-
symbolizeKeys = false;
|
54
|
-
encoding = null;
|
55
|
-
} else {
|
56
|
-
Ruby runtime = options.getRuntime();
|
57
|
-
ThreadContext ctx = runtime.getCurrentContext();
|
58
|
-
RubySymbol key = runtime.newSymbol("symbolize_keys");
|
59
|
-
IRubyObject value = options.fastARef(key);
|
60
|
-
symbolizeKeys = value != null && value.isTrue();
|
61
|
-
IRubyObject rubyEncoding = options.fastARef(runtime.newSymbol("encoding"));
|
62
|
-
encoding = runtime.getEncodingService().getEncodingFromObject(rubyEncoding);
|
63
|
-
}
|
64
|
-
}
|
65
|
-
}
|
66
|
-
|
67
|
-
public IRubyObject unpack(RubyString str, RubyHash options) throws IOException {
|
68
|
-
return unpack(str.getRuntime(), str.getBytes(), new CompiledOptions(options));
|
69
|
-
}
|
70
|
-
|
71
|
-
public IRubyObject unpack(Ruby runtime, byte[] data, RubyHash options) throws IOException {
|
72
|
-
return unpack(runtime, data, new CompiledOptions(options));
|
73
|
-
}
|
74
|
-
|
75
|
-
public IRubyObject unpack(Ruby runtime, byte[] data, CompiledOptions options) throws IOException {
|
76
|
-
MessagePackBufferUnpacker unpacker = new MessagePackBufferUnpacker(msgPack);
|
77
|
-
unpacker.wrap(data);
|
78
|
-
return valueToRubyObject(runtime, unpacker.readValue(), options);
|
79
|
-
}
|
80
|
-
|
81
|
-
IRubyObject valueToRubyObject(Ruby runtime, Value value, RubyHash options) throws IOException {
|
82
|
-
return valueToRubyObject(runtime, value, new CompiledOptions(options));
|
83
|
-
}
|
84
|
-
|
85
|
-
IRubyObject valueToRubyObject(Ruby runtime, Value value, CompiledOptions options) {
|
86
|
-
switch (value.getType()) {
|
87
|
-
case NIL:
|
88
|
-
return runtime.getNil();
|
89
|
-
case BOOLEAN:
|
90
|
-
return convert(runtime, value.asBooleanValue());
|
91
|
-
case INTEGER:
|
92
|
-
return convert(runtime, value.asIntegerValue());
|
93
|
-
case FLOAT:
|
94
|
-
return convert(runtime, value.asFloatValue());
|
95
|
-
case ARRAY:
|
96
|
-
return convert(runtime, value.asArrayValue(), options);
|
97
|
-
case MAP:
|
98
|
-
return convert(runtime, value.asMapValue(), options);
|
99
|
-
case RAW:
|
100
|
-
return convert(runtime, value.asRawValue(), options);
|
101
|
-
default:
|
102
|
-
throw runtime.newArgumentError(String.format("Unexpected value: %s", value.toString()));
|
103
|
-
}
|
104
|
-
}
|
105
|
-
|
106
|
-
private IRubyObject convert(Ruby runtime, BooleanValue value) {
|
107
|
-
return RubyBoolean.newBoolean(runtime, value.asBooleanValue().getBoolean());
|
108
|
-
}
|
109
|
-
|
110
|
-
private IRubyObject convert(Ruby runtime, IntegerValue value) {
|
111
|
-
// TODO: is there any way of checking for bignums up front?
|
112
|
-
IntegerValue iv = value.asIntegerValue();
|
113
|
-
try {
|
114
|
-
return RubyFixnum.newFixnum(runtime, iv.getLong());
|
115
|
-
} catch (MessageTypeException mte) {
|
116
|
-
return RubyBignum.newBignum(runtime, iv.getBigInteger());
|
117
|
-
}
|
118
|
-
}
|
119
|
-
|
120
|
-
private IRubyObject convert(Ruby runtime, FloatValue value) {
|
121
|
-
return RubyFloat.newFloat(runtime, value.asFloatValue().getDouble());
|
122
|
-
}
|
123
|
-
|
124
|
-
private IRubyObject convert(Ruby runtime, ArrayValue value, CompiledOptions options) {
|
125
|
-
Value[] elements = value.asArrayValue().getElementArray();
|
126
|
-
int elementCount = elements.length;
|
127
|
-
IRubyObject[] rubyObjects = new IRubyObject[elementCount];
|
128
|
-
for (int i = 0; i < elementCount; i++) {
|
129
|
-
rubyObjects[i] = valueToRubyObject(runtime, elements[i], options);
|
130
|
-
}
|
131
|
-
return RubyArray.newArray(runtime, rubyObjects);
|
132
|
-
}
|
133
|
-
|
134
|
-
private IRubyObject convert(Ruby runtime, MapValue value, CompiledOptions options) {
|
135
|
-
Value[] keysAndValues = value.asMapValue().getKeyValueArray();
|
136
|
-
int kvCount = keysAndValues.length;
|
137
|
-
RubyHash hash = RubyHash.newHash(runtime);
|
138
|
-
for (int i = 0; i < kvCount; i += 2) {
|
139
|
-
Value k = keysAndValues[i];
|
140
|
-
Value v = keysAndValues[i + 1];
|
141
|
-
IRubyObject kk = valueToRubyObject(runtime, k, options);
|
142
|
-
IRubyObject vv = valueToRubyObject(runtime, v, options);
|
143
|
-
if (options.symbolizeKeys) {
|
144
|
-
kk = runtime.newSymbol(kk.asString().getByteList());
|
145
|
-
}
|
146
|
-
hash.put(kk, vv);
|
147
|
-
}
|
148
|
-
return hash;
|
149
|
-
}
|
150
|
-
|
151
|
-
private IRubyObject convert(Ruby runtime, RawValue value, CompiledOptions options) {
|
152
|
-
RubyString string = RubyString.newString(runtime, value.asRawValue().getByteArray());
|
153
|
-
if (options.encoding != null) {
|
154
|
-
string.setEncoding(options.encoding);
|
155
|
-
}
|
156
|
-
return string;
|
157
|
-
}
|
158
|
-
}
|
data/msgpack-jruby.gemspec
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
$:.push File.expand_path('../lib', __FILE__)
|
4
|
-
|
5
|
-
require 'msgpack/version'
|
6
|
-
|
7
|
-
|
8
|
-
Gem::Specification.new do |s|
|
9
|
-
s.name = 'msgpack-jruby'
|
10
|
-
s.version = MessagePack::VERSION
|
11
|
-
s.platform = 'java'
|
12
|
-
s.authors = ['Theo Hultberg']
|
13
|
-
s.email = ['theo@iconara.net']
|
14
|
-
s.homepage = 'http://github.com/iconara/msgpack-jruby'
|
15
|
-
s.summary = %q{MessagePack implementation for JRuby}
|
16
|
-
s.description = %q{JRuby compatible MessagePack implementation that does not use FFI}
|
17
|
-
|
18
|
-
s.rubyforge_project = 'msgpack-jruby'
|
19
|
-
|
20
|
-
s.files = `git ls-files`.split("\n")
|
21
|
-
# s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
-
# s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
-
s.require_paths = %w(lib)
|
24
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
if RUBY_PLATFORM.include?('java')
|
4
|
-
# JRuby should use this library, MRI should use the standard gem
|
5
|
-
$: << File.expand_path('../../../lib', __FILE__)
|
6
|
-
end
|
7
|
-
|
8
|
-
require 'viiite'
|
9
|
-
require 'msgpack'
|
10
|
-
require 'json'
|
11
|
-
require 'bson'
|
12
|
-
|
13
|
-
if RUBY_PLATFORM.include?('java')
|
14
|
-
BSON_IMPL = BSON::BSON_JAVA
|
15
|
-
else
|
16
|
-
BSON_IMPL = BSON::BSON_C
|
17
|
-
end
|
18
|
-
|
19
|
-
OBJECT_STRUCTURE = {'x' => ['y', 34, 2**30 + 3, 2.1223423423356, {'hello' => 'world', '5' => [63, 'asjdl']}]}
|
20
|
-
ENCODED_MSGPACK = "\x81\xA1x\x95\xA1y\"\xCE@\x00\x00\x03\xCB@\x00\xFA\x8E\x9F9\xFA\xC1\x82\xA5hello\xA5world\xA15\x92?\xA5asjdl"
|
21
|
-
ENCODED_BSON = "d\x00\x00\x00\x04x\x00\\\x00\x00\x00\x020\x00\x02\x00\x00\x00y\x00\x101\x00\"\x00\x00\x00\x102\x00\x03\x00\x00@\x013\x00\xC1\xFA9\x9F\x8E\xFA\x00@\x034\x002\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x045\x00\x19\x00\x00\x00\x100\x00?\x00\x00\x00\x021\x00\x06\x00\x00\x00asjdl\x00\x00\x00\x00\x00"
|
22
|
-
ENCODED_JSON = '{"x":["y",34,1073741827,2.1223423423356,{"hello":"world","5":[63,"asjdl"]}]}'
|
23
|
-
ITERATIONS = 1_00_000
|
24
|
-
IMPLEMENTATIONS = ENV.fetch('IMPLEMENTATIONS', 'json,bson,msgpack').split(',').map(&:to_sym)
|
25
|
-
|
26
|
-
Viiite.bm do |b|
|
27
|
-
b.variation_point :ruby, Viiite.which_ruby
|
28
|
-
|
29
|
-
IMPLEMENTATIONS.each do |lib|
|
30
|
-
b.variation_point :lib, lib
|
31
|
-
|
32
|
-
|
33
|
-
b.report(:pack) do
|
34
|
-
ITERATIONS.times do
|
35
|
-
case lib
|
36
|
-
when :msgpack then MessagePack.pack(OBJECT_STRUCTURE)
|
37
|
-
when :bson then BSON_IMPL.serialize(OBJECT_STRUCTURE).to_s
|
38
|
-
when :json then OBJECT_STRUCTURE.to_json
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
b.report(:unpack) do
|
44
|
-
ITERATIONS.times do
|
45
|
-
case lib
|
46
|
-
when :msgpack then MessagePack.unpack(ENCODED_MSGPACK)
|
47
|
-
when :bson then BSON_IMPL.deserialize(ENCODED_BSON)
|
48
|
-
when :json then JSON.parse(ENCODED_JSON)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
b.report(:pack_unpack) do
|
54
|
-
ITERATIONS.times do
|
55
|
-
case lib
|
56
|
-
when :msgpack then MessagePack.unpack(MessagePack.pack(OBJECT_STRUCTURE))
|
57
|
-
when :bson then BSON_IMPL.deserialize(BSON_IMPL.serialize(OBJECT_STRUCTURE).to_s)
|
58
|
-
when :json then JSON.parse(OBJECT_STRUCTURE.to_json)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
b.report(:unpack_pack) do
|
64
|
-
ITERATIONS.times do
|
65
|
-
case lib
|
66
|
-
when :msgpack then MessagePack.pack(MessagePack.unpack(ENCODED_MSGPACK))
|
67
|
-
when :bson then BSON_IMPL.serialize(BSON_IMPL.deserialize(ENCODED_BSON)).to_s
|
68
|
-
when :json then OBJECT_STRUCTURE.to_json(JSON.parse(ENCODED_JSON))
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
$: << File.expand_path('../../../lib', __FILE__)
|
4
|
-
|
5
|
-
require 'viiite'
|
6
|
-
require 'msgpack'
|
7
|
-
|
8
|
-
|
9
|
-
iterations = 10_000
|
10
|
-
data = MessagePack.pack(:hello => 'world', :nested => ['structure', {:value => 42}])
|
11
|
-
|
12
|
-
Viiite.bm do |b|
|
13
|
-
b.report(:strings) do
|
14
|
-
iterations.times do
|
15
|
-
MessagePack.unpack(data)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
b.report(:symbols) do
|
20
|
-
options = {:symbolize_keys => true}
|
21
|
-
iterations.times do
|
22
|
-
MessagePack.unpack(data, options)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,254 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
|
3
|
-
require 'stringio'
|
4
|
-
require 'tempfile'
|
5
|
-
require 'spec_helper'
|
6
|
-
|
7
|
-
|
8
|
-
describe ::MessagePack::Unpacker do
|
9
|
-
subject do
|
10
|
-
described_class.new
|
11
|
-
end
|
12
|
-
|
13
|
-
let :buffer1 do
|
14
|
-
MessagePack.pack(:foo => 'bar')
|
15
|
-
end
|
16
|
-
|
17
|
-
let :buffer2 do
|
18
|
-
MessagePack.pack(:hello => {:world => [1, 2, 3]})
|
19
|
-
end
|
20
|
-
|
21
|
-
let :buffer3 do
|
22
|
-
MessagePack.pack(:x => 'y')
|
23
|
-
end
|
24
|
-
|
25
|
-
describe '#execute/#execute_limit/#finished?' do
|
26
|
-
let :buffer do
|
27
|
-
buffer1 + buffer2 + buffer3
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'extracts an object from the buffer' do
|
31
|
-
subject.execute(buffer, 0)
|
32
|
-
subject.data.should == {'foo' => 'bar'}
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'extracts an object from the buffer, starting at an offset' do
|
36
|
-
subject.execute(buffer, buffer1.length)
|
37
|
-
subject.data.should == {'hello' => {'world' => [1, 2, 3]}}
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'extracts an object from the buffer, starting at an offset reading bytes up to a limit' do
|
41
|
-
subject.execute_limit(buffer, buffer1.length, buffer2.length)
|
42
|
-
subject.data.should == {'hello' => {'world' => [1, 2, 3]}}
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'extracts nothing if the limit cuts an object in half' do
|
46
|
-
subject.execute_limit(buffer, buffer1.length, 3)
|
47
|
-
subject.data.should be_nil
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'returns the offset where the object ended' do
|
51
|
-
subject.execute(buffer, 0).should == buffer1.length
|
52
|
-
subject.execute(buffer, buffer1.length).should == buffer1.length + buffer2.length
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'is finished if #data returns an object' do
|
56
|
-
subject.execute_limit(buffer, buffer1.length, buffer2.length)
|
57
|
-
subject.should be_finished
|
58
|
-
|
59
|
-
subject.execute_limit(buffer, buffer1.length, 3)
|
60
|
-
subject.should_not be_finished
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
describe '#each' do
|
65
|
-
context 'with a buffer' do
|
66
|
-
it 'yields each object in the buffer' do
|
67
|
-
objects = []
|
68
|
-
subject.feed(buffer1)
|
69
|
-
subject.feed(buffer2)
|
70
|
-
subject.feed(buffer3)
|
71
|
-
subject.each do |obj|
|
72
|
-
objects << obj
|
73
|
-
end
|
74
|
-
objects.should == [{'foo' => 'bar'}, {'hello' => {'world' => [1, 2, 3]}}, {'x' => 'y'}]
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'returns an enumerator when no block is given' do
|
78
|
-
subject.feed(buffer1)
|
79
|
-
subject.feed(buffer2)
|
80
|
-
subject.feed(buffer3)
|
81
|
-
enum = subject.each
|
82
|
-
enum.map { |obj| obj.keys.first }.should == %w[foo hello x]
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
context 'with a StringIO stream' do
|
87
|
-
it 'yields each object in the stream' do
|
88
|
-
objects = []
|
89
|
-
subject.stream = StringIO.new(buffer1 + buffer2 + buffer3)
|
90
|
-
subject.each do |obj|
|
91
|
-
objects << obj
|
92
|
-
end
|
93
|
-
objects.should == [{'foo' => 'bar'}, {'hello' => {'world' => [1, 2, 3]}}, {'x' => 'y'}]
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
context 'with a File stream' do
|
98
|
-
it 'yields each object in the stream' do
|
99
|
-
objects = []
|
100
|
-
file = Tempfile.new('msgpack')
|
101
|
-
file.write(buffer1)
|
102
|
-
file.write(buffer2)
|
103
|
-
file.write(buffer3)
|
104
|
-
file.open
|
105
|
-
subject.stream = file
|
106
|
-
subject.each do |obj|
|
107
|
-
objects << obj
|
108
|
-
end
|
109
|
-
objects.should == [{'foo' => 'bar'}, {'hello' => {'world' => [1, 2, 3]}}, {'x' => 'y'}]
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
context 'with a stream passed to the constructor' do
|
114
|
-
it 'yields each object in the stream' do
|
115
|
-
objects = []
|
116
|
-
unpacker = described_class.new(StringIO.new(buffer1 + buffer2 + buffer3))
|
117
|
-
unpacker.each do |obj|
|
118
|
-
objects << obj
|
119
|
-
end
|
120
|
-
objects.should == [{'foo' => 'bar'}, {'hello' => {'world' => [1, 2, 3]}}, {'x' => 'y'}]
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
describe '#feed_each' do
|
126
|
-
it 'feeds the buffer then runs #each' do
|
127
|
-
objects = []
|
128
|
-
subject.feed_each(buffer1 + buffer2 + buffer3) do |obj|
|
129
|
-
objects << obj
|
130
|
-
end
|
131
|
-
objects.should == [{'foo' => 'bar'}, {'hello' => {'world' => [1, 2, 3]}}, {'x' => 'y'}]
|
132
|
-
end
|
133
|
-
|
134
|
-
it 'handles chunked data' do
|
135
|
-
objects = []
|
136
|
-
buffer = buffer1 + buffer2 + buffer3
|
137
|
-
buffer.chars.each do |ch|
|
138
|
-
subject.feed_each(ch) do |obj|
|
139
|
-
objects << obj
|
140
|
-
end
|
141
|
-
end
|
142
|
-
objects.should == [{'foo' => 'bar'}, {'hello' => {'world' => [1, 2, 3]}}, {'x' => 'y'}]
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
describe '#fill' do
|
147
|
-
it 'is a no-op' do
|
148
|
-
subject.stream = StringIO.new(buffer1 + buffer2 + buffer3)
|
149
|
-
subject.fill
|
150
|
-
subject.each { |obj| }
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
describe '#reset' do
|
155
|
-
context 'with a buffer' do
|
156
|
-
it 'is unclear what it is supposed to do'
|
157
|
-
end
|
158
|
-
|
159
|
-
context 'with a stream' do
|
160
|
-
it 'is unclear what it is supposed to do'
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
context 'regressions' do
|
165
|
-
it 'handles massive arrays (issue #2)' do
|
166
|
-
array = ['foo'] * 10_000
|
167
|
-
MessagePack.unpack(MessagePack.pack(array)).should have(10_000).items
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
context 'extensions' do
|
172
|
-
context 'symbolized keys' do
|
173
|
-
let :buffer do
|
174
|
-
MessagePack.pack({'hello' => 'world', 'nested' => ['object', {'structure' => true}]})
|
175
|
-
end
|
176
|
-
|
177
|
-
let :unpacker do
|
178
|
-
described_class.new(:symbolize_keys => true)
|
179
|
-
end
|
180
|
-
|
181
|
-
it 'can symbolize keys when using #execute' do
|
182
|
-
unpacker.execute(buffer, 0)
|
183
|
-
unpacker.data.should == {:hello => 'world', :nested => ['object', {:structure => true}]}
|
184
|
-
end
|
185
|
-
|
186
|
-
it 'can symbolize keys when using #each' do
|
187
|
-
objs = []
|
188
|
-
unpacker.feed(buffer)
|
189
|
-
unpacker.each do |obj|
|
190
|
-
objs << obj
|
191
|
-
end
|
192
|
-
objs.should == [{:hello => 'world', :nested => ['object', {:structure => true}]}]
|
193
|
-
end
|
194
|
-
|
195
|
-
it 'can symbolize keys when using #feed_each' do
|
196
|
-
objs = []
|
197
|
-
unpacker.feed_each(buffer) do |obj|
|
198
|
-
objs << obj
|
199
|
-
end
|
200
|
-
objs.should == [{:hello => 'world', :nested => ['object', {:structure => true}]}]
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
context 'encoding', :encodings do
|
205
|
-
def flatten(struct, results = [])
|
206
|
-
case struct
|
207
|
-
when Array
|
208
|
-
struct.each { |v| flatten(v, results) }
|
209
|
-
when Hash
|
210
|
-
struct.each { |k, v| flatten(v, flatten(k, results)) }
|
211
|
-
else
|
212
|
-
results << struct
|
213
|
-
end
|
214
|
-
results
|
215
|
-
end
|
216
|
-
|
217
|
-
let :buffer do
|
218
|
-
MessagePack.pack({'hello' => 'world', 'nested' => ['object', {'structure' => true}]})
|
219
|
-
end
|
220
|
-
|
221
|
-
let :unpacker do
|
222
|
-
described_class.new(:encoding => 'UTF-8')
|
223
|
-
end
|
224
|
-
|
225
|
-
it 'can symbolize keys when using #execute' do
|
226
|
-
unpacker.execute(buffer, 0)
|
227
|
-
strings = flatten(unpacker.data).grep(String)
|
228
|
-
strings.should == %w[hello world nested object structure]
|
229
|
-
strings.map(&:encoding).uniq.should == [Encoding::UTF_8]
|
230
|
-
end
|
231
|
-
|
232
|
-
it 'can symbolize keys when using #each' do
|
233
|
-
objs = []
|
234
|
-
unpacker.feed(buffer)
|
235
|
-
unpacker.each do |obj|
|
236
|
-
objs << obj
|
237
|
-
end
|
238
|
-
strings = flatten(objs).grep(String)
|
239
|
-
strings.should == %w[hello world nested object structure]
|
240
|
-
strings.map(&:encoding).uniq.should == [Encoding::UTF_8]
|
241
|
-
end
|
242
|
-
|
243
|
-
it 'can symbolize keys when using #feed_each' do
|
244
|
-
objs = []
|
245
|
-
unpacker.feed_each(buffer) do |obj|
|
246
|
-
objs << obj
|
247
|
-
end
|
248
|
-
strings = flatten(objs).grep(String)
|
249
|
-
strings.should == %w[hello world nested object structure]
|
250
|
-
strings.map(&:encoding).uniq.should == [Encoding::UTF_8]
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
|
-
end
|
data/spec/msgpack_spec.rb
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
# encoding: ascii-8bit
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
|
6
|
-
describe MessagePack do
|
7
|
-
tests = {
|
8
|
-
'constant values' => [
|
9
|
-
['true', true, "\xC3"],
|
10
|
-
['false', false, "\xC2"],
|
11
|
-
['nil', nil, "\xC0"]
|
12
|
-
],
|
13
|
-
'numbers' => [
|
14
|
-
['zero', 0, "\x00"],
|
15
|
-
['127', 127, "\x7F"],
|
16
|
-
['128', 128, "\xCC\x80"],
|
17
|
-
['256', 256, "\xCD\x01\x00"],
|
18
|
-
['-1', -1, "\xFF"],
|
19
|
-
['-33', -33, "\xD0\xDF"],
|
20
|
-
['-129', -129, "\xD1\xFF\x7F"],
|
21
|
-
['small integers', 42, "*"],
|
22
|
-
['medium integers', 333, "\xCD\x01M"],
|
23
|
-
['large integers', 2**31 - 1, "\xCE\x7F\xFF\xFF\xFF"],
|
24
|
-
['huge integers', 2**64 - 1, "\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"],
|
25
|
-
['negative integers', -1, "\xFF"],
|
26
|
-
['1.0', 1.0, "\xcb\x3f\xf0\x00\x00\x00\x00\x00\x00"],
|
27
|
-
['small floats', 3.14, "\xCB@\t\x1E\xB8Q\xEB\x85\x1F"],
|
28
|
-
['big floats', Math::PI * 1_000_000_000_000_000_000, "\xCBC\xC5\xCC\x96\xEF\xD1\x19%"],
|
29
|
-
['negative floats', -2.1, "\xCB\xC0\x00\xCC\xCC\xCC\xCC\xCC\xCD"]
|
30
|
-
],
|
31
|
-
'strings' => [
|
32
|
-
['strings', 'hello world', "\xABhello world"],
|
33
|
-
['empty strings', '', "\xA0"]
|
34
|
-
],
|
35
|
-
'arrays' => [
|
36
|
-
['empty arrays', [], "\x90"],
|
37
|
-
['arrays with strings', ["hello", "world"], "\x92\xA5hello\xA5world"],
|
38
|
-
['arrays with mixed values', ["hello", "world", 42], "\x93\xA5hello\xA5world*"],
|
39
|
-
['arrays of arrays', [[[[1, 2], 3], 4]], "\x91\x92\x92\x92\x01\x02\x03\x04"],
|
40
|
-
['empty arrays', [], "\x90"]
|
41
|
-
],
|
42
|
-
'hashes' => [
|
43
|
-
['empty hashes', {}, "\x80"],
|
44
|
-
['hashes', {'foo' => 'bar'}, "\x81\xA3foo\xA3bar"],
|
45
|
-
['hashes with mixed keys and values', {'foo' => 'bar', 3 => 'three', 'four' => 4, 'x' => ['y'], 'a' => 'b'}, "\x85\xA3foo\xA3bar\x03\xA5three\xA4four\x04\xA1x\x91\xA1y\xA1a\xA1b"],
|
46
|
-
['hashes of hashes', {{'x' => {'y' => 'z'}} => 's'}, "\x81\x81\xA1x\x81\xA1y\xA1z\xA1s"],
|
47
|
-
['hashes with nils', {'foo' => nil}, "\x81\xA3foo\xC0"]
|
48
|
-
]
|
49
|
-
}
|
50
|
-
|
51
|
-
tests.each do |ctx, its|
|
52
|
-
context("with #{ctx}") do
|
53
|
-
its.each do |desc, unpacked, packed|
|
54
|
-
it("encodes #{desc}") do
|
55
|
-
MessagePack.pack(unpacked).should == packed
|
56
|
-
end
|
57
|
-
|
58
|
-
it "decodes #{desc}" do
|
59
|
-
MessagePack.unpack(packed).should == unpacked
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
context 'with symbols' do
|
66
|
-
it 'encodes symbols as strings' do
|
67
|
-
MessagePack.pack(:symbol).should == "\xA6symbol"
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'with other things' do
|
72
|
-
it 'raises an error on #pack with an unsupported type' do
|
73
|
-
expect { MessagePack.pack(self) }.to raise_error(ArgumentError, /^Cannot pack type:/)
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'rasies an error on #unpack with garbage' do
|
77
|
-
pending
|
78
|
-
expect { MessagePack.unpack('asdka;sd') }.to raise_error(MessagePack::UnpackError)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
context 'extensions' do
|
83
|
-
it 'can unpack hashes with symbolized keys' do
|
84
|
-
packed = MessagePack.pack({'hello' => 'world', 'nested' => ['object', {'structure' => true}]})
|
85
|
-
unpacked = MessagePack.unpack(packed, :symbolize_keys => true)
|
86
|
-
unpacked.should == {:hello => 'world', :nested => ['object', {:structure => true}]}
|
87
|
-
end
|
88
|
-
|
89
|
-
it 'can unpack strings with a specified encoding', :encodings do
|
90
|
-
packed = MessagePack.pack({'hello' => 'world'})
|
91
|
-
unpacked = MessagePack.unpack(packed, :encoding => Encoding::UTF_8)
|
92
|
-
unpacked['hello'].encoding.should == Encoding::UTF_8
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|