msgpack 1.2.6 → 1.4.4
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 +56 -0
- data/.gitignore +3 -1
- data/.rubocop.yml +4 -1
- data/ChangeLog +59 -0
- data/Gemfile +3 -0
- data/README.md +242 -0
- data/Rakefile +3 -8
- data/doclib/msgpack/factory.rb +1 -0
- data/doclib/msgpack/packer.rb +20 -0
- data/doclib/msgpack/time.rb +22 -0
- data/doclib/msgpack/timestamp.rb +44 -0
- data/doclib/msgpack.rb +2 -2
- data/ext/java/org/msgpack/jruby/Buffer.java +21 -16
- data/ext/java/org/msgpack/jruby/Decoder.java +29 -10
- data/ext/java/org/msgpack/jruby/Encoder.java +38 -19
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +9 -9
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +5 -8
- data/ext/java/org/msgpack/jruby/Factory.java +8 -3
- data/ext/java/org/msgpack/jruby/Packer.java +31 -8
- data/ext/java/org/msgpack/jruby/Unpacker.java +40 -27
- data/ext/msgpack/buffer.c +4 -16
- data/ext/msgpack/buffer.h +60 -5
- data/ext/msgpack/compat.h +1 -12
- data/ext/msgpack/extconf.rb +39 -7
- data/ext/msgpack/factory_class.c +10 -5
- data/ext/msgpack/packer.c +18 -5
- data/ext/msgpack/packer.h +0 -16
- data/ext/msgpack/packer_class.c +21 -9
- data/ext/msgpack/packer_ext_registry.c +0 -22
- data/ext/msgpack/unpacker.c +41 -49
- data/ext/msgpack/unpacker.h +8 -0
- data/ext/msgpack/unpacker_class.c +23 -13
- data/lib/msgpack/symbol.rb +14 -4
- data/lib/msgpack/time.rb +29 -0
- data/lib/msgpack/timestamp.rb +76 -0
- data/lib/msgpack/version.rb +4 -7
- data/lib/msgpack.rb +8 -10
- data/msgpack.gemspec +3 -7
- data/spec/cruby/buffer_spec.rb +6 -1
- data/spec/factory_spec.rb +17 -0
- data/spec/msgpack_spec.rb +44 -1
- data/spec/packer_spec.rb +54 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/timestamp_spec.rb +161 -0
- data/spec/unpacker_spec.rb +113 -1
- metadata +19 -51
- data/.travis.yml +0 -41
- data/README.rdoc +0 -201
@@ -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;
|
@@ -34,6 +35,7 @@ public class Unpacker extends RubyObject {
|
|
34
35
|
private Decoder decoder;
|
35
36
|
private final RubyClass underflowErrorClass;
|
36
37
|
private boolean symbolizeKeys;
|
38
|
+
private boolean freeze;
|
37
39
|
private boolean allowUnknownExt;
|
38
40
|
|
39
41
|
public Unpacker(Ruby runtime, RubyClass type) {
|
@@ -56,19 +58,25 @@ public class Unpacker extends RubyObject {
|
|
56
58
|
public IRubyObject initialize(ThreadContext ctx, IRubyObject[] args) {
|
57
59
|
symbolizeKeys = false;
|
58
60
|
allowUnknownExt = false;
|
61
|
+
freeze = false;
|
59
62
|
if (args.length > 0) {
|
63
|
+
Ruby runtime = ctx.runtime;
|
60
64
|
if (args[args.length - 1] instanceof RubyHash) {
|
61
65
|
RubyHash options = (RubyHash) args[args.length - 1];
|
62
|
-
IRubyObject sk = options.fastARef(
|
66
|
+
IRubyObject sk = options.fastARef(runtime.newSymbol("symbolize_keys"));
|
63
67
|
if (sk != null) {
|
64
68
|
symbolizeKeys = sk.isTrue();
|
65
69
|
}
|
66
|
-
IRubyObject
|
70
|
+
IRubyObject f = options.fastARef(runtime.newSymbol("freeze"));
|
71
|
+
if (f != null) {
|
72
|
+
freeze = f.isTrue();
|
73
|
+
}
|
74
|
+
IRubyObject au = options.fastARef(runtime.newSymbol("allow_unknown_ext"));
|
67
75
|
if (au != null) {
|
68
76
|
allowUnknownExt = au.isTrue();
|
69
77
|
}
|
70
78
|
}
|
71
|
-
if (args[0] !=
|
79
|
+
if (args[0] != runtime.getNil() && !(args[0] instanceof RubyHash)) {
|
72
80
|
setStream(ctx, args[0]);
|
73
81
|
}
|
74
82
|
}
|
@@ -76,19 +84,24 @@ public class Unpacker extends RubyObject {
|
|
76
84
|
}
|
77
85
|
|
78
86
|
public static Unpacker newUnpacker(ThreadContext ctx, ExtensionRegistry extRegistry, IRubyObject[] args) {
|
79
|
-
Unpacker unpacker = new Unpacker(ctx.
|
87
|
+
Unpacker unpacker = new Unpacker(ctx.runtime, ctx.runtime.getModule("MessagePack").getClass("Unpacker"), extRegistry);
|
80
88
|
unpacker.initialize(ctx, args);
|
81
89
|
return unpacker;
|
82
90
|
}
|
83
91
|
|
84
92
|
@JRubyMethod(name = "symbolize_keys?")
|
85
93
|
public IRubyObject isSymbolizeKeys(ThreadContext ctx) {
|
86
|
-
return symbolizeKeys ? ctx.
|
94
|
+
return symbolizeKeys ? ctx.runtime.getTrue() : ctx.runtime.getFalse();
|
95
|
+
}
|
96
|
+
|
97
|
+
@JRubyMethod(name = "freeze?")
|
98
|
+
public IRubyObject isFreeze(ThreadContext ctx) {
|
99
|
+
return freeze ? ctx.runtime.getTrue() : ctx.runtime.getFalse();
|
87
100
|
}
|
88
101
|
|
89
102
|
@JRubyMethod(name = "allow_unknown_ext?")
|
90
103
|
public IRubyObject isAllowUnknownExt(ThreadContext ctx) {
|
91
|
-
return allowUnknownExt ? ctx.
|
104
|
+
return allowUnknownExt ? ctx.runtime.getTrue() : ctx.runtime.getFalse();
|
92
105
|
}
|
93
106
|
|
94
107
|
@JRubyMethod(name = "registered_types_internal", visibility = PRIVATE)
|
@@ -98,7 +111,7 @@ public class Unpacker extends RubyObject {
|
|
98
111
|
|
99
112
|
@JRubyMethod(name = "register_type", required = 1, optional = 2)
|
100
113
|
public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Block block) {
|
101
|
-
Ruby runtime = ctx.
|
114
|
+
Ruby runtime = ctx.runtime;
|
102
115
|
IRubyObject type = args[0];
|
103
116
|
|
104
117
|
RubyModule extModule;
|
@@ -144,7 +157,7 @@ public class Unpacker extends RubyObject {
|
|
144
157
|
if (limit == -1) {
|
145
158
|
limit = byteList.length() - offset;
|
146
159
|
}
|
147
|
-
Decoder decoder = new Decoder(ctx.
|
160
|
+
Decoder decoder = new Decoder(ctx.runtime, registry, byteList.unsafeBytes(), byteList.begin() + offset, limit, symbolizeKeys, freeze, allowUnknownExt);
|
148
161
|
try {
|
149
162
|
data = null;
|
150
163
|
data = decoder.next();
|
@@ -153,13 +166,13 @@ public class Unpacker extends RubyObject {
|
|
153
166
|
throw re;
|
154
167
|
}
|
155
168
|
}
|
156
|
-
return ctx.
|
169
|
+
return ctx.runtime.newFixnum(decoder.offset());
|
157
170
|
}
|
158
171
|
|
159
172
|
@JRubyMethod(name = "data")
|
160
173
|
public IRubyObject getData(ThreadContext ctx) {
|
161
174
|
if (data == null) {
|
162
|
-
return ctx.
|
175
|
+
return ctx.runtime.getNil();
|
163
176
|
} else {
|
164
177
|
return data;
|
165
178
|
}
|
@@ -167,14 +180,14 @@ public class Unpacker extends RubyObject {
|
|
167
180
|
|
168
181
|
@JRubyMethod(name = "finished?")
|
169
182
|
public IRubyObject finished_p(ThreadContext ctx) {
|
170
|
-
return data == null ? ctx.
|
183
|
+
return data == null ? ctx.runtime.getFalse() : ctx.runtime.getTrue();
|
171
184
|
}
|
172
185
|
|
173
|
-
@JRubyMethod(required = 1)
|
186
|
+
@JRubyMethod(required = 1, name = "feed", alias = { "feed_reference" })
|
174
187
|
public IRubyObject feed(ThreadContext ctx, IRubyObject data) {
|
175
188
|
ByteList byteList = data.asString().getByteList();
|
176
189
|
if (decoder == null) {
|
177
|
-
decoder = new Decoder(ctx.
|
190
|
+
decoder = new Decoder(ctx.runtime, registry, byteList.unsafeBytes(), byteList.begin(), byteList.length(), symbolizeKeys, freeze, allowUnknownExt);
|
178
191
|
} else {
|
179
192
|
decoder.feed(byteList.unsafeBytes(), byteList.begin(), byteList.length());
|
180
193
|
}
|
@@ -191,7 +204,7 @@ public class Unpacker extends RubyObject {
|
|
191
204
|
feed(ctx, data);
|
192
205
|
if (block.isGiven()) {
|
193
206
|
each(ctx, block);
|
194
|
-
return ctx.
|
207
|
+
return ctx.runtime.getNil();
|
195
208
|
} else {
|
196
209
|
return callMethod(ctx, "to_enum");
|
197
210
|
}
|
@@ -219,7 +232,7 @@ public class Unpacker extends RubyObject {
|
|
219
232
|
|
220
233
|
@JRubyMethod
|
221
234
|
public IRubyObject fill(ThreadContext ctx) {
|
222
|
-
return ctx.
|
235
|
+
return ctx.runtime.getNil();
|
223
236
|
}
|
224
237
|
|
225
238
|
@JRubyMethod
|
@@ -227,13 +240,13 @@ public class Unpacker extends RubyObject {
|
|
227
240
|
if (decoder != null) {
|
228
241
|
decoder.reset();
|
229
242
|
}
|
230
|
-
return ctx.
|
243
|
+
return ctx.runtime.getNil();
|
231
244
|
}
|
232
245
|
|
233
246
|
@JRubyMethod(name = "read", alias = { "unpack" })
|
234
247
|
public IRubyObject read(ThreadContext ctx) {
|
235
248
|
if (decoder == null) {
|
236
|
-
throw ctx.
|
249
|
+
throw ctx.runtime.newEOFError();
|
237
250
|
}
|
238
251
|
try {
|
239
252
|
return decoder.next();
|
@@ -241,19 +254,19 @@ public class Unpacker extends RubyObject {
|
|
241
254
|
if (re.getException().getType() != underflowErrorClass) {
|
242
255
|
throw re;
|
243
256
|
} else {
|
244
|
-
throw ctx.
|
257
|
+
throw ctx.runtime.newEOFError();
|
245
258
|
}
|
246
259
|
}
|
247
260
|
}
|
248
261
|
|
249
262
|
@JRubyMethod(name = "skip")
|
250
263
|
public IRubyObject skip(ThreadContext ctx) {
|
251
|
-
throw ctx.
|
264
|
+
throw ctx.runtime.newNotImplementedError("Not supported yet in JRuby implementation");
|
252
265
|
}
|
253
266
|
|
254
267
|
@JRubyMethod(name = "skip_nil")
|
255
268
|
public IRubyObject skipNil(ThreadContext ctx) {
|
256
|
-
throw ctx.
|
269
|
+
throw ctx.runtime.newNotImplementedError("Not supported yet in JRuby implementation");
|
257
270
|
}
|
258
271
|
|
259
272
|
@JRubyMethod
|
@@ -265,11 +278,11 @@ public class Unpacker extends RubyObject {
|
|
265
278
|
if (re.getException().getType() != underflowErrorClass) {
|
266
279
|
throw re;
|
267
280
|
} else {
|
268
|
-
throw ctx.
|
281
|
+
throw ctx.runtime.newEOFError();
|
269
282
|
}
|
270
283
|
}
|
271
284
|
}
|
272
|
-
return ctx.
|
285
|
+
return ctx.runtime.getNil();
|
273
286
|
}
|
274
287
|
|
275
288
|
@JRubyMethod
|
@@ -281,17 +294,17 @@ public class Unpacker extends RubyObject {
|
|
281
294
|
if (re.getException().getType() != underflowErrorClass) {
|
282
295
|
throw re;
|
283
296
|
} else {
|
284
|
-
throw ctx.
|
297
|
+
throw ctx.runtime.newEOFError();
|
285
298
|
}
|
286
299
|
}
|
287
300
|
}
|
288
|
-
return ctx.
|
301
|
+
return ctx.runtime.getNil();
|
289
302
|
}
|
290
303
|
|
291
304
|
@JRubyMethod(name = "stream")
|
292
305
|
public IRubyObject getStream(ThreadContext ctx) {
|
293
306
|
if (stream == null) {
|
294
|
-
return ctx.
|
307
|
+
return ctx.runtime.getNil();
|
295
308
|
} else {
|
296
309
|
return stream;
|
297
310
|
}
|
@@ -307,12 +320,12 @@ public class Unpacker extends RubyObject {
|
|
307
320
|
} else if (stream.respondsTo("read")) {
|
308
321
|
str = stream.callMethod(ctx, "read").asString();
|
309
322
|
} else {
|
310
|
-
throw ctx.
|
323
|
+
throw ctx.runtime.newTypeError(stream, "IO");
|
311
324
|
}
|
312
325
|
ByteList byteList = str.getByteList();
|
313
326
|
this.stream = stream;
|
314
327
|
this.decoder = null;
|
315
|
-
this.decoder = new Decoder(ctx.
|
328
|
+
this.decoder = new Decoder(ctx.runtime, registry, byteList.unsafeBytes(), byteList.begin(), byteList.length(), symbolizeKeys, freeze, allowUnknownExt);
|
316
329
|
return getStream(ctx);
|
317
330
|
}
|
318
331
|
}
|
data/ext/msgpack/buffer.c
CHANGED
@@ -23,11 +23,11 @@
|
|
23
23
|
static ID s_replace;
|
24
24
|
#endif
|
25
25
|
|
26
|
-
#ifdef COMPAT_HAVE_ENCODING /* see compat.h*/
|
27
26
|
int msgpack_rb_encindex_utf8;
|
28
27
|
int msgpack_rb_encindex_usascii;
|
29
28
|
int msgpack_rb_encindex_ascii8bit;
|
30
|
-
|
29
|
+
|
30
|
+
ID s_uminus;
|
31
31
|
|
32
32
|
#ifndef DISABLE_RMEM
|
33
33
|
static msgpack_rmem_t s_rmem;
|
@@ -35,11 +35,11 @@ static msgpack_rmem_t s_rmem;
|
|
35
35
|
|
36
36
|
void msgpack_buffer_static_init()
|
37
37
|
{
|
38
|
-
|
38
|
+
s_uminus = rb_intern("-@");
|
39
|
+
|
39
40
|
msgpack_rb_encindex_utf8 = rb_utf8_encindex();
|
40
41
|
msgpack_rb_encindex_usascii = rb_usascii_encindex();
|
41
42
|
msgpack_rb_encindex_ascii8bit = rb_ascii8bit_encindex();
|
42
|
-
#endif
|
43
43
|
|
44
44
|
#ifndef DISABLE_RMEM
|
45
45
|
msgpack_rmem_init(&s_rmem);
|
@@ -164,12 +164,7 @@ size_t msgpack_buffer_read_to_string_nonblock(msgpack_buffer_t* b, VALUE string,
|
|
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);
|
@@ -308,9 +303,7 @@ static inline void _msgpack_buffer_add_new_chunk(msgpack_buffer_t* b)
|
|
308
303
|
static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE string)
|
309
304
|
{
|
310
305
|
VALUE mapped_string = rb_str_dup(string);
|
311
|
-
#ifdef COMPAT_HAVE_ENCODING
|
312
306
|
ENCODING_SET(mapped_string, msgpack_rb_encindex_ascii8bit);
|
313
|
-
#endif
|
314
307
|
|
315
308
|
_msgpack_buffer_add_new_chunk(b);
|
316
309
|
|
@@ -337,7 +330,6 @@ void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string)
|
|
337
330
|
|
338
331
|
if(b->io != Qnil) {
|
339
332
|
msgpack_buffer_flush(b);
|
340
|
-
#ifdef COMPAT_HAVE_ENCODING
|
341
333
|
if (ENCODING_GET(string) == msgpack_rb_encindex_ascii8bit) {
|
342
334
|
rb_funcall(b->io, b->io_write_all_method, 1, string);
|
343
335
|
} else if(!STR_DUP_LIKELY_DOES_COPY(string)) {
|
@@ -347,10 +339,6 @@ void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string)
|
|
347
339
|
} else {
|
348
340
|
msgpack_buffer_append(b, RSTRING_PTR(string), length);
|
349
341
|
}
|
350
|
-
#else
|
351
|
-
rb_funcall(b->io, b->io_write_all_method, 1, string);
|
352
|
-
#endif
|
353
|
-
|
354
342
|
} else if(!STR_DUP_LIKELY_DOES_COPY(string)) {
|
355
343
|
_msgpack_buffer_append_reference(b, string);
|
356
344
|
|
data/ext/msgpack/buffer.h
CHANGED
@@ -49,11 +49,11 @@
|
|
49
49
|
|
50
50
|
#define NO_MAPPED_STRING ((VALUE)0)
|
51
51
|
|
52
|
-
#ifdef COMPAT_HAVE_ENCODING /* see compat.h*/
|
53
52
|
extern int msgpack_rb_encindex_utf8;
|
54
53
|
extern int msgpack_rb_encindex_usascii;
|
55
54
|
extern int msgpack_rb_encindex_ascii8bit;
|
56
|
-
|
55
|
+
|
56
|
+
extern ID s_uminus;
|
57
57
|
|
58
58
|
struct msgpack_buffer_chunk_t;
|
59
59
|
typedef struct msgpack_buffer_chunk_t msgpack_buffer_chunk_t;
|
@@ -262,6 +262,20 @@ static inline size_t msgpack_buffer_append_string(msgpack_buffer_t* b, VALUE str
|
|
262
262
|
return length;
|
263
263
|
}
|
264
264
|
|
265
|
+
static inline size_t msgpack_buffer_append_string_reference(msgpack_buffer_t* b, VALUE string)
|
266
|
+
{
|
267
|
+
size_t length = RSTRING_LEN(string);
|
268
|
+
|
269
|
+
if(length > MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM) {
|
270
|
+
_msgpack_buffer_append_long_string(b, string);
|
271
|
+
|
272
|
+
} else {
|
273
|
+
msgpack_buffer_append(b, RSTRING_PTR(string), length);
|
274
|
+
}
|
275
|
+
|
276
|
+
return length;
|
277
|
+
}
|
278
|
+
|
265
279
|
|
266
280
|
/*
|
267
281
|
* IO functions
|
@@ -424,7 +438,7 @@ static inline VALUE _msgpack_buffer_refer_head_mapped_string(msgpack_buffer_t* b
|
|
424
438
|
return rb_str_substr(b->head->mapped_string, offset, length);
|
425
439
|
}
|
426
440
|
|
427
|
-
static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_t length, bool will_be_frozen)
|
441
|
+
static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_t length, bool will_be_frozen, bool utf8)
|
428
442
|
{
|
429
443
|
#ifndef DISABLE_BUFFER_READ_REFERENCE_OPTIMIZE
|
430
444
|
/* optimize */
|
@@ -432,16 +446,57 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
|
|
432
446
|
b->head->mapped_string != NO_MAPPED_STRING &&
|
433
447
|
length >= b->read_reference_threshold) {
|
434
448
|
VALUE result = _msgpack_buffer_refer_head_mapped_string(b, length);
|
449
|
+
if (utf8) ENCODING_SET(result, msgpack_rb_encindex_utf8);
|
435
450
|
_msgpack_buffer_consumed(b, length);
|
436
451
|
return result;
|
437
452
|
}
|
438
453
|
#endif
|
439
454
|
|
440
|
-
VALUE result
|
455
|
+
VALUE result;
|
456
|
+
|
457
|
+
#ifdef HAVE_RB_ENC_INTERNED_STR
|
458
|
+
if (will_be_frozen) {
|
459
|
+
result = rb_enc_interned_str(b->read_buffer, length, utf8 ? rb_utf8_encoding() : rb_ascii8bit_encoding());
|
460
|
+
} else {
|
461
|
+
if (utf8) {
|
462
|
+
result = rb_utf8_str_new(b->read_buffer, length);
|
463
|
+
} else {
|
464
|
+
result = rb_str_new(b->read_buffer, length);
|
465
|
+
}
|
466
|
+
}
|
441
467
|
_msgpack_buffer_consumed(b, length);
|
442
468
|
return result;
|
469
|
+
|
470
|
+
#else
|
471
|
+
|
472
|
+
if (utf8) {
|
473
|
+
result = rb_utf8_str_new(b->read_buffer, length);
|
474
|
+
} else {
|
475
|
+
result = rb_str_new(b->read_buffer, length);
|
476
|
+
}
|
477
|
+
|
478
|
+
#if STR_UMINUS_DEDUPE
|
479
|
+
if (will_be_frozen) {
|
480
|
+
#if STR_UMINUS_DEDUPE_FROZEN
|
481
|
+
// Starting from MRI 2.8 it is preferable to freeze the string
|
482
|
+
// before deduplication so that it can be interned directly
|
483
|
+
// otherwise it would be duplicated first which is wasteful.
|
484
|
+
rb_str_freeze(result);
|
485
|
+
#endif //STR_UMINUS_DEDUPE_FROZEN
|
486
|
+
// MRI 2.5 and older do not deduplicate strings that are already
|
487
|
+
// frozen.
|
488
|
+
result = rb_funcall(result, s_uminus, 0);
|
489
|
+
}
|
490
|
+
#endif // STR_UMINUS_DEDUPE
|
491
|
+
_msgpack_buffer_consumed(b, length);
|
492
|
+
return result;
|
493
|
+
|
494
|
+
#endif // HAVE_RB_ENC_INTERNED_STR
|
443
495
|
}
|
444
496
|
|
497
|
+
static inline VALUE msgpack_buffer_read_top_as_symbol(msgpack_buffer_t* b, size_t length)
|
498
|
+
{
|
499
|
+
return rb_str_intern(msgpack_buffer_read_top_as_string(b, length, true, false));
|
500
|
+
}
|
445
501
|
|
446
502
|
#endif
|
447
|
-
|
data/ext/msgpack/compat.h
CHANGED
@@ -20,6 +20,7 @@
|
|
20
20
|
|
21
21
|
#include <stdbool.h>
|
22
22
|
#include "ruby.h"
|
23
|
+
#include "ruby/encoding.h"
|
23
24
|
|
24
25
|
#if defined(HAVE_RUBY_ST_H)
|
25
26
|
# include "ruby/st.h" /* ruby hash on Ruby 1.9 */
|
@@ -38,18 +39,6 @@
|
|
38
39
|
# define ZALLOC_N(type,n) RB_ZALLOC_N(type,n)
|
39
40
|
#endif
|
40
41
|
|
41
|
-
/*
|
42
|
-
* COMPAT_HAVE_ENCODING
|
43
|
-
*/
|
44
|
-
#ifdef HAVE_RUBY_ENCODING_H
|
45
|
-
# include "ruby/encoding.h"
|
46
|
-
# define COMPAT_HAVE_ENCODING
|
47
|
-
#endif
|
48
|
-
|
49
|
-
#if defined(__MACRUBY__) /* MacRuby */
|
50
|
-
# undef COMPAT_HAVE_ENCODING
|
51
|
-
#endif
|
52
|
-
|
53
42
|
|
54
43
|
/*
|
55
44
|
* define STR_DUP_LIKELY_DOES_COPY
|
data/ext/msgpack/extconf.rb
CHANGED
@@ -2,13 +2,7 @@ require 'mkmf'
|
|
2
2
|
|
3
3
|
have_header("ruby/st.h")
|
4
4
|
have_header("st.h")
|
5
|
-
have_func("
|
6
|
-
have_func("rb_intern_str", ["ruby.h"])
|
7
|
-
have_func("rb_sym2str", ["ruby.h"])
|
8
|
-
have_func("rb_str_intern", ["ruby.h"])
|
9
|
-
have_func("rb_block_lambda", ["ruby.h"])
|
10
|
-
have_func("rb_hash_dup", ["ruby.h"])
|
11
|
-
have_func("rb_hash_clear", ["ruby.h"])
|
5
|
+
have_func("rb_enc_interned_str", "ruby.h")
|
12
6
|
|
13
7
|
unless RUBY_PLATFORM.include? 'mswin'
|
14
8
|
$CFLAGS << %[ -I.. -Wall -O3 -g -std=gnu99]
|
@@ -25,6 +19,44 @@ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
|
|
25
19
|
$CFLAGS << %[ -DDISABLE_RMEM]
|
26
20
|
end
|
27
21
|
|
22
|
+
# checking if Hash#[]= (rb_hash_aset) dedupes string keys
|
23
|
+
h = {}
|
24
|
+
x = {}
|
25
|
+
r = rand.to_s
|
26
|
+
h[%W(#{r}).join('')] = :foo
|
27
|
+
x[%W(#{r}).join('')] = :foo
|
28
|
+
if x.keys[0].equal?(h.keys[0])
|
29
|
+
$CFLAGS << ' -DHASH_ASET_DEDUPE=1 '
|
30
|
+
else
|
31
|
+
$CFLAGS << ' -DHASH_ASET_DEDUPE=0 '
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
# checking if String#-@ (str_uminus) dedupes... '
|
36
|
+
begin
|
37
|
+
a = -(%w(t e s t).join)
|
38
|
+
b = -(%w(t e s t).join)
|
39
|
+
if a.equal?(b)
|
40
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=1 '
|
41
|
+
else
|
42
|
+
$CFLAGS += ' -DSTR_UMINUS_DEDUPE=0 '
|
43
|
+
end
|
44
|
+
rescue NoMethodError
|
45
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
|
46
|
+
end
|
47
|
+
|
48
|
+
# checking if String#-@ (str_uminus) directly interns frozen strings... '
|
49
|
+
begin
|
50
|
+
s = rand.to_s.freeze
|
51
|
+
if (-s).equal?(s) && (-s.dup).equal?(s)
|
52
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=1 '
|
53
|
+
else
|
54
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
|
55
|
+
end
|
56
|
+
rescue NoMethodError
|
57
|
+
$CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 '
|
58
|
+
end
|
59
|
+
|
28
60
|
if warnflags = CONFIG['warnflags']
|
29
61
|
warnflags.slice!(/ -Wdeclaration-after-statement/)
|
30
62
|
end
|
data/ext/msgpack/factory_class.c
CHANGED
@@ -32,6 +32,8 @@ struct msgpack_factory_t {
|
|
32
32
|
msgpack_packer_ext_registry_t pkrg;
|
33
33
|
msgpack_unpacker_ext_registry_t ukrg;
|
34
34
|
bool has_symbol_ext_type;
|
35
|
+
bool optimized_symbol_ext_type;
|
36
|
+
int symbol_ext_type;
|
35
37
|
};
|
36
38
|
|
37
39
|
#define FACTORY(from, name) \
|
@@ -114,6 +116,8 @@ VALUE MessagePack_Factory_unpacker(int argc, VALUE* argv, VALUE self)
|
|
114
116
|
|
115
117
|
msgpack_unpacker_ext_registry_destroy(&uk->ext_registry);
|
116
118
|
msgpack_unpacker_ext_registry_dup(&fc->ukrg, &uk->ext_registry);
|
119
|
+
uk->optimized_symbol_ext_type = fc->optimized_symbol_ext_type;
|
120
|
+
uk->symbol_ext_type = fc->symbol_ext_type;
|
117
121
|
|
118
122
|
return unpacker;
|
119
123
|
}
|
@@ -128,11 +132,7 @@ static VALUE Factory_registered_types_internal(VALUE self)
|
|
128
132
|
rb_hash_aset(uk_mapping, INT2FIX(i - 128), fc->ukrg.array[i]);
|
129
133
|
}
|
130
134
|
}
|
131
|
-
#ifdef HAVE_RB_HASH_DUP
|
132
135
|
return rb_ary_new3(2, rb_hash_dup(fc->pkrg.hash), uk_mapping);
|
133
|
-
#else
|
134
|
-
return rb_ary_new3(2, rb_funcall(fc->pkrg.hash, rb_intern("dup"), 0), uk_mapping);
|
135
|
-
#endif
|
136
136
|
}
|
137
137
|
|
138
138
|
static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
@@ -141,7 +141,7 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
141
141
|
|
142
142
|
int ext_type;
|
143
143
|
VALUE ext_module;
|
144
|
-
VALUE options;
|
144
|
+
VALUE options = Qnil;
|
145
145
|
VALUE packer_arg, unpacker_arg;
|
146
146
|
VALUE packer_proc, unpacker_proc;
|
147
147
|
|
@@ -188,6 +188,8 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
188
188
|
if(unpacker_arg != Qnil) {
|
189
189
|
if(rb_type(unpacker_arg) == T_SYMBOL || rb_type(unpacker_arg) == T_STRING) {
|
190
190
|
unpacker_proc = rb_obj_method(ext_module, unpacker_arg);
|
191
|
+
} else if (rb_respond_to(unpacker_arg, rb_intern("call"))) {
|
192
|
+
unpacker_proc = unpacker_arg;
|
191
193
|
} else {
|
192
194
|
unpacker_proc = rb_funcall(unpacker_arg, rb_intern("method"), 1, ID2SYM(rb_intern("call")));
|
193
195
|
}
|
@@ -197,6 +199,9 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
197
199
|
|
198
200
|
if (ext_module == rb_cSymbol) {
|
199
201
|
fc->has_symbol_ext_type = true;
|
202
|
+
if(RB_TEST(options) && RB_TEST(rb_hash_aref(options, ID2SYM(rb_intern("optimized_symbols_parsing"))))) {
|
203
|
+
fc->optimized_symbol_ext_type = true;
|
204
|
+
}
|
200
205
|
}
|
201
206
|
|
202
207
|
msgpack_unpacker_ext_registry_put(&fc->ukrg, ext_module, ext_type, unpacker_proc, unpacker_arg);
|
data/ext/msgpack/packer.c
CHANGED
@@ -121,7 +121,7 @@ void msgpack_packer_write_hash_value(msgpack_packer_t* pk, VALUE v)
|
|
121
121
|
#endif
|
122
122
|
}
|
123
123
|
|
124
|
-
|
124
|
+
bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v)
|
125
125
|
{
|
126
126
|
int ext_type;
|
127
127
|
|
@@ -131,7 +131,14 @@ void msgpack_packer_write_other_value(msgpack_packer_t* pk, VALUE v)
|
|
131
131
|
VALUE payload = rb_funcall(proc, s_call, 1, v);
|
132
132
|
StringValue(payload);
|
133
133
|
msgpack_packer_write_ext(pk, ext_type, payload);
|
134
|
-
|
134
|
+
return true;
|
135
|
+
}
|
136
|
+
return false;
|
137
|
+
}
|
138
|
+
|
139
|
+
void msgpack_packer_write_other_value(msgpack_packer_t* pk, VALUE v)
|
140
|
+
{
|
141
|
+
if(!(msgpack_packer_try_write_with_ext_type_lookup(pk, v))) {
|
135
142
|
rb_funcall(v, pk->to_msgpack_method, 1, pk->to_msgpack_arg);
|
136
143
|
}
|
137
144
|
}
|
@@ -155,13 +162,19 @@ void msgpack_packer_write_value(msgpack_packer_t* pk, VALUE v)
|
|
155
162
|
msgpack_packer_write_symbol_value(pk, v);
|
156
163
|
break;
|
157
164
|
case T_STRING:
|
158
|
-
|
165
|
+
if(rb_class_of(v) == rb_cString || !msgpack_packer_try_write_with_ext_type_lookup(pk, v)) {
|
166
|
+
msgpack_packer_write_string_value(pk, v);
|
167
|
+
}
|
159
168
|
break;
|
160
169
|
case T_ARRAY:
|
161
|
-
|
170
|
+
if(rb_class_of(v) == rb_cArray || !msgpack_packer_try_write_with_ext_type_lookup(pk, v)) {
|
171
|
+
msgpack_packer_write_array_value(pk, v);
|
172
|
+
}
|
162
173
|
break;
|
163
174
|
case T_HASH:
|
164
|
-
|
175
|
+
if(rb_class_of(v) == rb_cHash || !msgpack_packer_try_write_with_ext_type_lookup(pk, v)) {
|
176
|
+
msgpack_packer_write_hash_value(pk, v);
|
177
|
+
}
|
165
178
|
break;
|
166
179
|
case T_BIGNUM:
|
167
180
|
msgpack_packer_write_bignum_value(pk, v);
|
data/ext/msgpack/packer.h
CHANGED
@@ -396,7 +396,6 @@ static inline void msgpack_packer_write_ext(msgpack_packer_t* pk, int ext_type,
|
|
396
396
|
msgpack_buffer_append_string(PACKER_BUFFER_(pk), payload);
|
397
397
|
}
|
398
398
|
|
399
|
-
#ifdef COMPAT_HAVE_ENCODING
|
400
399
|
static inline bool msgpack_packer_is_binary(VALUE v, int encindex)
|
401
400
|
{
|
402
401
|
return encindex == msgpack_rb_encindex_ascii8bit;
|
@@ -414,7 +413,6 @@ static inline bool msgpack_packer_is_utf8_compat_string(VALUE v, int encindex)
|
|
414
413
|
#endif
|
415
414
|
;
|
416
415
|
}
|
417
|
-
#endif
|
418
416
|
|
419
417
|
static inline void msgpack_packer_write_string_value(msgpack_packer_t* pk, VALUE v)
|
420
418
|
{
|
@@ -425,7 +423,6 @@ static inline void msgpack_packer_write_string_value(msgpack_packer_t* pk, VALUE
|
|
425
423
|
rb_raise(rb_eArgError, "size of string is too long to pack: %lu bytes should be <= %lu", len, 0xffffffffUL);
|
426
424
|
}
|
427
425
|
|
428
|
-
#ifdef COMPAT_HAVE_ENCODING
|
429
426
|
int encindex = ENCODING_GET(v);
|
430
427
|
if(msgpack_packer_is_binary(v, encindex) && !pk->compatibility_mode) {
|
431
428
|
/* write ASCII-8BIT string using Binary type */
|
@@ -443,24 +440,11 @@ static inline void msgpack_packer_write_string_value(msgpack_packer_t* pk, VALUE
|
|
443
440
|
msgpack_packer_write_raw_header(pk, (unsigned int)len);
|
444
441
|
msgpack_buffer_append_string(PACKER_BUFFER_(pk), v);
|
445
442
|
}
|
446
|
-
#else
|
447
|
-
msgpack_packer_write_raw_header(pk, (unsigned int)len);
|
448
|
-
msgpack_buffer_append_string(PACKER_BUFFER_(pk), v);
|
449
|
-
#endif
|
450
443
|
}
|
451
444
|
|
452
445
|
static inline void msgpack_packer_write_symbol_string_value(msgpack_packer_t* pk, VALUE v)
|
453
446
|
{
|
454
|
-
#ifdef HAVE_RB_SYM2STR
|
455
|
-
/* rb_sym2str is added since MRI 2.2.0 */
|
456
447
|
msgpack_packer_write_string_value(pk, rb_sym2str(v));
|
457
|
-
#else
|
458
|
-
VALUE str = rb_id2str(SYM2ID(v));
|
459
|
-
if (!str) {
|
460
|
-
rb_raise(rb_eRuntimeError, "could not convert a symbol to string");
|
461
|
-
}
|
462
|
-
msgpack_packer_write_string_value(pk, str);
|
463
|
-
#endif
|
464
448
|
}
|
465
449
|
|
466
450
|
void msgpack_packer_write_other_value(msgpack_packer_t* pk, VALUE v);
|