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