msgpack-jruby 1.1.3-java → 1.2.0-java

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.
data/Rakefile CHANGED
@@ -31,16 +31,17 @@ end
31
31
  namespace :benchmark do
32
32
  BENCHMARK_RUBIES = ['1.9.2-p0', 'jruby-1.6.5', 'jruby-head']
33
33
  BENCHMARK_GEMSET = 'msgpack-jruby-benchmarking'
34
+ BENCHMARK_FILE = 'spec/benchmarks/shootout_bm.rb'
34
35
 
35
36
  task :run do
36
37
  rubies = BENCHMARK_RUBIES.map { |rb| "#{rb}@#{BENCHMARK_GEMSET}" }
37
- cmd = %(rvm #{rubies.join(',')} exec viiite run spec/benchmark.rb | tee benchmark | viiite report --hierarchy --regroup=bench,lib,ruby)
38
+ cmd = %(rvm #{rubies.join(',')} exec viiite run #{BENCHMARK_FILE} | tee benchmark | viiite report --hierarchy --regroup=bench,lib,ruby)
38
39
  puts cmd
39
40
  system cmd
40
41
  end
41
42
 
42
43
  task :quick do
43
- cmd = %(IMPLEMENTATIONS=msgpack viiite run spec/benchmark.rb | viiite report --hierarchy --regroup=bench)
44
+ cmd = %(IMPLEMENTATIONS=msgpack viiite run #{BENCHMARK_FILE} | viiite report --hierarchy --regroup=bench)
44
45
  puts cmd
45
46
  system cmd
46
47
  end
@@ -10,6 +10,7 @@ import org.jruby.RubyModule;
10
10
  import org.jruby.RubyClass;
11
11
  import org.jruby.RubyString;
12
12
  import org.jruby.RubyObject;
13
+ import org.jruby.RubyHash;
13
14
  import org.jruby.RubyIO;
14
15
  import org.jruby.RubyStringIO;
15
16
  import org.jruby.RubyNumeric;
@@ -54,18 +55,19 @@ public class MessagePackLibrary implements Library {
54
55
  @JRubyModule(name = "MessagePack")
55
56
  public static class MessagePackModule {
56
57
  private static MessagePack msgPack = new MessagePack();
58
+ private static RubyObjectPacker packer = new RubyObjectPacker(msgPack);
57
59
  private static RubyObjectUnpacker unpacker = new RubyObjectUnpacker(msgPack);
58
60
 
59
61
  @JRubyMethod(module = true, required = 1)
60
62
  public static IRubyObject pack(ThreadContext ctx, IRubyObject recv, IRubyObject obj) throws IOException {
61
- BufferPacker bufferedPacker = msgPack.createBufferPacker();
62
- Packer packer = new RubyObjectPacker(msgPack, bufferedPacker).write(obj);
63
- return RubyString.newString(ctx.getRuntime(), bufferedPacker.toByteArray());
63
+ return packer.pack(obj);
64
64
  }
65
65
 
66
- @JRubyMethod(module = true, required = 1)
67
- public static IRubyObject unpack(ThreadContext ctx, IRubyObject recv, IRubyObject obj) throws IOException {
68
- return unpacker.unpack(obj.asString());
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);
69
71
  }
70
72
  }
71
73
 
@@ -89,6 +91,7 @@ public class MessagePackLibrary implements Library {
89
91
  private MessagePackUnpacker streamUnpacker;
90
92
  private IRubyObject stream;
91
93
  private IRubyObject data;
94
+ private RubyHash options;
92
95
 
93
96
  public Unpacker(Ruby runtime, RubyClass type, MessagePack msgPack) {
94
97
  super(runtime, type);
@@ -100,10 +103,17 @@ public class MessagePackLibrary implements Library {
100
103
  this.data = null;
101
104
  }
102
105
 
103
- @JRubyMethod(name = "initialize", optional = 1, visibility = PRIVATE)
106
+ @JRubyMethod(name = "initialize", optional = 2, visibility = PRIVATE)
104
107
  public IRubyObject initialize(ThreadContext ctx, IRubyObject[] args) {
105
- if (args.length > 0) {
108
+ if (args.length == 0) {
109
+ options = null;
110
+ } else if (args.length == 1 && args[0] instanceof RubyHash) {
111
+ options = (RubyHash) args[0];
112
+ } else if (args.length > 0) {
106
113
  setStream(ctx, args[0]);
114
+ if (args.length > 2) {
115
+ options = (RubyHash) args[1];
116
+ }
107
117
  }
108
118
  return this;
109
119
  }
@@ -125,7 +135,7 @@ public class MessagePackLibrary implements Library {
125
135
  byte[] bytes = data.asString().getBytes();
126
136
  MessagePackBufferUnpacker localBufferUnpacker = new MessagePackBufferUnpacker(msgPack, bytes.length);
127
137
  localBufferUnpacker.wrap(bytes, jOffset, jLimit == -1 ? bytes.length - jOffset : jLimit);
128
- this.data = rubyObjectUnpacker.valueToRubyObject(ctx.getRuntime(), localBufferUnpacker.readValue());
138
+ this.data = rubyObjectUnpacker.valueToRubyObject(ctx.getRuntime(), localBufferUnpacker.readValue(), options);
129
139
  return ctx.getRuntime().newFixnum(jOffset + localBufferUnpacker.getReadByteCount());
130
140
  } catch (IOException ioe) {
131
141
  // TODO: how to throw Ruby exceptions?
@@ -177,12 +187,12 @@ public class MessagePackLibrary implements Library {
177
187
  }
178
188
  if (block.isGiven()) {
179
189
  for (Value value : localUnpacker) {
180
- IRubyObject rubyObject = rubyObjectUnpacker.valueToRubyObject(ctx.getRuntime(), value);
190
+ IRubyObject rubyObject = rubyObjectUnpacker.valueToRubyObject(ctx.getRuntime(), value, options);
181
191
  block.yield(ctx, rubyObject);
182
192
  }
183
193
  return ctx.getRuntime().getNil();
184
194
  } else {
185
- return RubyEnumerator.RubyEnumeratorKernel.obj_to_enum(ctx, this, Block.NULL_BLOCK);
195
+ return RubyEnumerator.RubyEnumeratorKernel.obj_to_enum(ctx, this);
186
196
  }
187
197
  }
188
198
 
@@ -4,8 +4,7 @@ package org.msgpack.jruby;
4
4
  import java.io.IOException;
5
5
 
6
6
  import org.msgpack.MessagePack;
7
- import org.msgpack.packer.Packer;
8
- import org.msgpack.packer.MessagePackBufferPacker;
7
+ import org.msgpack.packer.BufferPacker;
9
8
 
10
9
  import org.jruby.RubyObject;
11
10
  import org.jruby.RubyNil;
@@ -21,91 +20,91 @@ import org.jruby.RubyHash;
21
20
  import org.jruby.runtime.builtin.IRubyObject;
22
21
 
23
22
 
24
- public class RubyObjectPacker extends MessagePackBufferPacker {
25
- private final Packer packer;
23
+ public class RubyObjectPacker {
24
+ private final MessagePack msgPack;
26
25
 
27
- public RubyObjectPacker(MessagePack msgPack, Packer packer) {
28
- super(msgPack);
29
- this.packer = packer;
26
+ public RubyObjectPacker(MessagePack msgPack) {
27
+ this.msgPack = msgPack;
30
28
  }
31
29
 
32
- public Packer write(IRubyObject o) throws IOException {
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 {
33
41
  if (o == null || o instanceof RubyNil) {
34
42
  packer.writeNil();
35
- return this;
36
43
  } else if (o instanceof RubyBoolean) {
37
44
  packer.write(((RubyBoolean) o).isTrue());
38
- return this;
39
45
  } else if (o instanceof RubyBignum) {
40
- return write((RubyBignum) o);
46
+ write(packer, (RubyBignum) o);
41
47
  } else if (o instanceof RubyInteger) {
42
- return write((RubyInteger) o);
48
+ write(packer, (RubyInteger) o);
43
49
  } else if (o instanceof RubyFixnum) {
44
- return write((RubyFixnum) o);
50
+ write(packer, (RubyFixnum) o);
45
51
  } else if (o instanceof RubyFloat) {
46
- return write((RubyFloat) o);
52
+ write(packer, (RubyFloat) o);
47
53
  } else if (o instanceof RubyString) {
48
- return write((RubyString) o);
54
+ write(packer, (RubyString) o);
49
55
  } else if (o instanceof RubySymbol) {
50
- return write((RubySymbol) o);
56
+ write(packer, (RubySymbol) o);
51
57
  } else if (o instanceof RubyArray) {
52
- return write((RubyArray) o);
58
+ write(packer, (RubyArray) o);
53
59
  } else if (o instanceof RubyHash) {
54
- return write((RubyHash) o);
60
+ write(packer, (RubyHash) o);
55
61
  } else {
56
62
  throw o.getRuntime().newArgumentError(String.format("Cannot pack type: %s", o.getClass().getName()));
57
63
  }
58
64
  }
59
65
 
60
- public final Packer write(RubyBignum bignum) throws IOException {
66
+ private void write(BufferPacker packer, RubyBignum bignum) throws IOException {
61
67
  packer.write(bignum.getBigIntegerValue());
62
- return this;
63
68
  }
64
69
 
65
- public final Packer write(RubyInteger integer) throws IOException {
70
+ private void write(BufferPacker packer, RubyInteger integer) throws IOException {
66
71
  packer.write(integer.getLongValue());
67
- return this;
68
72
  }
69
73
 
70
- public final Packer write(RubyFixnum fixnum) throws IOException {
74
+ private void write(BufferPacker packer, RubyFixnum fixnum) throws IOException {
71
75
  packer.write(fixnum.getLongValue());
72
- return this;
73
76
  }
74
77
 
75
- public final Packer write(RubyFloat flt) throws IOException {
78
+ private void write(BufferPacker packer, RubyFloat flt) throws IOException {
76
79
  packer.write(flt.getDoubleValue());
77
- return this;
78
80
  }
79
81
 
80
- public final Packer write(RubyString str) throws IOException {
82
+ private void write(BufferPacker packer, RubyString str) throws IOException {
81
83
  packer.write(str.getBytes());
82
- return this;
83
84
  }
84
85
 
85
- public final Packer write(RubySymbol sym) throws IOException {
86
- return write((RubyString) sym.to_s());
86
+ private void write(BufferPacker packer, RubySymbol sym) throws IOException {
87
+ write(packer, (RubyString) sym.to_s());
87
88
  }
88
89
 
89
- public final Packer write(RubyArray array) throws IOException {
90
+ private void write(BufferPacker packer, RubyArray array) throws IOException {
90
91
  int count = array.size();
91
92
  packer.writeArrayBegin(count);
92
93
  for (int i = 0; i < count; i++) {
93
- write((RubyObject) array.entry(i));
94
+ write(packer, (RubyObject) array.entry(i));
94
95
  }
95
96
  packer.writeArrayEnd();
96
- return this;
97
97
  }
98
98
 
99
- public final Packer write(RubyHash hash) throws IOException {
99
+ private void write(BufferPacker packer, RubyHash hash) throws IOException {
100
100
  int count = hash.size();
101
101
  packer.writeMapBegin(count);
102
102
  RubyArray keys = hash.keys();
103
103
  RubyArray values = hash.rb_values();
104
104
  for (int i = 0; i < count; i++) {
105
- write((RubyObject) keys.entry(i));
106
- write((RubyObject) values.entry(i));
105
+ write(packer, (RubyObject) keys.entry(i));
106
+ write(packer, (RubyObject) values.entry(i));
107
107
  }
108
108
  packer.writeMapEnd();
109
- return this;
110
109
  }
111
110
  }
@@ -28,6 +28,7 @@ import org.jruby.RubySymbol;
28
28
  import org.jruby.RubyArray;
29
29
  import org.jruby.RubyHash;
30
30
  import org.jruby.runtime.builtin.IRubyObject;
31
+ import org.jruby.runtime.ThreadContext;
31
32
 
32
33
 
33
34
  public class RubyObjectUnpacker {
@@ -37,17 +38,17 @@ public class RubyObjectUnpacker {
37
38
  this.msgPack = msgPack;
38
39
  }
39
40
 
40
- public IRubyObject unpack(RubyString str) throws IOException {
41
- return unpack(str.getRuntime(), str.getBytes());
41
+ public IRubyObject unpack(RubyString str, RubyHash options) throws IOException {
42
+ return unpack(str.getRuntime(), str.getBytes(), options);
42
43
  }
43
44
 
44
- public IRubyObject unpack(Ruby runtime, byte[] data) throws IOException {
45
+ public IRubyObject unpack(Ruby runtime, byte[] data, RubyHash options) throws IOException {
45
46
  MessagePackBufferUnpacker unpacker = new MessagePackBufferUnpacker(msgPack);
46
47
  unpacker.wrap(data);
47
- return valueToRubyObject(runtime, unpacker.readValue());
48
+ return valueToRubyObject(runtime, unpacker.readValue(), options);
48
49
  }
49
50
 
50
- IRubyObject valueToRubyObject(Ruby runtime, Value value) {
51
+ IRubyObject valueToRubyObject(Ruby runtime, Value value, RubyHash options) {
51
52
  switch (value.getType()) {
52
53
  case NIL:
53
54
  return runtime.getNil();
@@ -58,9 +59,9 @@ public class RubyObjectUnpacker {
58
59
  case FLOAT:
59
60
  return convert(runtime, value.asFloatValue());
60
61
  case ARRAY:
61
- return convert(runtime, value.asArrayValue());
62
+ return convert(runtime, value.asArrayValue(), options);
62
63
  case MAP:
63
- return convert(runtime, value.asMapValue());
64
+ return convert(runtime, value.asMapValue(), options);
64
65
  case RAW:
65
66
  return convert(runtime, value.asRawValue());
66
67
  default:
@@ -86,24 +87,29 @@ public class RubyObjectUnpacker {
86
87
  return RubyFloat.newFloat(runtime, value.asFloatValue().getDouble());
87
88
  }
88
89
 
89
- private IRubyObject convert(Ruby runtime, ArrayValue value) {
90
+ private IRubyObject convert(Ruby runtime, ArrayValue value, RubyHash options) {
90
91
  Value[] elements = value.asArrayValue().getElementArray();
91
92
  int elementCount = elements.length;
92
93
  IRubyObject[] rubyObjects = new IRubyObject[elementCount];
93
94
  for (int i = 0; i < elementCount; i++) {
94
- rubyObjects[i] = valueToRubyObject(runtime, elements[i]);
95
+ rubyObjects[i] = valueToRubyObject(runtime, elements[i], options);
95
96
  }
96
97
  return RubyArray.newArray(runtime, rubyObjects);
97
98
  }
98
99
 
99
- private IRubyObject convert(Ruby runtime, MapValue value) {
100
+ private IRubyObject convert(Ruby runtime, MapValue value, RubyHash options) {
100
101
  Value[] keysAndValues = value.asMapValue().getKeyValueArray();
101
102
  int kvCount = keysAndValues.length;
102
103
  RubyHash hash = RubyHash.newHash(runtime);
103
104
  for (int i = 0; i < kvCount; i += 2) {
104
105
  Value k = keysAndValues[i];
105
106
  Value v = keysAndValues[i + 1];
106
- hash.put(valueToRubyObject(runtime, k), valueToRubyObject(runtime, v));
107
+ IRubyObject kk = valueToRubyObject(runtime, k, options);
108
+ IRubyObject vv = valueToRubyObject(runtime, v, options);
109
+ if (symbolizeKeysEnabled(options)) {
110
+ kk = runtime.newSymbol(kk.asString().getByteList());
111
+ }
112
+ hash.put(kk, vv);
107
113
  }
108
114
  return hash;
109
115
  }
@@ -111,4 +117,20 @@ public class RubyObjectUnpacker {
111
117
  private IRubyObject convert(Ruby runtime, RawValue value) {
112
118
  return RubyString.newString(runtime, value.asRawValue().getByteArray());
113
119
  }
120
+
121
+ private boolean symbolizeKeysEnabled(RubyHash options) {
122
+ if (options == null) {
123
+ return false;
124
+ } else {
125
+ Ruby runtime = options.getRuntime();
126
+ ThreadContext ctx = runtime.getCurrentContext();
127
+ RubySymbol key = runtime.newSymbol("symbolize_keys");
128
+ IRubyObject value = options.fastARef(key);
129
+ if (value == null) {
130
+ return false;
131
+ } else {
132
+ return value.isTrue();
133
+ }
134
+ }
135
+ }
114
136
  }
Binary file
@@ -1,3 +1,3 @@
1
1
  module MessagePack
2
- VERSION = '1.1.3'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  if RUBY_PLATFORM.include?('java')
4
4
  # JRuby should use this library, MRI should use the standard gem
5
- $: << File.expand_path('../../lib', __FILE__)
5
+ $: << File.expand_path('../../../lib', __FILE__)
6
6
  end
7
7
 
8
8
  require 'viiite'
@@ -0,0 +1,25 @@
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
@@ -156,4 +156,38 @@ describe ::MessagePack::Unpacker do
156
156
  MessagePack.unpack(MessagePack.pack(array)).should have(10_000).items
157
157
  end
158
158
  end
159
+
160
+ context 'extensions' do
161
+ context 'symbolized keys' do
162
+ let :buffer do
163
+ MessagePack.pack({'hello' => 'world', 'nested' => ['object', {'structure' => true}]})
164
+ end
165
+
166
+ let :unpacker do
167
+ described_class.new(:symbolize_keys => true)
168
+ end
169
+
170
+ it 'can symbolize keys when using #execute' do
171
+ unpacker.execute(buffer, 0)
172
+ unpacker.data.should == {:hello => 'world', :nested => ['object', {:structure => true}]}
173
+ end
174
+
175
+ it 'can symbolize keys when using #each' do
176
+ objs = []
177
+ unpacker.feed(buffer)
178
+ unpacker.each do |obj|
179
+ objs << obj
180
+ end
181
+ objs.should == [{:hello => 'world', :nested => ['object', {:structure => true}]}]
182
+ end
183
+
184
+ it 'can symbolize keys when using #feed_each' do
185
+ objs = []
186
+ unpacker.feed_each(buffer) do |obj|
187
+ objs << obj
188
+ end
189
+ objs.should == [{:hello => 'world', :nested => ['object', {:structure => true}]}]
190
+ end
191
+ end
192
+ end
159
193
  end
data/spec/msgpack_spec.rb CHANGED
@@ -78,4 +78,12 @@ describe MessagePack do
78
78
  expect { MessagePack.unpack('asdka;sd') }.to raise_error(MessagePack::UnpackError)
79
79
  end
80
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
+ end
81
89
  end
metadata CHANGED
@@ -2,14 +2,14 @@
2
2
  name: msgpack-jruby
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.1.3
5
+ version: 1.2.0
6
6
  platform: java
7
7
  authors:
8
8
  - Theo Hultberg
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-14 00:00:00.000000000Z
12
+ date: 2012-07-29 00:00:00.000000000Z
13
13
  dependencies: []
14
14
  description: JRuby compatible MessagePack implementation that does not use FFI
15
15
  email:
@@ -35,7 +35,8 @@ files:
35
35
  - lib/msgpack.rb
36
36
  - lib/msgpack/version.rb
37
37
  - msgpack-jruby.gemspec
38
- - spec/benchmark.rb
38
+ - spec/benchmarks/shootout_bm.rb
39
+ - spec/benchmarks/symbolize_keys_bm.rb
39
40
  - spec/msgpack/unpacker_spec.rb
40
41
  - spec/msgpack_spec.rb
41
42
  - spec/spec_helper.rb