diff --git a/.gitignore b/.gitignore index 770479e..5fb6938 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ *.gem .bundle pkg/* -/benchmark +/benchmark \ No newline at end of file diff --git a/Rakefile b/Rakefile index 51f8f8b..2f56607 100644 --- a/Rakefile +++ b/Rakefile @@ -4,11 +4,17 @@ require 'bundler' Bundler::GemHelper.install_tasks task :clean do - rm Dir['lib/ext/**/*.class'] + rm Dir['ext/java/**/*.class'] end task :compile do - exec %(javac -source 1.6 -target 1.6 -cp lib/ext/msgpack-0.6.5-SNAPSHOT.jar:$MY_RUBY_HOME/lib/jruby.jar -d lib/ext ext/java/org/msgpack/**/*.java) + classpath = (Dir["lib/ext/*.jar"] + ["#{ENV['MY_RUBY_HOME']}/lib/jruby.jar"]).join(':') + system %(javac -Xlint:-options -source 1.6 -target 1.6 -cp #{classpath} ext/java/*.java ext/java/org/msgpack/jruby/*.java) +end + +task :package => :compile do + class_files = Dir['ext/java/**/*.class'].map { |path| path = path.sub('ext/java/', ''); "-C ext/java '#{path}'" } + system %(jar cf lib/ext/msgpack_jruby.jar #{class_files.join(' ')}) end namespace :benchmark do diff --git a/ext/.gitignore b/ext/.gitignore new file mode 100644 index 0000000..6b468b6 --- /dev/null +++ b/ext/.gitignore @@ -0,0 +1 @@ +*.class diff --git a/ext/java/MsgpackJrubyService.java b/ext/java/MsgpackJrubyService.java new file mode 100644 index 0000000..ca331ec --- /dev/null +++ b/ext/java/MsgpackJrubyService.java @@ -0,0 +1,15 @@ +import java.io.IOException; + +import org.jruby.Ruby; +import org.jruby.runtime.load.BasicLibraryService; + +import org.msgpack.jruby.MessagePackLibrary; + + +public class MsgpackJrubyService implements BasicLibraryService { + public boolean basicLoad(final Ruby runtime) throws IOException { + new MessagePackLibrary().load(runtime, false); + return true; + } +} + diff --git a/ext/java/org/msgpack/jruby/MessagePackLibrary.java b/ext/java/org/msgpack/jruby/MessagePackLibrary.java new file mode 100644 index 0000000..addd0d2 --- /dev/null +++ b/ext/java/org/msgpack/jruby/MessagePackLibrary.java @@ -0,0 +1,68 @@ +package org.msgpack.jruby; + + +import java.io.IOException; + +import org.jruby.Ruby; +import org.jruby.RubyModule; +import org.jruby.RubyClass; +import org.jruby.RubyString; +import org.jruby.runtime.load.Library; +import org.jruby.runtime.callback.Callback; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.runtime.Arity; +import org.jruby.runtime.Block; + +import org.msgpack.MessagePack; +import org.msgpack.packer.BufferPacker; +import org.msgpack.packer.Packer; + + +public class MessagePackLibrary implements Library { + public void load(Ruby runtime, boolean wrap) throws IOException { + MessagePack msgPack = new MessagePack(); + RubyModule msgpackModule = runtime.defineModule("MessagePack"); + msgpackModule.defineModuleFunction("pack", new PackCallback(msgPack)); + msgpackModule.defineModuleFunction("unpack", new UnpackCallback(msgPack)); + } + + private static class PackCallback implements Callback { + private MessagePack msgPack; + + public PackCallback(MessagePack msgPack) { + this.msgPack = msgPack; + } + + public IRubyObject execute(IRubyObject recv, IRubyObject[] args, Block block) { + try { + BufferPacker bufferedPacker = msgPack.createBufferPacker(); + Packer packer = new RubyObjectPacker(msgPack, bufferedPacker).write(args[0]); + return RubyString.newString(recv.getRuntime(), bufferedPacker.toByteArray()); + } catch (IOException ioe) { + // TODO: how to propagate these to the Ruby runtime? + return recv.getRuntime().getNil(); + } + } + + public Arity getArity() { return Arity.ONE_REQUIRED; } + } + + private static class UnpackCallback implements Callback { + private RubyObjectUnpacker unpacker; + + public UnpackCallback(MessagePack msgPack) { + this.unpacker = new RubyObjectUnpacker(msgPack); + } + + public IRubyObject execute(IRubyObject recv, IRubyObject[] args, Block block) { + try { + return unpacker.unpack((RubyString) args[0]); + } catch (IOException ioe) { + // TODO: how to propagate these to the Ruby runtime? + return recv.getRuntime().getNil(); + } + } + + public Arity getArity() { return Arity.ONE_REQUIRED; } + } +} \ No newline at end of file diff --git a/ext/java/org/msgpack/jruby/MessagePackModule.java b/ext/java/org/msgpack/jruby/MessagePackModule.java deleted file mode 100644 index 286851c..0000000 --- a/ext/java/org/msgpack/jruby/MessagePackModule.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.msgpack.jruby; - - -import java.io.IOException; - -import org.msgpack.MessagePack; -import org.msgpack.MessagePack; -import org.msgpack.packer.BufferPacker; - -import org.jruby.Ruby; -import org.jruby.RubyObject; -import org.jruby.RubyString; -import org.jruby.compiler.ir.operands.StandardError; - - -public class MessagePackModule { - private static final MessagePack msgPack = new MessagePack(); - private static final RubyObjectUnpacker unpacker = new RubyObjectUnpacker(msgPack); - - public static RubyString pack(RubyObject o) throws IOException { - BufferPacker bufferedPacker = msgPack.createBufferPacker(); - RubyObjectPacker packer = new RubyObjectPacker(msgPack, bufferedPacker); - packer.write(o); - Ruby runtime = o == null ? Ruby.getGlobalRuntime() : o.getRuntime(); - return RubyString.newString(runtime, bufferedPacker.toByteArray()); - } - - public static RubyObject unpack(RubyString s) throws IOException { - return unpacker.unpack(s); - } - - public static class Unpacker { - public void feed(RubyString s) { } - } - - public static class UnpackError extends StandardError { } -} diff --git a/ext/java/org/msgpack/jruby/RubyObjectPacker.java b/ext/java/org/msgpack/jruby/RubyObjectPacker.java index ca01c84..f3d4711 100644 --- a/ext/java/org/msgpack/jruby/RubyObjectPacker.java +++ b/ext/java/org/msgpack/jruby/RubyObjectPacker.java @@ -18,6 +18,7 @@ import org.jruby.RubySymbol; import org.jruby.RubyArray; import org.jruby.RubyHash; +import org.jruby.runtime.builtin.IRubyObject; public class RubyObjectPacker extends MessagePackBufferPacker { @@ -28,7 +29,7 @@ public RubyObjectPacker(MessagePack msgPack, Packer packer) { this.packer = packer; } - public Packer write(RubyObject o) throws IOException { + public Packer write(IRubyObject o) throws IOException { if (o == null || o instanceof RubyNil) { packer.writeNil(); return this; diff --git a/lib/ext/msgpack_jruby.jar b/lib/ext/msgpack_jruby.jar new file mode 100644 index 0000000..6210543 Binary files /dev/null and b/lib/ext/msgpack_jruby.jar differ diff --git a/lib/ext/org/msgpack/jruby/MessagePackModule$UnpackError.class b/lib/ext/org/msgpack/jruby/MessagePackModule$UnpackError.class deleted file mode 100644 index cc2db05..0000000 Binary files a/lib/ext/org/msgpack/jruby/MessagePackModule$UnpackError.class and /dev/null differ diff --git a/lib/ext/org/msgpack/jruby/MessagePackModule$Unpacker.class b/lib/ext/org/msgpack/jruby/MessagePackModule$Unpacker.class deleted file mode 100644 index 9a3b844..0000000 Binary files a/lib/ext/org/msgpack/jruby/MessagePackModule$Unpacker.class and /dev/null differ diff --git a/lib/ext/org/msgpack/jruby/MessagePackModule.class b/lib/ext/org/msgpack/jruby/MessagePackModule.class deleted file mode 100644 index 09c3386..0000000 Binary files a/lib/ext/org/msgpack/jruby/MessagePackModule.class and /dev/null differ diff --git a/lib/ext/org/msgpack/jruby/RubyObjectPacker.class b/lib/ext/org/msgpack/jruby/RubyObjectPacker.class deleted file mode 100644 index 59b1723..0000000 Binary files a/lib/ext/org/msgpack/jruby/RubyObjectPacker.class and /dev/null differ diff --git a/lib/ext/org/msgpack/jruby/RubyObjectUnpacker$1.class b/lib/ext/org/msgpack/jruby/RubyObjectUnpacker$1.class deleted file mode 100644 index d2b1709..0000000 Binary files a/lib/ext/org/msgpack/jruby/RubyObjectUnpacker$1.class and /dev/null differ diff --git a/lib/ext/org/msgpack/jruby/RubyObjectUnpacker.class b/lib/ext/org/msgpack/jruby/RubyObjectUnpacker.class deleted file mode 100644 index 2e101f2..0000000 Binary files a/lib/ext/org/msgpack/jruby/RubyObjectUnpacker.class and /dev/null differ diff --git a/lib/msgpack.rb b/lib/msgpack.rb index 8b08cb8..15f80a2 100644 --- a/lib/msgpack.rb +++ b/lib/msgpack.rb @@ -1,8 +1,8 @@ # encoding: utf-8 -require 'java' - -$CLASSPATH << File.expand_path('../ext', __FILE__) -Dir[File.expand_path('../ext/*.jar', __FILE__)].each { |path| $CLASSPATH << path } +$: << File.expand_path('../ext', __FILE__) -MessagePack = org.msgpack.jruby.MessagePackModule +require 'java' +require 'javassist-3.15.0-GA' +require 'msgpack-0.6.5-SNAPSHOT' +require 'msgpack_jruby' diff --git a/lib/msgpack/unpacker.rb b/lib/msgpack/unpacker.rb deleted file mode 100644 index 3517866..0000000 --- a/lib/msgpack/unpacker.rb +++ /dev/null @@ -1,32 +0,0 @@ -# encoding: ascii-8bit - -class MessagePack - class Unpacker - def initialize - @unpacker = org.msgpack.Unpacker.new - @type_mapper = org.msgpack.jruby.TypeMapper.new - end - - def feed(bytes) - @unpacker.feed(bytes.to_java_bytes) - end - - def each - while obj = next_object - yield obj - end - end - - private - - def next_object - result = @unpacker.next - if result.finished? - @type_mapper.to_ruby_object(result.data) - else - nil - end - end - end -end - diff --git a/spec/msgpack/unpacker_spec.rb b/spec/msgpack/unpacker_spec.rb deleted file mode 100644 index 80369fa..0000000 --- a/spec/msgpack/unpacker_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -# encoding: ascii-8bit - -require_relative '../spec_helper' - -require 'stringio' - - -describe MessagePack::Unpacker do - context 'with a buffer' do - it 'unpacks objects fed through #feed' do - pending - subject.feed(MessagePack.pack('hello' => 'world') + MessagePack.pack('foo' => 42)) - objects = [] - subject.each do |obj| - objects << obj - end - objects.should == [{'hello' => 'world'}, {'foo' => 42}] - end - end - - context 'with a stream' do - it 'unpacks objects from the stream' do - pending - stream = StringIO.new(MessagePack.pack('hello' => 'world') + MessagePack.pack('foo' => 42)) - objects = [] - described_class.new(stream).each do |obj| - objects << obj - end - objects.should == [{'hello' => 'world'}, {'foo' => 42}] - end - end -end \ No newline at end of file