msgpack 1.5.1 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +55 -0
  3. data/README.md +30 -1
  4. data/ext/java/org/msgpack/jruby/Buffer.java +3 -3
  5. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +11 -20
  6. data/ext/java/org/msgpack/jruby/ExtensionValue.java +1 -1
  7. data/ext/java/org/msgpack/jruby/Factory.java +11 -50
  8. data/ext/java/org/msgpack/jruby/Packer.java +9 -24
  9. data/ext/java/org/msgpack/jruby/Unpacker.java +15 -32
  10. data/ext/msgpack/buffer.c +54 -69
  11. data/ext/msgpack/buffer.h +16 -18
  12. data/ext/msgpack/buffer_class.c +138 -37
  13. data/ext/msgpack/buffer_class.h +1 -0
  14. data/ext/msgpack/compat.h +0 -99
  15. data/ext/msgpack/extconf.rb +25 -39
  16. data/ext/msgpack/factory_class.c +75 -86
  17. data/ext/msgpack/packer.c +12 -39
  18. data/ext/msgpack/packer.h +1 -11
  19. data/ext/msgpack/packer_class.c +73 -99
  20. data/ext/msgpack/packer_class.h +11 -0
  21. data/ext/msgpack/packer_ext_registry.c +31 -28
  22. data/ext/msgpack/packer_ext_registry.h +10 -14
  23. data/ext/msgpack/rbinit.c +1 -1
  24. data/ext/msgpack/rmem.c +3 -4
  25. data/ext/msgpack/sysdep.h +5 -2
  26. data/ext/msgpack/unpacker.c +66 -94
  27. data/ext/msgpack/unpacker.h +13 -12
  28. data/ext/msgpack/unpacker_class.c +64 -80
  29. data/ext/msgpack/unpacker_class.h +11 -0
  30. data/ext/msgpack/unpacker_ext_registry.c +4 -16
  31. data/ext/msgpack/unpacker_ext_registry.h +3 -7
  32. data/lib/msgpack/buffer.rb +9 -0
  33. data/lib/msgpack/factory.rb +90 -63
  34. data/lib/msgpack/packer.rb +10 -1
  35. data/lib/msgpack/unpacker.rb +14 -1
  36. data/lib/msgpack/version.rb +1 -1
  37. data/lib/msgpack.rb +1 -0
  38. data/msgpack.gemspec +7 -3
  39. metadata +33 -56
  40. data/.github/workflows/ci.yaml +0 -57
  41. data/.gitignore +0 -23
  42. data/.rubocop.yml +0 -36
  43. data/Gemfile +0 -9
  44. data/Rakefile +0 -70
  45. data/appveyor.yml +0 -18
  46. data/bench/pack.rb +0 -23
  47. data/bench/pack_log.rb +0 -33
  48. data/bench/pack_log_long.rb +0 -65
  49. data/bench/pack_symbols.rb +0 -28
  50. data/bench/run.sh +0 -14
  51. data/bench/run_long.sh +0 -35
  52. data/bench/run_symbols.sh +0 -26
  53. data/bench/unpack.rb +0 -21
  54. data/bench/unpack_log.rb +0 -34
  55. data/bench/unpack_log_long.rb +0 -67
  56. data/doclib/msgpack/buffer.rb +0 -193
  57. data/doclib/msgpack/core_ext.rb +0 -101
  58. data/doclib/msgpack/error.rb +0 -19
  59. data/doclib/msgpack/extension_value.rb +0 -9
  60. data/doclib/msgpack/factory.rb +0 -145
  61. data/doclib/msgpack/packer.rb +0 -209
  62. data/doclib/msgpack/time.rb +0 -22
  63. data/doclib/msgpack/timestamp.rb +0 -44
  64. data/doclib/msgpack/unpacker.rb +0 -183
  65. data/doclib/msgpack.rb +0 -87
  66. data/msgpack.org.md +0 -46
  67. data/spec/bigint_spec.rb +0 -26
  68. data/spec/cases.json +0 -1
  69. data/spec/cases.msg +0 -0
  70. data/spec/cases_compact.msg +0 -0
  71. data/spec/cases_spec.rb +0 -39
  72. data/spec/cruby/buffer_io_spec.rb +0 -255
  73. data/spec/cruby/buffer_packer.rb +0 -29
  74. data/spec/cruby/buffer_spec.rb +0 -575
  75. data/spec/cruby/buffer_unpacker.rb +0 -19
  76. data/spec/cruby/unpacker_spec.rb +0 -70
  77. data/spec/ext_value_spec.rb +0 -99
  78. data/spec/exttypes.rb +0 -51
  79. data/spec/factory_spec.rb +0 -654
  80. data/spec/format_spec.rb +0 -301
  81. data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
  82. data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
  83. data/spec/jruby/unpacker_spec.rb +0 -186
  84. data/spec/msgpack_spec.rb +0 -214
  85. data/spec/pack_spec.rb +0 -61
  86. data/spec/packer_spec.rb +0 -575
  87. data/spec/random_compat.rb +0 -24
  88. data/spec/spec_helper.rb +0 -65
  89. data/spec/timestamp_spec.rb +0 -159
  90. data/spec/unpack_spec.rb +0 -57
  91. data/spec/unpacker_spec.rb +0 -847
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2c5ae461c691018c21ea088c4b629510c0626a31c16e640d7128d1d4be70276a
4
- data.tar.gz: 32ac330fedeb8fdcf90e172df4480d05564185ef9b3e72f430c83de04eea90b1
3
+ metadata.gz: 2f5b1af6b3a51f5ccc6bcf67c94c1fc6193b02fe01b123e2cfb06a6df9607116
4
+ data.tar.gz: cc057f24e1ffa4cdc3e331499eb04de4c2383b0657dcf0baeba08300fd20862e
5
5
  SHA512:
6
- metadata.gz: 2a5a1c96cbfdc2030c38cf559a61aaacc466a5b4fcaaa6af809b8d062f3042a44ee6df0f731fe77bbdf1ebba0a123da2b9db033e7117baabcc6e9664dd6f56ef
7
- data.tar.gz: 07c313bd70f92996b0131a0c5ce9836f025dd4fa98fdbe365ad04fa860b2bd6ca81c62fbd90cc2296a75eddd2a9b648b3ca48b8838a40ffab72a5845dfd6e724
6
+ metadata.gz: 3eb06321a534ca9b16e321cc4a71458532578dafe7967314a662223b1fbf4aa93449c98177fa982aa532ce3732ddda4a6d497704df0e9c874da07f378c73595c
7
+ data.tar.gz: 8e540755e3db9e21d7dfa4354854e8b0486f5a1bbf82c3994c6095022205f7873153d364df9310d8072c481de38ca2b4c3e088e4221c3451ceb9438312489419
data/ChangeLog CHANGED
@@ -1,3 +1,58 @@
1
+ 2023-07-18 1.7.2:
2
+
3
+ * Fix a potential GC bug when packing data using recursive extensions and buffers containing over 512KkiB of data (See #341).
4
+ * Fix a regression where feeding an empty string to an Unpacker would be considered like the end of the buffer.
5
+
6
+ 2023-05-19 1.7.1:
7
+
8
+ * Fix JRuby 9.4 compatibility.
9
+ * Fix compilation on older compilers (gcc 4.x).
10
+ * Fix an infinite recursion issue when registering a Symbol type with a `nil` packer.
11
+
12
+ 2023-03-29 1.7.0:
13
+
14
+ * Fix a possible double-free issue when GC triggers inside `_msgpack_rmem_alloc2`.
15
+ * `Unpacker#feed` now always directly read in provided strings instead of copying content in its buffer.
16
+ * `Unpacker#feed` is now an alias of `Unpacker#feed_reference`.
17
+ * Implement `Factory::Pool#unpacker` and `Factory::Pool#packer` to allow for more precise serialization.
18
+ * Require Ruby 2.5+.
19
+
20
+ 2023-03-03 1.6.1:
21
+
22
+ * Undefine `#clone` and `#dup` on `MessagePack::Buffer`, `MessagePack::Packer` and `MessagePack::Unpacker`.
23
+ These methods were never intended, and using them could cause leaks or crashes or worse.
24
+ * Fix a possible GC crash when GC trigger inside `MessagePack::Buffer.new` (#314).
25
+
26
+ 2022-09-30 1.6.0:
27
+
28
+ * Fix a potential use-after-free bug in Buffer_free when accessing a packer or unpacker buffer.
29
+ * `old-style-definition` compilation warnings.
30
+ * Restore zero-copy buffer feed when provided a Ruby string. This was accidentally broken in 1.5.4.
31
+ * Provide implementations for `ObjectSpace.memsize`. Message pack objects now properly report their size to Ruby.
32
+ * Fix an endianess bug on Windows platform.
33
+
34
+ 2022-08-23 1.5.6:
35
+
36
+ * No actual code change, just re-release the `java` version properly.
37
+
38
+ 2022-08-22 1.5.5:
39
+
40
+ * Fix a segfault when GC triggers inside a recursive extension.
41
+
42
+ 2022-07-25 1.5.4:
43
+
44
+ * Fix a segfault when deserializing empty symbol (`:""`).
45
+ * Improve compilation flags to not strip debug symbols.
46
+
47
+ 2022-05-30 version 1.5.3:
48
+
49
+ * Fix deduplication of empty strings when using the `freeze: true` option.
50
+ * Use `rb_hash_new_capa` when available (Ruby 3.2) for improved performance when parsing large hashes.
51
+
52
+ 2022-05-27 version 1.5.2:
53
+
54
+ * Fix bug about unpacking ext type objects with the recursive option
55
+
1
56
  2022-04-07 version 1.5.1:
2
57
 
3
58
  * Fix bug about packing/unpacking ext type objects with the recursive option
data/README.md CHANGED
@@ -40,7 +40,7 @@ or build msgpack-ruby and install:
40
40
  MessagePack for Ruby should run on x86, ARM, PowerPC, SPARC and other CPU architectures.
41
41
 
42
42
  And it works with MRI (CRuby) and Rubinius.
43
- Patches to improve portability is highly welcomed.
43
+ Patches to improve portability are highly welcomed.
44
44
 
45
45
 
46
46
  ## Serializing objects
@@ -51,6 +51,7 @@ Use `MessagePack.pack` or `to_msgpack`:
51
51
  require 'msgpack'
52
52
  msg = MessagePack.pack(obj) # or
53
53
  msg = obj.to_msgpack
54
+ File.binwrite('mydata.msgpack', msg)
54
55
  ```
55
56
 
56
57
  ### Streaming serialization
@@ -71,6 +72,7 @@ Use `MessagePack.unpack`:
71
72
 
72
73
  ```ruby
73
74
  require 'msgpack'
75
+ msg = File.binread('mydata.msgpack')
74
76
  obj = MessagePack.unpack(msg)
75
77
  ```
76
78
 
@@ -209,6 +211,33 @@ factory.register_type(
209
211
  factory.load(factory.dump(Point.new(12, 34))) # => #<struct Point x=12, y=34>
210
212
  ```
211
213
 
214
+ ## Pooling
215
+
216
+ Creating `Packer` and `Unpacker` objects is expensive. For best performance it is preferable to re-use these objects.
217
+
218
+ `MessagePack::Factory#pool` makes that easier:
219
+
220
+ ```ruby
221
+ factory = MessagePack::Factory.new
222
+ factory.register_type(
223
+ 0x01,
224
+ Point,
225
+ packer: ->(point, packer) {
226
+ packer.write(point.x)
227
+ packer.write(point.y)
228
+ },
229
+ unpacker: ->(unpacker) {
230
+ x = unpacker.read
231
+ y = unpacker.read
232
+ Point.new(x, y)
233
+ },
234
+ recursive: true,
235
+ )
236
+ pool = factory.pool(5) # The pool size should match the number of threads expected to use the factory concurrently.
237
+
238
+ pool.load(pool.dump(Point.new(12, 34))) # => #<struct Point x=12, y=34>
239
+ ```
240
+
212
241
  ## Buffer API
213
242
 
214
243
  MessagePack for Ruby provides a buffer API so that you can read or write data by hand, not via Packer or Unpacker API.
@@ -22,10 +22,10 @@ import org.jcodings.Encoding;
22
22
  @JRubyClass(name="MessagePack::Buffer")
23
23
  public class Buffer extends RubyObject {
24
24
  private static final long serialVersionUID = 8441244627425629412L;
25
- private IRubyObject io;
26
- private ByteBuffer buffer;
25
+ private transient IRubyObject io;
26
+ private transient ByteBuffer buffer;
27
27
  private boolean writeMode;
28
- private Encoding binaryEncoding;
28
+ private transient Encoding binaryEncoding;
29
29
 
30
30
  private static final int CACHE_LINE_SIZE = 64;
31
31
  private static final int ARRAY_HEADER_SIZE = 24;
@@ -18,22 +18,17 @@ public class ExtensionRegistry {
18
18
  private final ExtensionEntry[] extensionsByTypeId;
19
19
 
20
20
  public ExtensionRegistry() {
21
- this(new HashMap<RubyModule, ExtensionEntry>());
21
+ this(new HashMap<RubyModule, ExtensionEntry>(), new ExtensionEntry[256]);
22
22
  }
23
23
 
24
- private ExtensionRegistry(Map<RubyModule, ExtensionEntry> extensionsByModule) {
24
+ private ExtensionRegistry(Map<RubyModule, ExtensionEntry> extensionsByModule, ExtensionEntry[] extensionsByTypeId) {
25
25
  this.extensionsByModule = new HashMap<RubyModule, ExtensionEntry>(extensionsByModule);
26
26
  this.extensionsByAncestor = new HashMap<RubyModule, ExtensionEntry>();
27
- this.extensionsByTypeId = new ExtensionEntry[256];
28
- for (ExtensionEntry entry : extensionsByModule.values()) {
29
- if (entry.hasUnpacker()) {
30
- extensionsByTypeId[entry.getTypeId() + 128] = entry;
31
- }
32
- }
27
+ this.extensionsByTypeId = extensionsByTypeId.clone();
33
28
  }
34
29
 
35
30
  public ExtensionRegistry dup() {
36
- return new ExtensionRegistry(extensionsByModule);
31
+ return new ExtensionRegistry(extensionsByModule, extensionsByTypeId);
37
32
  }
38
33
 
39
34
  public IRubyObject toInternalPackerRegistry(ThreadContext ctx) {
@@ -59,8 +54,8 @@ public class ExtensionRegistry {
59
54
  return hash;
60
55
  }
61
56
 
62
- public void put(RubyModule mod, int typeId, boolean recursive, IRubyObject packerProc, IRubyObject packerArg, IRubyObject unpackerProc, IRubyObject unpackerArg) {
63
- ExtensionEntry entry = new ExtensionEntry(mod, typeId, recursive, packerProc, packerArg, unpackerProc, unpackerArg);
57
+ public void put(RubyModule mod, int typeId, boolean recursive, IRubyObject packerProc, IRubyObject unpackerProc) {
58
+ ExtensionEntry entry = new ExtensionEntry(mod, typeId, recursive, packerProc, unpackerProc);
64
59
  extensionsByModule.put(mod, entry);
65
60
  extensionsByTypeId[typeId + 128] = entry;
66
61
  extensionsByAncestor.clear();
@@ -119,18 +114,14 @@ public class ExtensionRegistry {
119
114
  private final int typeId;
120
115
  private final boolean recursive;
121
116
  private final IRubyObject packerProc;
122
- private final IRubyObject packerArg;
123
117
  private final IRubyObject unpackerProc;
124
- private final IRubyObject unpackerArg;
125
118
 
126
- public ExtensionEntry(RubyModule mod, int typeId, boolean recursive, IRubyObject packerProc, IRubyObject packerArg, IRubyObject unpackerProc, IRubyObject unpackerArg) {
119
+ public ExtensionEntry(RubyModule mod, int typeId, boolean recursive, IRubyObject packerProc, IRubyObject unpackerProc) {
127
120
  this.mod = mod;
128
121
  this.typeId = typeId;
129
122
  this.recursive = recursive;
130
123
  this.packerProc = packerProc;
131
- this.packerArg = packerArg;
132
124
  this.unpackerProc = unpackerProc;
133
- this.unpackerArg = unpackerArg;
134
125
  }
135
126
 
136
127
  public RubyModule getExtensionModule() {
@@ -146,11 +137,11 @@ public class ExtensionRegistry {
146
137
  }
147
138
 
148
139
  public boolean hasPacker() {
149
- return packerProc != null;
140
+ return packerProc != null && !packerProc.isNil();
150
141
  }
151
142
 
152
143
  public boolean hasUnpacker() {
153
- return unpackerProc != null;
144
+ return unpackerProc != null && !unpackerProc.isNil();
154
145
  }
155
146
 
156
147
  public IRubyObject getPackerProc() {
@@ -162,11 +153,11 @@ public class ExtensionRegistry {
162
153
  }
163
154
 
164
155
  public RubyArray<?> toPackerTuple(ThreadContext ctx) {
165
- return ctx.runtime.newArray(new IRubyObject[] {ctx.runtime.newFixnum(typeId), packerProc, packerArg});
156
+ return ctx.runtime.newArray(new IRubyObject[] {ctx.runtime.newFixnum(typeId), packerProc});
166
157
  }
167
158
 
168
159
  public RubyArray<?> toUnpackerTuple(ThreadContext ctx) {
169
- return ctx.runtime.newArray(new IRubyObject[] {mod, unpackerProc, unpackerArg});
160
+ return ctx.runtime.newArray(new IRubyObject[] {mod, unpackerProc});
170
161
  }
171
162
 
172
163
  public IRubyObject[] toPackerProcTypeIdPair(ThreadContext ctx) {
@@ -26,7 +26,7 @@ import static org.msgpack.jruby.Types.*;
26
26
  @JRubyClass(name="MessagePack::ExtensionValue")
27
27
  public class ExtensionValue extends RubyObject {
28
28
  private static final long serialVersionUID = 8451274621449322492L;
29
- private final Encoding binaryEncoding;
29
+ private transient final Encoding binaryEncoding;
30
30
 
31
31
  private RubyFixnum type;
32
32
  private RubyString payload;
@@ -26,8 +26,8 @@ import static org.jruby.runtime.Visibility.PRIVATE;
26
26
  @JRubyClass(name="MessagePack::Factory")
27
27
  public class Factory extends RubyObject {
28
28
  private static final long serialVersionUID = 8441284623445322492L;
29
- private final Ruby runtime;
30
- private ExtensionRegistry extensionRegistry;
29
+ private transient final Ruby runtime;
30
+ private transient ExtensionRegistry extensionRegistry;
31
31
  private boolean hasSymbolExtType;
32
32
  private boolean hasBigIntExtType;
33
33
 
@@ -80,39 +80,15 @@ public class Factory extends RubyObject {
80
80
  });
81
81
  }
82
82
 
83
- @JRubyMethod(name = "register_type", required = 2, optional = 1)
84
- public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args) {
85
- Ruby runtime = ctx.runtime;
86
- IRubyObject type = args[0];
87
- IRubyObject mod = args[1];
88
-
89
- IRubyObject packerArg;
90
- IRubyObject unpackerArg;
91
-
92
- RubyHash options = null;
83
+ @JRubyMethod(name = "register_type_internal", required = 3, visibility = PRIVATE)
84
+ public IRubyObject registerTypeInternal(ThreadContext ctx, IRubyObject type, IRubyObject mod, IRubyObject opts) {
85
+ testFrozen("MessagePack::Factory");
93
86
 
94
- if (isFrozen()) {
95
- throw runtime.newRuntimeError("can't modify frozen Factory");
96
- }
87
+ Ruby runtime = ctx.runtime;
88
+ RubyHash options = (RubyHash) opts;
97
89
 
98
- if (args.length == 2) {
99
- packerArg = runtime.newSymbol("to_msgpack_ext");
100
- unpackerArg = runtime.newSymbol("from_msgpack_ext");
101
- } else if (args.length == 3) {
102
- if (args[args.length - 1] instanceof RubyHash) {
103
- options = (RubyHash) args[args.length - 1];
104
- packerArg = options.fastARef(runtime.newSymbol("packer"));
105
- unpackerArg = options.fastARef(runtime.newSymbol("unpacker"));
106
- IRubyObject optimizedSymbolsParsingArg = options.fastARef(runtime.newSymbol("optimized_symbols_parsing"));
107
- if (optimizedSymbolsParsingArg != null && optimizedSymbolsParsingArg.isTrue()) {
108
- throw runtime.newArgumentError("JRuby implementation does not support the optimized_symbols_parsing option");
109
- }
110
- } else {
111
- throw runtime.newArgumentError(String.format("expected Hash but found %s.", args[args.length - 1].getType().getName()));
112
- }
113
- } else {
114
- throw runtime.newArgumentError(String.format("wrong number of arguments (%d for 2..3)", 2 + args.length));
115
- }
90
+ IRubyObject packerProc = options.fastARef(runtime.newSymbol("packer"));
91
+ IRubyObject unpackerProc = options.fastARef(runtime.newSymbol("unpacker"));
116
92
 
117
93
  long typeId = ((RubyFixnum) type).getLongValue();
118
94
  if (typeId < -128 || typeId > 127) {
@@ -124,21 +100,6 @@ public class Factory extends RubyObject {
124
100
  }
125
101
  RubyModule extModule = (RubyModule) mod;
126
102
 
127
- IRubyObject packerProc = runtime.getNil();
128
- IRubyObject unpackerProc = runtime.getNil();
129
- if (packerArg != null) {
130
- packerProc = packerArg.callMethod(ctx, "to_proc");
131
- }
132
- if (unpackerArg != null) {
133
- if (unpackerArg instanceof RubyString || unpackerArg instanceof RubySymbol) {
134
- unpackerProc = extModule.method(unpackerArg.callMethod(ctx, "to_sym"));
135
- } else if (unpackerArg instanceof RubyProc || unpackerArg instanceof RubyMethod) {
136
- unpackerProc = unpackerArg;
137
- } else {
138
- unpackerProc = unpackerArg.callMethod(ctx, "method", runtime.newSymbol("call"));
139
- }
140
- }
141
-
142
103
  boolean recursive = false;
143
104
  if (options != null) {
144
105
  IRubyObject recursiveExtensionArg = options.fastARef(runtime.newSymbol("recursive"));
@@ -147,9 +108,9 @@ public class Factory extends RubyObject {
147
108
  }
148
109
  }
149
110
 
150
- extensionRegistry.put(extModule, (int) typeId, recursive, packerProc, packerArg, unpackerProc, unpackerArg);
111
+ extensionRegistry.put(extModule, (int) typeId, recursive, packerProc, unpackerProc);
151
112
 
152
- if (extModule == runtime.getSymbol()) {
113
+ if (extModule == runtime.getSymbol() && !packerProc.isNil()) {
153
114
  hasSymbolExtType = true;
154
115
  }
155
116
 
@@ -28,12 +28,12 @@ import static org.jruby.runtime.Visibility.PRIVATE;
28
28
  @JRubyClass(name="MessagePack::Packer")
29
29
  public class Packer extends RubyObject {
30
30
  private static final long serialVersionUID = 8451274621499362492L;
31
- public ExtensionRegistry registry;
31
+ public transient ExtensionRegistry registry;
32
32
  private Buffer buffer;
33
- private Encoder encoder;
33
+ private transient Encoder encoder;
34
34
  private boolean hasSymbolExtType;
35
35
  private boolean hasBigintExtType;
36
- private Encoding binaryEncoding;
36
+ private transient Encoding binaryEncoding;
37
37
 
38
38
  public Packer(Ruby runtime, RubyClass type, ExtensionRegistry registry, boolean hasSymbolExtType, boolean hasBigintExtType) {
39
39
  super(runtime, type);
@@ -93,26 +93,11 @@ public class Packer extends RubyObject {
93
93
  return registry.toInternalPackerRegistry(ctx);
94
94
  }
95
95
 
96
- @JRubyMethod(name = "register_type", required = 2, optional = 1)
97
- public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Block block) {
96
+ @JRubyMethod(name = "register_type_internal", required = 3, visibility = PRIVATE)
97
+ public IRubyObject registerType(ThreadContext ctx, IRubyObject type, IRubyObject mod, IRubyObject proc) {
98
+ testFrozen("MessagePack::Packer");
99
+
98
100
  Ruby runtime = ctx.runtime;
99
- IRubyObject type = args[0];
100
- IRubyObject mod = args[1];
101
-
102
- IRubyObject arg;
103
- IRubyObject proc;
104
- if (args.length == 2) {
105
- if (! block.isGiven()) {
106
- throw runtime.newLocalJumpErrorNoBlock();
107
- }
108
- proc = block.getProcObject();
109
- arg = proc;
110
- } else if (args.length == 3) {
111
- arg = args[2];
112
- proc = arg.callMethod(ctx, "to_proc");
113
- } else {
114
- throw runtime.newArgumentError(String.format("wrong number of arguments (%d for 2..3)", 2 + args.length));
115
- }
116
101
 
117
102
  long typeId = ((RubyFixnum) type).getLongValue();
118
103
  if (typeId < -128 || typeId > 127) {
@@ -124,9 +109,9 @@ public class Packer extends RubyObject {
124
109
  }
125
110
  RubyModule extModule = (RubyModule) mod;
126
111
 
127
- registry.put(extModule, (int) typeId, false, proc, arg, null, null);
112
+ registry.put(extModule, (int) typeId, false, proc, null);
128
113
 
129
- if (extModule == runtime.getSymbol()) {
114
+ if (extModule == runtime.getSymbol() && !proc.isNil()) {
130
115
  encoder.hasSymbolExtType = true;
131
116
  }
132
117
 
@@ -21,18 +21,17 @@ import org.jruby.runtime.ThreadContext;
21
21
  import org.jruby.anno.JRubyClass;
22
22
  import org.jruby.anno.JRubyMethod;
23
23
  import org.jruby.util.ByteList;
24
- import org.jruby.ext.stringio.StringIO;
25
24
 
26
25
  import static org.jruby.runtime.Visibility.PRIVATE;
27
26
 
28
27
  @JRubyClass(name="MessagePack::Unpacker")
29
28
  public class Unpacker extends RubyObject {
30
29
  private static final long serialVersionUID = 8451264671199362492L;
31
- private final ExtensionRegistry registry;
30
+ private transient final ExtensionRegistry registry;
32
31
 
33
- private IRubyObject stream;
34
- private IRubyObject data;
35
- private Decoder decoder;
32
+ private transient IRubyObject stream;
33
+ private transient IRubyObject data;
34
+ private transient Decoder decoder;
36
35
  private final RubyClass underflowErrorClass;
37
36
  private boolean symbolizeKeys;
38
37
  private boolean freeze;
@@ -127,37 +126,23 @@ public class Unpacker extends RubyObject {
127
126
  return registry.toInternalUnpackerRegistry(ctx);
128
127
  }
129
128
 
130
- @JRubyMethod(name = "register_type", required = 1, optional = 2)
131
- public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Block block) {
129
+ @JRubyMethod(name = "register_type_internal", required = 3, visibility = PRIVATE)
130
+ public IRubyObject registerTypeInternal(ThreadContext ctx, IRubyObject type, IRubyObject mod, IRubyObject proc) {
131
+ testFrozen("MessagePack::Unpacker");
132
+
132
133
  Ruby runtime = ctx.runtime;
133
- IRubyObject type = args[0];
134
-
135
- RubyModule extModule;
136
- IRubyObject arg;
137
- IRubyObject proc;
138
- if (args.length == 1) {
139
- if (! block.isGiven()) {
140
- throw runtime.newLocalJumpErrorNoBlock();
141
- }
142
- proc = RubyProc.newProc(runtime, block, block.type);
143
- if (proc == null)
144
- System.err.println("proc from Block is null");
145
- arg = proc;
146
- extModule = null;
147
- } else if (args.length == 3) {
148
- extModule = (RubyModule) args[1];
149
- arg = args[2];
150
- proc = extModule.method(arg);
151
- } else {
152
- throw runtime.newArgumentError(String.format("wrong number of arguments (%d for 1 or 3)", 2 + args.length));
153
- }
154
134
 
155
135
  long typeId = ((RubyFixnum) type).getLongValue();
156
136
  if (typeId < -128 || typeId > 127) {
157
137
  throw runtime.newRangeError(String.format("integer %d too big to convert to `signed char'", typeId));
158
138
  }
159
139
 
160
- registry.put(extModule, (int) typeId, false, null, null, proc, arg);
140
+ RubyModule extModule = null;
141
+ if (mod != runtime.getNil()) {
142
+ extModule = (RubyModule)mod;
143
+ }
144
+
145
+ registry.put(extModule, (int) typeId, false, null, proc);
161
146
  return runtime.getNil();
162
147
  }
163
148
 
@@ -331,9 +316,7 @@ public class Unpacker extends RubyObject {
331
316
  @JRubyMethod(name = "stream=", required = 1)
332
317
  public IRubyObject setStream(ThreadContext ctx, IRubyObject stream) {
333
318
  RubyString str;
334
- if (stream instanceof StringIO) {
335
- str = stream.callMethod(ctx, "string").asString();
336
- } else if (stream instanceof RubyIO) {
319
+ if (stream instanceof RubyIO) {
337
320
  str = stream.callMethod(ctx, "read").asString();
338
321
  } else if (stream.respondsTo("read")) {
339
322
  str = stream.callMethod(ctx, "read").asString();