msgpack 1.4.2 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +85 -0
  3. data/README.md +52 -1
  4. data/ext/java/org/msgpack/jruby/Buffer.java +26 -19
  5. data/ext/java/org/msgpack/jruby/Decoder.java +29 -21
  6. data/ext/java/org/msgpack/jruby/Encoder.java +68 -30
  7. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +43 -64
  8. data/ext/java/org/msgpack/jruby/ExtensionValue.java +6 -9
  9. data/ext/java/org/msgpack/jruby/Factory.java +43 -42
  10. data/ext/java/org/msgpack/jruby/Packer.java +37 -40
  11. data/ext/java/org/msgpack/jruby/Unpacker.java +80 -73
  12. data/ext/msgpack/buffer.c +54 -74
  13. data/ext/msgpack/buffer.h +21 -18
  14. data/ext/msgpack/buffer_class.c +161 -52
  15. data/ext/msgpack/buffer_class.h +1 -0
  16. data/ext/msgpack/compat.h +0 -99
  17. data/ext/msgpack/extconf.rb +25 -46
  18. data/ext/msgpack/factory_class.c +143 -87
  19. data/ext/msgpack/packer.c +66 -43
  20. data/ext/msgpack/packer.h +25 -20
  21. data/ext/msgpack/packer_class.c +102 -130
  22. data/ext/msgpack/packer_class.h +11 -0
  23. data/ext/msgpack/packer_ext_registry.c +35 -40
  24. data/ext/msgpack/packer_ext_registry.h +41 -38
  25. data/ext/msgpack/rbinit.c +1 -1
  26. data/ext/msgpack/rmem.c +3 -4
  27. data/ext/msgpack/sysdep.h +5 -2
  28. data/ext/msgpack/unpacker.c +126 -108
  29. data/ext/msgpack/unpacker.h +16 -13
  30. data/ext/msgpack/unpacker_class.c +86 -126
  31. data/ext/msgpack/unpacker_class.h +11 -0
  32. data/ext/msgpack/unpacker_ext_registry.c +40 -28
  33. data/ext/msgpack/unpacker_ext_registry.h +21 -18
  34. data/lib/msgpack/bigint.rb +69 -0
  35. data/lib/msgpack/buffer.rb +9 -0
  36. data/lib/msgpack/factory.rb +140 -10
  37. data/lib/msgpack/packer.rb +10 -1
  38. data/lib/msgpack/symbol.rb +21 -4
  39. data/lib/msgpack/time.rb +1 -1
  40. data/lib/msgpack/unpacker.rb +14 -1
  41. data/lib/msgpack/version.rb +1 -1
  42. data/lib/msgpack.rb +6 -7
  43. data/msgpack.gemspec +8 -5
  44. metadata +37 -82
  45. data/.gitignore +0 -23
  46. data/.rubocop.yml +0 -36
  47. data/.travis.yml +0 -39
  48. data/Gemfile +0 -9
  49. data/Rakefile +0 -71
  50. data/appveyor.yml +0 -18
  51. data/bench/pack.rb +0 -23
  52. data/bench/pack_log.rb +0 -33
  53. data/bench/pack_log_long.rb +0 -65
  54. data/bench/pack_symbols.rb +0 -28
  55. data/bench/run.sh +0 -14
  56. data/bench/run_long.sh +0 -35
  57. data/bench/run_symbols.sh +0 -26
  58. data/bench/unpack.rb +0 -21
  59. data/bench/unpack_log.rb +0 -34
  60. data/bench/unpack_log_long.rb +0 -67
  61. data/doclib/msgpack/buffer.rb +0 -193
  62. data/doclib/msgpack/core_ext.rb +0 -101
  63. data/doclib/msgpack/error.rb +0 -19
  64. data/doclib/msgpack/extension_value.rb +0 -9
  65. data/doclib/msgpack/factory.rb +0 -101
  66. data/doclib/msgpack/packer.rb +0 -208
  67. data/doclib/msgpack/time.rb +0 -22
  68. data/doclib/msgpack/timestamp.rb +0 -44
  69. data/doclib/msgpack/unpacker.rb +0 -183
  70. data/doclib/msgpack.rb +0 -87
  71. data/msgpack.org.md +0 -46
  72. data/spec/cases.json +0 -1
  73. data/spec/cases.msg +0 -0
  74. data/spec/cases_compact.msg +0 -0
  75. data/spec/cases_spec.rb +0 -39
  76. data/spec/cruby/buffer_io_spec.rb +0 -255
  77. data/spec/cruby/buffer_packer.rb +0 -29
  78. data/spec/cruby/buffer_spec.rb +0 -575
  79. data/spec/cruby/buffer_unpacker.rb +0 -19
  80. data/spec/cruby/unpacker_spec.rb +0 -70
  81. data/spec/ext_value_spec.rb +0 -99
  82. data/spec/exttypes.rb +0 -51
  83. data/spec/factory_spec.rb +0 -367
  84. data/spec/format_spec.rb +0 -301
  85. data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
  86. data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
  87. data/spec/jruby/unpacker_spec.rb +0 -186
  88. data/spec/msgpack_spec.rb +0 -214
  89. data/spec/pack_spec.rb +0 -61
  90. data/spec/packer_spec.rb +0 -557
  91. data/spec/random_compat.rb +0 -24
  92. data/spec/spec_helper.rb +0 -55
  93. data/spec/timestamp_spec.rb +0 -121
  94. data/spec/unpack_spec.rb +0 -57
  95. data/spec/unpacker_spec.rb +0 -819
@@ -21,17 +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
- private final ExtensionRegistry registry;
29
+ private static final long serialVersionUID = 8451264671199362492L;
30
+ private transient final ExtensionRegistry registry;
31
31
 
32
- private IRubyObject stream;
33
- private IRubyObject data;
34
- private Decoder decoder;
32
+ private transient IRubyObject stream;
33
+ private transient IRubyObject data;
34
+ private transient Decoder decoder;
35
35
  private final RubyClass underflowErrorClass;
36
36
  private boolean symbolizeKeys;
37
37
  private boolean freeze;
@@ -55,51 +55,70 @@ public class Unpacker extends RubyObject {
55
55
 
56
56
  @JRubyMethod(name = "initialize", optional = 2, visibility = PRIVATE)
57
57
  public IRubyObject initialize(ThreadContext ctx, IRubyObject[] args) {
58
+ Ruby runtime = ctx.runtime;
59
+
58
60
  symbolizeKeys = false;
59
61
  allowUnknownExt = false;
60
62
  freeze = false;
61
- if (args.length > 0) {
62
- if (args[args.length - 1] instanceof RubyHash) {
63
- RubyHash options = (RubyHash) args[args.length - 1];
64
- IRubyObject sk = options.fastARef(ctx.getRuntime().newSymbol("symbolize_keys"));
65
- if (sk != null) {
66
- symbolizeKeys = sk.isTrue();
67
- }
68
- IRubyObject f = options.fastARef(ctx.getRuntime().newSymbol("freeze"));
69
- if (f != null) {
70
- freeze = f.isTrue();
71
- }
72
- IRubyObject au = options.fastARef(ctx.getRuntime().newSymbol("allow_unknown_ext"));
73
- if (au != null) {
74
- allowUnknownExt = au.isTrue();
75
- }
63
+
64
+ IRubyObject io = null;
65
+ RubyHash options = null;
66
+
67
+ if (args.length >= 1) {
68
+ io = args[0];
69
+ }
70
+
71
+ if (args.length >= 2 && args[1] != runtime.getNil()) {
72
+ options = (RubyHash)args[1];
73
+ }
74
+
75
+ if (options == null && io != null && io instanceof RubyHash) {
76
+ options = (RubyHash)io;
77
+ io = null;
78
+ }
79
+
80
+ if (options != null) {
81
+ IRubyObject sk = options.fastARef(runtime.newSymbol("symbolize_keys"));
82
+ if (sk != null) {
83
+ symbolizeKeys = sk.isTrue();
84
+ }
85
+ IRubyObject f = options.fastARef(runtime.newSymbol("freeze"));
86
+ if (f != null) {
87
+ freeze = f.isTrue();
76
88
  }
77
- if (args[0] != ctx.getRuntime().getNil() && !(args[0] instanceof RubyHash)) {
78
- setStream(ctx, args[0]);
89
+ IRubyObject au = options.fastARef(runtime.newSymbol("allow_unknown_ext"));
90
+ if (au != null) {
91
+ allowUnknownExt = au.isTrue();
79
92
  }
93
+
94
+ }
95
+
96
+ if (io != null && io != runtime.getNil()) {
97
+ setStream(ctx, io);
80
98
  }
99
+
81
100
  return this;
82
101
  }
83
102
 
84
103
  public static Unpacker newUnpacker(ThreadContext ctx, ExtensionRegistry extRegistry, IRubyObject[] args) {
85
- Unpacker unpacker = new Unpacker(ctx.getRuntime(), ctx.getRuntime().getModule("MessagePack").getClass("Unpacker"), extRegistry);
104
+ Unpacker unpacker = new Unpacker(ctx.runtime, ctx.runtime.getModule("MessagePack").getClass("Unpacker"), extRegistry);
86
105
  unpacker.initialize(ctx, args);
87
106
  return unpacker;
88
107
  }
89
108
 
90
109
  @JRubyMethod(name = "symbolize_keys?")
91
110
  public IRubyObject isSymbolizeKeys(ThreadContext ctx) {
92
- return symbolizeKeys ? ctx.getRuntime().getTrue() : ctx.getRuntime().getFalse();
111
+ return symbolizeKeys ? ctx.runtime.getTrue() : ctx.runtime.getFalse();
93
112
  }
94
113
 
95
114
  @JRubyMethod(name = "freeze?")
96
115
  public IRubyObject isFreeze(ThreadContext ctx) {
97
- return freeze ? ctx.getRuntime().getTrue() : ctx.getRuntime().getFalse();
116
+ return freeze ? ctx.runtime.getTrue() : ctx.runtime.getFalse();
98
117
  }
99
118
 
100
119
  @JRubyMethod(name = "allow_unknown_ext?")
101
120
  public IRubyObject isAllowUnknownExt(ThreadContext ctx) {
102
- return allowUnknownExt ? ctx.getRuntime().getTrue() : ctx.getRuntime().getFalse();
121
+ return allowUnknownExt ? ctx.runtime.getTrue() : ctx.runtime.getFalse();
103
122
  }
104
123
 
105
124
  @JRubyMethod(name = "registered_types_internal", visibility = PRIVATE)
@@ -107,37 +126,23 @@ public class Unpacker extends RubyObject {
107
126
  return registry.toInternalUnpackerRegistry(ctx);
108
127
  }
109
128
 
110
- @JRubyMethod(name = "register_type", required = 1, optional = 2)
111
- public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Block block) {
112
- Ruby runtime = ctx.getRuntime();
113
- IRubyObject type = args[0];
114
-
115
- RubyModule extModule;
116
- IRubyObject arg;
117
- IRubyObject proc;
118
- if (args.length == 1) {
119
- if (! block.isGiven()) {
120
- throw runtime.newLocalJumpErrorNoBlock();
121
- }
122
- proc = RubyProc.newProc(runtime, block, block.type);
123
- if (proc == null)
124
- System.err.println("proc from Block is null");
125
- arg = proc;
126
- extModule = null;
127
- } else if (args.length == 3) {
128
- extModule = (RubyModule) args[1];
129
- arg = args[2];
130
- proc = extModule.method(arg);
131
- } else {
132
- throw runtime.newArgumentError(String.format("wrong number of arguments (%d for 1 or 3)", 2 + args.length));
133
- }
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
+
133
+ Ruby runtime = ctx.runtime;
134
134
 
135
135
  long typeId = ((RubyFixnum) type).getLongValue();
136
136
  if (typeId < -128 || typeId > 127) {
137
137
  throw runtime.newRangeError(String.format("integer %d too big to convert to `signed char'", typeId));
138
138
  }
139
139
 
140
- registry.put(extModule, (int) typeId, 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);
141
146
  return runtime.getNil();
142
147
  }
143
148
 
@@ -155,7 +160,7 @@ public class Unpacker extends RubyObject {
155
160
  if (limit == -1) {
156
161
  limit = byteList.length() - offset;
157
162
  }
158
- Decoder decoder = new Decoder(ctx.getRuntime(), registry, byteList.unsafeBytes(), byteList.begin() + offset, limit, symbolizeKeys, freeze, allowUnknownExt);
163
+ Decoder decoder = new Decoder(ctx.runtime, this, byteList.unsafeBytes(), byteList.begin() + offset, limit, symbolizeKeys, freeze, allowUnknownExt);
159
164
  try {
160
165
  data = null;
161
166
  data = decoder.next();
@@ -164,13 +169,13 @@ public class Unpacker extends RubyObject {
164
169
  throw re;
165
170
  }
166
171
  }
167
- return ctx.getRuntime().newFixnum(decoder.offset());
172
+ return ctx.runtime.newFixnum(decoder.offset());
168
173
  }
169
174
 
170
175
  @JRubyMethod(name = "data")
171
176
  public IRubyObject getData(ThreadContext ctx) {
172
177
  if (data == null) {
173
- return ctx.getRuntime().getNil();
178
+ return ctx.runtime.getNil();
174
179
  } else {
175
180
  return data;
176
181
  }
@@ -178,14 +183,14 @@ public class Unpacker extends RubyObject {
178
183
 
179
184
  @JRubyMethod(name = "finished?")
180
185
  public IRubyObject finished_p(ThreadContext ctx) {
181
- return data == null ? ctx.getRuntime().getFalse() : ctx.getRuntime().getTrue();
186
+ return data == null ? ctx.runtime.getFalse() : ctx.runtime.getTrue();
182
187
  }
183
188
 
184
189
  @JRubyMethod(required = 1, name = "feed", alias = { "feed_reference" })
185
190
  public IRubyObject feed(ThreadContext ctx, IRubyObject data) {
186
191
  ByteList byteList = data.asString().getByteList();
187
192
  if (decoder == null) {
188
- decoder = new Decoder(ctx.getRuntime(), registry, byteList.unsafeBytes(), byteList.begin(), byteList.length(), symbolizeKeys, freeze, allowUnknownExt);
193
+ decoder = new Decoder(ctx.runtime, this, byteList.unsafeBytes(), byteList.begin(), byteList.length(), symbolizeKeys, freeze, allowUnknownExt);
189
194
  } else {
190
195
  decoder.feed(byteList.unsafeBytes(), byteList.begin(), byteList.length());
191
196
  }
@@ -202,7 +207,7 @@ public class Unpacker extends RubyObject {
202
207
  feed(ctx, data);
203
208
  if (block.isGiven()) {
204
209
  each(ctx, block);
205
- return ctx.getRuntime().getNil();
210
+ return ctx.runtime.getNil();
206
211
  } else {
207
212
  return callMethod(ctx, "to_enum");
208
213
  }
@@ -230,7 +235,7 @@ public class Unpacker extends RubyObject {
230
235
 
231
236
  @JRubyMethod
232
237
  public IRubyObject fill(ThreadContext ctx) {
233
- return ctx.getRuntime().getNil();
238
+ return ctx.runtime.getNil();
234
239
  }
235
240
 
236
241
  @JRubyMethod
@@ -238,13 +243,13 @@ public class Unpacker extends RubyObject {
238
243
  if (decoder != null) {
239
244
  decoder.reset();
240
245
  }
241
- return ctx.getRuntime().getNil();
246
+ return ctx.runtime.getNil();
242
247
  }
243
248
 
244
249
  @JRubyMethod(name = "read", alias = { "unpack" })
245
250
  public IRubyObject read(ThreadContext ctx) {
246
251
  if (decoder == null) {
247
- throw ctx.getRuntime().newEOFError();
252
+ throw ctx.runtime.newEOFError();
248
253
  }
249
254
  try {
250
255
  return decoder.next();
@@ -252,19 +257,19 @@ public class Unpacker extends RubyObject {
252
257
  if (re.getException().getType() != underflowErrorClass) {
253
258
  throw re;
254
259
  } else {
255
- throw ctx.getRuntime().newEOFError();
260
+ throw ctx.runtime.newEOFError();
256
261
  }
257
262
  }
258
263
  }
259
264
 
260
265
  @JRubyMethod(name = "skip")
261
266
  public IRubyObject skip(ThreadContext ctx) {
262
- throw ctx.getRuntime().newNotImplementedError("Not supported yet in JRuby implementation");
267
+ throw ctx.runtime.newNotImplementedError("Not supported yet in JRuby implementation");
263
268
  }
264
269
 
265
270
  @JRubyMethod(name = "skip_nil")
266
271
  public IRubyObject skipNil(ThreadContext ctx) {
267
- throw ctx.getRuntime().newNotImplementedError("Not supported yet in JRuby implementation");
272
+ throw ctx.runtime.newNotImplementedError("Not supported yet in JRuby implementation");
268
273
  }
269
274
 
270
275
  @JRubyMethod
@@ -276,11 +281,11 @@ public class Unpacker extends RubyObject {
276
281
  if (re.getException().getType() != underflowErrorClass) {
277
282
  throw re;
278
283
  } else {
279
- throw ctx.getRuntime().newEOFError();
284
+ throw ctx.runtime.newEOFError();
280
285
  }
281
286
  }
282
287
  }
283
- return ctx.getRuntime().getNil();
288
+ return ctx.runtime.getNil();
284
289
  }
285
290
 
286
291
  @JRubyMethod
@@ -292,17 +297,17 @@ public class Unpacker extends RubyObject {
292
297
  if (re.getException().getType() != underflowErrorClass) {
293
298
  throw re;
294
299
  } else {
295
- throw ctx.getRuntime().newEOFError();
300
+ throw ctx.runtime.newEOFError();
296
301
  }
297
302
  }
298
303
  }
299
- return ctx.getRuntime().getNil();
304
+ return ctx.runtime.getNil();
300
305
  }
301
306
 
302
307
  @JRubyMethod(name = "stream")
303
308
  public IRubyObject getStream(ThreadContext ctx) {
304
309
  if (stream == null) {
305
- return ctx.getRuntime().getNil();
310
+ return ctx.runtime.getNil();
306
311
  } else {
307
312
  return stream;
308
313
  }
@@ -311,19 +316,21 @@ public class Unpacker extends RubyObject {
311
316
  @JRubyMethod(name = "stream=", required = 1)
312
317
  public IRubyObject setStream(ThreadContext ctx, IRubyObject stream) {
313
318
  RubyString str;
314
- if (stream instanceof StringIO) {
315
- str = stream.callMethod(ctx, "string").asString();
316
- } else if (stream instanceof RubyIO) {
319
+ if (stream instanceof RubyIO) {
317
320
  str = stream.callMethod(ctx, "read").asString();
318
321
  } else if (stream.respondsTo("read")) {
319
322
  str = stream.callMethod(ctx, "read").asString();
320
323
  } else {
321
- throw ctx.getRuntime().newTypeError(stream, "IO");
324
+ throw ctx.runtime.newTypeError(stream, "IO");
322
325
  }
323
326
  ByteList byteList = str.getByteList();
324
327
  this.stream = stream;
325
328
  this.decoder = null;
326
- this.decoder = new Decoder(ctx.getRuntime(), registry, byteList.unsafeBytes(), byteList.begin(), byteList.length(), symbolizeKeys, freeze, allowUnknownExt);
329
+ this.decoder = new Decoder(ctx.runtime, this, byteList.unsafeBytes(), byteList.begin(), byteList.length(), symbolizeKeys, freeze, allowUnknownExt);
327
330
  return getStream(ctx);
328
331
  }
332
+
333
+ public ExtensionRegistry.ExtensionEntry lookupExtensionByTypeId(int typeId) {
334
+ return registry.lookupExtensionByTypeId(typeId);
335
+ }
329
336
  }
data/ext/msgpack/buffer.c CHANGED
@@ -19,21 +19,15 @@
19
19
  #include "buffer.h"
20
20
  #include "rmem.h"
21
21
 
22
- #ifndef HAVE_RB_STR_REPLACE
23
- static ID s_replace;
24
- #endif
25
-
26
22
  int msgpack_rb_encindex_utf8;
27
23
  int msgpack_rb_encindex_usascii;
28
24
  int msgpack_rb_encindex_ascii8bit;
29
25
 
30
26
  ID s_uminus;
31
27
 
32
- #ifndef DISABLE_RMEM
33
28
  static msgpack_rmem_t s_rmem;
34
- #endif
35
29
 
36
- void msgpack_buffer_static_init()
30
+ void msgpack_buffer_static_init(void)
37
31
  {
38
32
  s_uminus = rb_intern("-@");
39
33
 
@@ -41,20 +35,12 @@ void msgpack_buffer_static_init()
41
35
  msgpack_rb_encindex_usascii = rb_usascii_encindex();
42
36
  msgpack_rb_encindex_ascii8bit = rb_ascii8bit_encindex();
43
37
 
44
- #ifndef DISABLE_RMEM
45
38
  msgpack_rmem_init(&s_rmem);
46
- #endif
47
-
48
- #ifndef HAVE_RB_STR_REPLACE
49
- s_replace = rb_intern("replace");
50
- #endif
51
39
  }
52
40
 
53
- void msgpack_buffer_static_destroy()
41
+ void msgpack_buffer_static_destroy(void)
54
42
  {
55
- #ifndef DISABLE_RMEM
56
43
  msgpack_rmem_destroy(&s_rmem);
57
- #endif
58
44
  }
59
45
 
60
46
  void msgpack_buffer_init(msgpack_buffer_t* b)
@@ -72,16 +58,16 @@ void msgpack_buffer_init(msgpack_buffer_t* b)
72
58
  static void _msgpack_buffer_chunk_destroy(msgpack_buffer_chunk_t* c)
73
59
  {
74
60
  if(c->mem != NULL) {
75
- #ifndef DISABLE_RMEM
76
- if(!msgpack_rmem_free(&s_rmem, c->mem)) {
61
+ if(c->rmem) {
62
+ if(!msgpack_rmem_free(&s_rmem, c->mem)) {
63
+ rb_bug("Failed to free an rmem pointer, memory leak?");
64
+ }
65
+ } else {
77
66
  xfree(c->mem);
78
67
  }
79
68
  /* no needs to update rmem_owner because chunks will not be
80
69
  * free()ed (left in free_list) and thus *rmem_owner is
81
70
  * always valid. */
82
- #else
83
- xfree(c->mem);
84
- #endif
85
71
  }
86
72
  c->first = NULL;
87
73
  c->last = NULL;
@@ -108,8 +94,25 @@ void msgpack_buffer_destroy(msgpack_buffer_t* b)
108
94
  }
109
95
  }
110
96
 
111
- void msgpack_buffer_mark(msgpack_buffer_t* b)
97
+ size_t msgpack_buffer_memsize(const msgpack_buffer_t* b)
98
+ {
99
+ size_t memsize = 0;
100
+ msgpack_buffer_chunk_t* c = b->head;
101
+
102
+ while(c) {
103
+ memsize += sizeof(msgpack_buffer_chunk_t);
104
+ if(c->mapped_string != NO_MAPPED_STRING) {
105
+ memsize += (c->last - c->first);
106
+ }
107
+ c = c->next;
108
+ }
109
+
110
+ return memsize;
111
+ }
112
+
113
+ void msgpack_buffer_mark(void *ptr)
112
114
  {
115
+ msgpack_buffer_t* b = ptr;
113
116
  /* head is always available */
114
117
  msgpack_buffer_chunk_t* c = b->head;
115
118
  while(c != &b->tail) {
@@ -120,8 +123,6 @@ void msgpack_buffer_mark(msgpack_buffer_t* b)
120
123
 
121
124
  rb_gc_mark(b->io);
122
125
  rb_gc_mark(b->io_buffer);
123
-
124
- rb_gc_mark(b->owner);
125
126
  }
126
127
 
127
128
  bool _msgpack_buffer_shift_chunk(msgpack_buffer_t* b)
@@ -158,24 +159,17 @@ size_t msgpack_buffer_read_to_string_nonblock(msgpack_buffer_t* b, VALUE string,
158
159
  {
159
160
  size_t avail = msgpack_buffer_top_readable_size(b);
160
161
 
161
- #ifndef DISABLE_BUFFER_READ_REFERENCE_OPTIMIZE
162
162
  /* optimize */
163
163
  if(length <= avail && RSTRING_LEN(string) == 0 &&
164
164
  b->head->mapped_string != NO_MAPPED_STRING &&
165
165
  length >= b->read_reference_threshold) {
166
166
  VALUE s = _msgpack_buffer_refer_head_mapped_string(b, length);
167
- #ifndef HAVE_RB_STR_REPLACE
168
- /* TODO MRI 1.8 */
169
- rb_funcall(string, s_replace, 1, s);
170
- #else
171
167
  rb_str_replace(string, s);
172
- #endif
173
168
  /* here doesn't have to call ENCODING_SET because
174
169
  * encoding of s is always ASCII-8BIT */
175
170
  _msgpack_buffer_consumed(b, length);
176
171
  return length;
177
172
  }
178
- #endif
179
173
 
180
174
  size_t const length_orig = length;
181
175
 
@@ -257,12 +251,14 @@ bool _msgpack_buffer_read_all2(msgpack_buffer_t* b, char* buffer, size_t length)
257
251
 
258
252
  static inline msgpack_buffer_chunk_t* _msgpack_buffer_alloc_new_chunk(msgpack_buffer_t* b)
259
253
  {
260
- msgpack_buffer_chunk_t* reuse = b->free_list;
261
- if(reuse == NULL) {
262
- return xmalloc(sizeof(msgpack_buffer_chunk_t));
254
+ msgpack_buffer_chunk_t* chunk = b->free_list;
255
+ if (chunk) {
256
+ b->free_list = b->free_list->next;
257
+ } else {
258
+ chunk = xmalloc(sizeof(msgpack_buffer_chunk_t));
263
259
  }
264
- b->free_list = b->free_list->next;
265
- return reuse;
260
+ memset(chunk, 0, sizeof(msgpack_buffer_chunk_t));
261
+ return chunk;
266
262
  }
267
263
 
268
264
  static inline void _msgpack_buffer_add_new_chunk(msgpack_buffer_t* b)
@@ -288,15 +284,11 @@ static inline void _msgpack_buffer_add_new_chunk(msgpack_buffer_t* b)
288
284
 
289
285
  msgpack_buffer_chunk_t* nc = _msgpack_buffer_alloc_new_chunk(b);
290
286
 
291
- #ifndef DISABLE_RMEM
292
- #ifndef DISABLE_RMEM_REUSE_INTERNAL_FRAGMENT
293
287
  if(b->rmem_last == b->tail_buffer_end) {
294
288
  /* reuse unused rmem space */
295
289
  size_t unused = b->tail_buffer_end - b->tail.last;
296
290
  b->rmem_last -= unused;
297
291
  }
298
- #endif
299
- #endif
300
292
 
301
293
  /* rebuild tail */
302
294
  *nc = b->tail;
@@ -307,8 +299,13 @@ static inline void _msgpack_buffer_add_new_chunk(msgpack_buffer_t* b)
307
299
 
308
300
  static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE string)
309
301
  {
310
- VALUE mapped_string = rb_str_dup(string);
311
- ENCODING_SET(mapped_string, msgpack_rb_encindex_ascii8bit);
302
+ VALUE mapped_string;
303
+ if(ENCODING_GET(string) == msgpack_rb_encindex_ascii8bit && RTEST(rb_obj_frozen_p(string))) {
304
+ mapped_string = string;
305
+ } else {
306
+ mapped_string = rb_str_dup(string);
307
+ ENCODING_SET(mapped_string, msgpack_rb_encindex_ascii8bit);
308
+ }
312
309
 
313
310
  _msgpack_buffer_add_new_chunk(b);
314
311
 
@@ -331,24 +328,15 @@ static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE s
331
328
 
332
329
  void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string)
333
330
  {
334
- size_t length = RSTRING_LEN(string);
335
-
336
331
  if(b->io != Qnil) {
337
332
  msgpack_buffer_flush(b);
338
333
  if (ENCODING_GET(string) == msgpack_rb_encindex_ascii8bit) {
339
334
  rb_funcall(b->io, b->io_write_all_method, 1, string);
340
- } else if(!STR_DUP_LIKELY_DOES_COPY(string)) {
341
- VALUE s = rb_str_dup(string);
342
- ENCODING_SET(s, msgpack_rb_encindex_ascii8bit);
343
- rb_funcall(b->io, b->io_write_all_method, 1, s);
344
335
  } else {
345
- msgpack_buffer_append(b, RSTRING_PTR(string), length);
336
+ msgpack_buffer_append(b, RSTRING_PTR(string), RSTRING_LEN(string));
346
337
  }
347
- } else if(!STR_DUP_LIKELY_DOES_COPY(string)) {
348
- _msgpack_buffer_append_reference(b, string);
349
-
350
338
  } else {
351
- msgpack_buffer_append(b, RSTRING_PTR(string), length);
339
+ _msgpack_buffer_append_reference(b, string);
352
340
  }
353
341
  }
354
342
 
@@ -356,11 +344,10 @@ static inline void* _msgpack_buffer_chunk_malloc(
356
344
  msgpack_buffer_t* b, msgpack_buffer_chunk_t* c,
357
345
  size_t required_size, size_t* allocated_size)
358
346
  {
359
- #ifndef DISABLE_RMEM
360
347
  if(required_size <= MSGPACK_RMEM_PAGE_SIZE) {
361
- #ifndef DISABLE_RMEM_REUSE_INTERNAL_FRAGMENT
348
+ c->rmem = true;
349
+
362
350
  if((size_t)(b->rmem_end - b->rmem_last) < required_size) {
363
- #endif
364
351
  /* alloc new rmem page */
365
352
  *allocated_size = MSGPACK_RMEM_PAGE_SIZE;
366
353
  char* buffer = msgpack_rmem_alloc(&s_rmem);
@@ -371,8 +358,6 @@ static inline void* _msgpack_buffer_chunk_malloc(
371
358
  b->rmem_last = b->rmem_end = buffer + MSGPACK_RMEM_PAGE_SIZE;
372
359
 
373
360
  return buffer;
374
-
375
- #ifndef DISABLE_RMEM_REUSE_INTERNAL_FRAGMENT
376
361
  } else {
377
362
  /* reuse unused rmem */
378
363
  *allocated_size = (size_t)(b->rmem_end - b->rmem_last);
@@ -386,18 +371,13 @@ static inline void* _msgpack_buffer_chunk_malloc(
386
371
 
387
372
  return buffer;
388
373
  }
389
- #endif
390
374
  }
391
- #else
392
- if(required_size < 72) {
393
- required_size = 72;
394
- }
395
- #endif
396
375
 
397
376
  // TODO alignment?
398
377
  *allocated_size = required_size;
399
378
  void* mem = xmalloc(required_size);
400
379
  c->mem = mem;
380
+ c->rmem = false;
401
381
  return mem;
402
382
  }
403
383
 
@@ -447,11 +427,7 @@ void _msgpack_buffer_expand(msgpack_buffer_t* b, const char* data, size_t length
447
427
  size_t capacity = b->tail.last - b->tail.first;
448
428
 
449
429
  /* can't realloc mapped chunk or rmem page */
450
- if(b->tail.mapped_string != NO_MAPPED_STRING
451
- #ifndef DISABLE_RMEM
452
- || capacity <= MSGPACK_RMEM_PAGE_SIZE
453
- #endif
454
- ) {
430
+ if(b->tail.mapped_string != NO_MAPPED_STRING || capacity <= MSGPACK_RMEM_PAGE_SIZE) {
455
431
  /* allocate new chunk */
456
432
  _msgpack_buffer_add_new_chunk(b);
457
433
 
@@ -624,13 +600,13 @@ size_t msgpack_buffer_flush_to_io(msgpack_buffer_t* b, VALUE io, ID write_method
624
600
  size_t _msgpack_buffer_feed_from_io(msgpack_buffer_t* b)
625
601
  {
626
602
  if(b->io_buffer == Qnil) {
627
- b->io_buffer = rb_funcall(b->io, b->io_partial_read_method, 1, LONG2NUM(b->io_buffer_size));
603
+ b->io_buffer = rb_funcall(b->io, b->io_partial_read_method, 1, SIZET2NUM(b->io_buffer_size));
628
604
  if(b->io_buffer == Qnil) {
629
605
  rb_raise(rb_eEOFError, "IO reached end of file");
630
606
  }
631
607
  StringValue(b->io_buffer);
632
608
  } else {
633
- VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, LONG2NUM(b->io_buffer_size), b->io_buffer);
609
+ VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, SIZET2NUM(b->io_buffer_size), b->io_buffer);
634
610
  if(ret == Qnil) {
635
611
  rb_raise(rb_eEOFError, "IO reached end of file");
636
612
  }
@@ -649,9 +625,11 @@ size_t _msgpack_buffer_feed_from_io(msgpack_buffer_t* b)
649
625
 
650
626
  size_t _msgpack_buffer_read_from_io_to_string(msgpack_buffer_t* b, VALUE string, size_t length)
651
627
  {
628
+ #define MIN(x, y) (((x) < (y)) ? (x) : (y))
629
+
652
630
  if(RSTRING_LEN(string) == 0) {
653
631
  /* direct read */
654
- VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, LONG2NUM(length), string);
632
+ VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, SIZET2NUM(MIN(b->io_buffer_size, length)), string);
655
633
  if(ret == Qnil) {
656
634
  return 0;
657
635
  }
@@ -663,7 +641,7 @@ size_t _msgpack_buffer_read_from_io_to_string(msgpack_buffer_t* b, VALUE string,
663
641
  b->io_buffer = rb_str_buf_new(0);
664
642
  }
665
643
 
666
- VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, LONG2NUM(length), b->io_buffer);
644
+ VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, SIZET2NUM(MIN(b->io_buffer_size, length)), b->io_buffer);
667
645
  if(ret == Qnil) {
668
646
  return 0;
669
647
  }
@@ -671,6 +649,8 @@ size_t _msgpack_buffer_read_from_io_to_string(msgpack_buffer_t* b, VALUE string,
671
649
 
672
650
  rb_str_buf_cat(string, (const void*)RSTRING_PTR(b->io_buffer), rl);
673
651
  return rl;
652
+
653
+ #undef MIN
674
654
  }
675
655
 
676
656
  size_t _msgpack_buffer_skip_from_io(msgpack_buffer_t* b, size_t length)
@@ -679,7 +659,7 @@ size_t _msgpack_buffer_skip_from_io(msgpack_buffer_t* b, size_t length)
679
659
  b->io_buffer = rb_str_buf_new(0);
680
660
  }
681
661
 
682
- VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, LONG2NUM(length), b->io_buffer);
662
+ VALUE ret = rb_funcall(b->io, b->io_partial_read_method, 2, SIZET2NUM(length), b->io_buffer);
683
663
  if(ret == Qnil) {
684
664
  return 0;
685
665
  }