msgpack 1.4.2 → 1.7.2

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.
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
  }