msgpack 1.6.1 → 1.7.1
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/ChangeLog +14 -0
- data/README.md +27 -0
- data/ext/java/org/msgpack/jruby/Buffer.java +3 -3
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +2 -2
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +1 -1
- data/ext/java/org/msgpack/jruby/Factory.java +11 -7
- data/ext/java/org/msgpack/jruby/Packer.java +6 -4
- data/ext/java/org/msgpack/jruby/Unpacker.java +7 -8
- data/ext/msgpack/buffer.c +9 -12
- data/ext/msgpack/buffer.h +2 -10
- data/ext/msgpack/extconf.rb +15 -24
- data/ext/msgpack/factory_class.c +6 -3
- data/ext/msgpack/packer_class.c +10 -1
- data/ext/msgpack/rmem.c +3 -4
- data/ext/msgpack/unpacker.c +6 -21
- data/ext/msgpack/unpacker.h +0 -4
- data/ext/msgpack/unpacker_class.c +6 -14
- data/lib/msgpack/factory.rb +41 -53
- data/lib/msgpack/version.rb +1 -1
- data/msgpack.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c2caf680ff4cafade89a14da270f52528ba2a862cea237ad028ba27fa6a93e9b
|
|
4
|
+
data.tar.gz: 01d8cc906d925acbd32a88c22f6ace7f5534a0b447be1736ea58cfdf9abb85b6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 48fcd12bfb13741d88a17e1a261cd742c903ba53cb1959a88b7083c2344817d90cfa898e775c136d785fbfcdd76be14b6dc5fc8ba3638a13ecabbb2d1387dbee
|
|
7
|
+
data.tar.gz: 310f3ea573cf41b15c47bc0033121496bd8ab7a723ef3667a96a38bc286feb79536ac5aeb8d27c3c71568149f93c8f36cc9ca8e050595e27ff87762cbccfe2dd
|
data/ChangeLog
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
2023-05-19 1.7.1:
|
|
2
|
+
|
|
3
|
+
* Fix JRuby 9.4 compatibility.
|
|
4
|
+
* Fix compilation on older compilers (gcc 4.x).
|
|
5
|
+
* Fix an infinite recursion issue when registering a Symbol type with a `nil` packer.
|
|
6
|
+
|
|
7
|
+
2023-03-29 1.7.0:
|
|
8
|
+
|
|
9
|
+
* Fix a possible double-free issue when GC triggers inside `_msgpack_rmem_alloc2`.
|
|
10
|
+
* `Unpacker#feed` now always directly read in provided strings instead of copying content in its buffer.
|
|
11
|
+
* `Unpacker#feed` is now an alias of `Unpacker#feed_reference`.
|
|
12
|
+
* Implement `Factory::Pool#unpacker` and `Factory::Pool#packer` to allow for more precise serialization.
|
|
13
|
+
* Require Ruby 2.5+.
|
|
14
|
+
|
|
1
15
|
2023-03-03 1.6.1:
|
|
2
16
|
|
|
3
17
|
* Undefine `#clone` and `#dup` on `MessagePack::Buffer`, `MessagePack::Packer` and `MessagePack::Unpacker`.
|
data/README.md
CHANGED
|
@@ -211,6 +211,33 @@ factory.register_type(
|
|
|
211
211
|
factory.load(factory.dump(Point.new(12, 34))) # => #<struct Point x=12, y=34>
|
|
212
212
|
```
|
|
213
213
|
|
|
214
|
+
## Pooling
|
|
215
|
+
|
|
216
|
+
Creating `Packer` and `Unpacker` objects is expensive. For best performance it is preferable to re-use these objects.
|
|
217
|
+
|
|
218
|
+
`MessagePack::Factory#pool` makes that easier:
|
|
219
|
+
|
|
220
|
+
```ruby
|
|
221
|
+
factory = MessagePack::Factory.new
|
|
222
|
+
factory.register_type(
|
|
223
|
+
0x01,
|
|
224
|
+
Point,
|
|
225
|
+
packer: ->(point, packer) {
|
|
226
|
+
packer.write(point.x)
|
|
227
|
+
packer.write(point.y)
|
|
228
|
+
},
|
|
229
|
+
unpacker: ->(unpacker) {
|
|
230
|
+
x = unpacker.read
|
|
231
|
+
y = unpacker.read
|
|
232
|
+
Point.new(x, y)
|
|
233
|
+
},
|
|
234
|
+
recursive: true,
|
|
235
|
+
)
|
|
236
|
+
pool = factory.pool(5) # The pool size should match the number of threads expected to use the factory concurrently.
|
|
237
|
+
|
|
238
|
+
pool.load(pool.dump(Point.new(12, 34))) # => #<struct Point x=12, y=34>
|
|
239
|
+
```
|
|
240
|
+
|
|
214
241
|
## Buffer API
|
|
215
242
|
|
|
216
243
|
MessagePack for Ruby provides a buffer API so that you can read or write data by hand, not via Packer or Unpacker API.
|
|
@@ -22,10 +22,10 @@ import org.jcodings.Encoding;
|
|
|
22
22
|
@JRubyClass(name="MessagePack::Buffer")
|
|
23
23
|
public class Buffer extends RubyObject {
|
|
24
24
|
private static final long serialVersionUID = 8441244627425629412L;
|
|
25
|
-
private IRubyObject io;
|
|
26
|
-
private ByteBuffer buffer;
|
|
25
|
+
private transient IRubyObject io;
|
|
26
|
+
private transient ByteBuffer buffer;
|
|
27
27
|
private boolean writeMode;
|
|
28
|
-
private Encoding binaryEncoding;
|
|
28
|
+
private transient Encoding binaryEncoding;
|
|
29
29
|
|
|
30
30
|
private static final int CACHE_LINE_SIZE = 64;
|
|
31
31
|
private static final int ARRAY_HEADER_SIZE = 24;
|
|
@@ -141,11 +141,11 @@ public class ExtensionRegistry {
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
public boolean hasPacker() {
|
|
144
|
-
return packerProc != null;
|
|
144
|
+
return packerProc != null && !packerProc.isNil();
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
public boolean hasUnpacker() {
|
|
148
|
-
return unpackerProc != null;
|
|
148
|
+
return unpackerProc != null && !unpackerProc.isNil();
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
public IRubyObject getPackerProc() {
|
|
@@ -26,7 +26,7 @@ import static org.msgpack.jruby.Types.*;
|
|
|
26
26
|
@JRubyClass(name="MessagePack::ExtensionValue")
|
|
27
27
|
public class ExtensionValue extends RubyObject {
|
|
28
28
|
private static final long serialVersionUID = 8451274621449322492L;
|
|
29
|
-
private final Encoding binaryEncoding;
|
|
29
|
+
private transient final Encoding binaryEncoding;
|
|
30
30
|
|
|
31
31
|
private RubyFixnum type;
|
|
32
32
|
private RubyString payload;
|
|
@@ -26,8 +26,8 @@ import static org.jruby.runtime.Visibility.PRIVATE;
|
|
|
26
26
|
@JRubyClass(name="MessagePack::Factory")
|
|
27
27
|
public class Factory extends RubyObject {
|
|
28
28
|
private static final long serialVersionUID = 8441284623445322492L;
|
|
29
|
-
private final Ruby runtime;
|
|
30
|
-
private ExtensionRegistry extensionRegistry;
|
|
29
|
+
private transient final Ruby runtime;
|
|
30
|
+
private transient ExtensionRegistry extensionRegistry;
|
|
31
31
|
private boolean hasSymbolExtType;
|
|
32
32
|
private boolean hasBigIntExtType;
|
|
33
33
|
|
|
@@ -82,6 +82,8 @@ public class Factory extends RubyObject {
|
|
|
82
82
|
|
|
83
83
|
@JRubyMethod(name = "register_type", required = 2, optional = 1)
|
|
84
84
|
public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args) {
|
|
85
|
+
testFrozen("MessagePack::Factory");
|
|
86
|
+
|
|
85
87
|
Ruby runtime = ctx.runtime;
|
|
86
88
|
IRubyObject type = args[0];
|
|
87
89
|
IRubyObject mod = args[1];
|
|
@@ -91,10 +93,6 @@ public class Factory extends RubyObject {
|
|
|
91
93
|
|
|
92
94
|
RubyHash options = null;
|
|
93
95
|
|
|
94
|
-
if (isFrozen()) {
|
|
95
|
-
throw runtime.newRuntimeError("can't modify frozen Factory");
|
|
96
|
-
}
|
|
97
|
-
|
|
98
96
|
if (args.length == 2) {
|
|
99
97
|
packerArg = runtime.newSymbol("to_msgpack_ext");
|
|
100
98
|
unpackerArg = runtime.newSymbol("from_msgpack_ext");
|
|
@@ -102,7 +100,13 @@ public class Factory extends RubyObject {
|
|
|
102
100
|
if (args[args.length - 1] instanceof RubyHash) {
|
|
103
101
|
options = (RubyHash) args[args.length - 1];
|
|
104
102
|
packerArg = options.fastARef(runtime.newSymbol("packer"));
|
|
103
|
+
if (packerArg != null && packerArg.isNil()) {
|
|
104
|
+
packerArg = null;
|
|
105
|
+
}
|
|
105
106
|
unpackerArg = options.fastARef(runtime.newSymbol("unpacker"));
|
|
107
|
+
if (unpackerArg != null && unpackerArg.isNil()) {
|
|
108
|
+
unpackerArg = null;
|
|
109
|
+
}
|
|
106
110
|
IRubyObject optimizedSymbolsParsingArg = options.fastARef(runtime.newSymbol("optimized_symbols_parsing"));
|
|
107
111
|
if (optimizedSymbolsParsingArg != null && optimizedSymbolsParsingArg.isTrue()) {
|
|
108
112
|
throw runtime.newArgumentError("JRuby implementation does not support the optimized_symbols_parsing option");
|
|
@@ -149,7 +153,7 @@ public class Factory extends RubyObject {
|
|
|
149
153
|
|
|
150
154
|
extensionRegistry.put(extModule, (int) typeId, recursive, packerProc, packerArg, unpackerProc, unpackerArg);
|
|
151
155
|
|
|
152
|
-
if (extModule == runtime.getSymbol()) {
|
|
156
|
+
if (extModule == runtime.getSymbol() && !packerProc.isNil()) {
|
|
153
157
|
hasSymbolExtType = true;
|
|
154
158
|
}
|
|
155
159
|
|
|
@@ -28,12 +28,12 @@ import static org.jruby.runtime.Visibility.PRIVATE;
|
|
|
28
28
|
@JRubyClass(name="MessagePack::Packer")
|
|
29
29
|
public class Packer extends RubyObject {
|
|
30
30
|
private static final long serialVersionUID = 8451274621499362492L;
|
|
31
|
-
public ExtensionRegistry registry;
|
|
31
|
+
public transient ExtensionRegistry registry;
|
|
32
32
|
private Buffer buffer;
|
|
33
|
-
private Encoder encoder;
|
|
33
|
+
private transient Encoder encoder;
|
|
34
34
|
private boolean hasSymbolExtType;
|
|
35
35
|
private boolean hasBigintExtType;
|
|
36
|
-
private Encoding binaryEncoding;
|
|
36
|
+
private transient Encoding binaryEncoding;
|
|
37
37
|
|
|
38
38
|
public Packer(Ruby runtime, RubyClass type, ExtensionRegistry registry, boolean hasSymbolExtType, boolean hasBigintExtType) {
|
|
39
39
|
super(runtime, type);
|
|
@@ -95,6 +95,8 @@ public class Packer extends RubyObject {
|
|
|
95
95
|
|
|
96
96
|
@JRubyMethod(name = "register_type", required = 2, optional = 1)
|
|
97
97
|
public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Block block) {
|
|
98
|
+
testFrozen("MessagePack::Packer");
|
|
99
|
+
|
|
98
100
|
Ruby runtime = ctx.runtime;
|
|
99
101
|
IRubyObject type = args[0];
|
|
100
102
|
IRubyObject mod = args[1];
|
|
@@ -126,7 +128,7 @@ public class Packer extends RubyObject {
|
|
|
126
128
|
|
|
127
129
|
registry.put(extModule, (int) typeId, false, proc, arg, null, null);
|
|
128
130
|
|
|
129
|
-
if (extModule == runtime.getSymbol()) {
|
|
131
|
+
if (extModule == runtime.getSymbol() && !proc.isNil()) {
|
|
130
132
|
encoder.hasSymbolExtType = true;
|
|
131
133
|
}
|
|
132
134
|
|
|
@@ -21,18 +21,17 @@ import org.jruby.runtime.ThreadContext;
|
|
|
21
21
|
import org.jruby.anno.JRubyClass;
|
|
22
22
|
import org.jruby.anno.JRubyMethod;
|
|
23
23
|
import org.jruby.util.ByteList;
|
|
24
|
-
import org.jruby.ext.stringio.StringIO;
|
|
25
24
|
|
|
26
25
|
import static org.jruby.runtime.Visibility.PRIVATE;
|
|
27
26
|
|
|
28
27
|
@JRubyClass(name="MessagePack::Unpacker")
|
|
29
28
|
public class Unpacker extends RubyObject {
|
|
30
29
|
private static final long serialVersionUID = 8451264671199362492L;
|
|
31
|
-
private final ExtensionRegistry registry;
|
|
30
|
+
private transient final ExtensionRegistry registry;
|
|
32
31
|
|
|
33
|
-
private IRubyObject stream;
|
|
34
|
-
private IRubyObject data;
|
|
35
|
-
private Decoder decoder;
|
|
32
|
+
private transient IRubyObject stream;
|
|
33
|
+
private transient IRubyObject data;
|
|
34
|
+
private transient Decoder decoder;
|
|
36
35
|
private final RubyClass underflowErrorClass;
|
|
37
36
|
private boolean symbolizeKeys;
|
|
38
37
|
private boolean freeze;
|
|
@@ -129,6 +128,8 @@ public class Unpacker extends RubyObject {
|
|
|
129
128
|
|
|
130
129
|
@JRubyMethod(name = "register_type", required = 1, optional = 2)
|
|
131
130
|
public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Block block) {
|
|
131
|
+
testFrozen("MessagePack::Unpacker");
|
|
132
|
+
|
|
132
133
|
Ruby runtime = ctx.runtime;
|
|
133
134
|
IRubyObject type = args[0];
|
|
134
135
|
|
|
@@ -331,9 +332,7 @@ public class Unpacker extends RubyObject {
|
|
|
331
332
|
@JRubyMethod(name = "stream=", required = 1)
|
|
332
333
|
public IRubyObject setStream(ThreadContext ctx, IRubyObject stream) {
|
|
333
334
|
RubyString str;
|
|
334
|
-
if (stream instanceof
|
|
335
|
-
str = stream.callMethod(ctx, "string").asString();
|
|
336
|
-
} else if (stream instanceof RubyIO) {
|
|
335
|
+
if (stream instanceof RubyIO) {
|
|
337
336
|
str = stream.callMethod(ctx, "read").asString();
|
|
338
337
|
} else if (stream.respondsTo("read")) {
|
|
339
338
|
str = stream.callMethod(ctx, "read").asString();
|
data/ext/msgpack/buffer.c
CHANGED
|
@@ -19,10 +19,6 @@
|
|
|
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;
|
|
@@ -40,10 +36,6 @@ void msgpack_buffer_static_init(void)
|
|
|
40
36
|
msgpack_rb_encindex_ascii8bit = rb_ascii8bit_encindex();
|
|
41
37
|
|
|
42
38
|
msgpack_rmem_init(&s_rmem);
|
|
43
|
-
|
|
44
|
-
#ifndef HAVE_RB_STR_REPLACE
|
|
45
|
-
s_replace = rb_intern("replace");
|
|
46
|
-
#endif
|
|
47
39
|
}
|
|
48
40
|
|
|
49
41
|
void msgpack_buffer_static_destroy(void)
|
|
@@ -66,7 +58,11 @@ void msgpack_buffer_init(msgpack_buffer_t* b)
|
|
|
66
58
|
static void _msgpack_buffer_chunk_destroy(msgpack_buffer_chunk_t* c)
|
|
67
59
|
{
|
|
68
60
|
if(c->mem != NULL) {
|
|
69
|
-
if(
|
|
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 {
|
|
70
66
|
xfree(c->mem);
|
|
71
67
|
}
|
|
72
68
|
/* no needs to update rmem_owner because chunks will not be
|
|
@@ -330,14 +326,12 @@ static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE s
|
|
|
330
326
|
|
|
331
327
|
void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string)
|
|
332
328
|
{
|
|
333
|
-
size_t length = RSTRING_LEN(string);
|
|
334
|
-
|
|
335
329
|
if(b->io != Qnil) {
|
|
336
330
|
msgpack_buffer_flush(b);
|
|
337
331
|
if (ENCODING_GET(string) == msgpack_rb_encindex_ascii8bit) {
|
|
338
332
|
rb_funcall(b->io, b->io_write_all_method, 1, string);
|
|
339
333
|
} else {
|
|
340
|
-
msgpack_buffer_append(b, RSTRING_PTR(string),
|
|
334
|
+
msgpack_buffer_append(b, RSTRING_PTR(string), RSTRING_LEN(string));
|
|
341
335
|
}
|
|
342
336
|
} else {
|
|
343
337
|
_msgpack_buffer_append_reference(b, string);
|
|
@@ -349,6 +343,8 @@ static inline void* _msgpack_buffer_chunk_malloc(
|
|
|
349
343
|
size_t required_size, size_t* allocated_size)
|
|
350
344
|
{
|
|
351
345
|
if(required_size <= MSGPACK_RMEM_PAGE_SIZE) {
|
|
346
|
+
c->rmem = true;
|
|
347
|
+
|
|
352
348
|
if((size_t)(b->rmem_end - b->rmem_last) < required_size) {
|
|
353
349
|
/* alloc new rmem page */
|
|
354
350
|
*allocated_size = MSGPACK_RMEM_PAGE_SIZE;
|
|
@@ -379,6 +375,7 @@ static inline void* _msgpack_buffer_chunk_malloc(
|
|
|
379
375
|
*allocated_size = required_size;
|
|
380
376
|
void* mem = xmalloc(required_size);
|
|
381
377
|
c->mem = mem;
|
|
378
|
+
c->rmem = false;
|
|
382
379
|
return mem;
|
|
383
380
|
}
|
|
384
381
|
|
data/ext/msgpack/buffer.h
CHANGED
|
@@ -78,6 +78,7 @@ struct msgpack_buffer_chunk_t {
|
|
|
78
78
|
void* mem;
|
|
79
79
|
msgpack_buffer_chunk_t* next;
|
|
80
80
|
VALUE mapped_string; /* RBString or NO_MAPPED_STRING */
|
|
81
|
+
bool rmem;
|
|
81
82
|
};
|
|
82
83
|
|
|
83
84
|
union msgpack_buffer_cast_block_t {
|
|
@@ -267,14 +268,7 @@ static inline size_t msgpack_buffer_append_string(msgpack_buffer_t* b, VALUE str
|
|
|
267
268
|
static inline size_t msgpack_buffer_append_string_reference(msgpack_buffer_t* b, VALUE string)
|
|
268
269
|
{
|
|
269
270
|
size_t length = RSTRING_LEN(string);
|
|
270
|
-
|
|
271
|
-
if(length > MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM) {
|
|
272
|
-
_msgpack_buffer_append_long_string(b, string);
|
|
273
|
-
|
|
274
|
-
} else {
|
|
275
|
-
msgpack_buffer_append(b, RSTRING_PTR(string), length);
|
|
276
|
-
}
|
|
277
|
-
|
|
271
|
+
_msgpack_buffer_append_long_string(b, string);
|
|
278
272
|
return length;
|
|
279
273
|
}
|
|
280
274
|
|
|
@@ -479,7 +473,6 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
|
|
|
479
473
|
result = rb_str_new(b->read_buffer, length);
|
|
480
474
|
}
|
|
481
475
|
|
|
482
|
-
#if STR_UMINUS_DEDUPE
|
|
483
476
|
if (will_be_frozen) {
|
|
484
477
|
#if STR_UMINUS_DEDUPE_FROZEN
|
|
485
478
|
// Starting from MRI 2.8 it is preferable to freeze the string
|
|
@@ -491,7 +484,6 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
|
|
|
491
484
|
// frozen.
|
|
492
485
|
result = rb_funcall(result, s_uminus, 0);
|
|
493
486
|
}
|
|
494
|
-
#endif // STR_UMINUS_DEDUPE
|
|
495
487
|
_msgpack_buffer_consumed(b, length);
|
|
496
488
|
return result;
|
|
497
489
|
|
data/ext/msgpack/extconf.rb
CHANGED
|
@@ -5,15 +5,20 @@ have_header("st.h")
|
|
|
5
5
|
have_func("rb_enc_interned_str", "ruby.h") # Ruby 3.0+
|
|
6
6
|
have_func("rb_hash_new_capa", "ruby.h") # Ruby 3.2+
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
append_cflags([
|
|
9
|
+
"-fvisibility=hidden",
|
|
10
|
+
"-I..",
|
|
11
|
+
"-Wall",
|
|
12
|
+
"-O3",
|
|
13
|
+
"-std=gnu99"
|
|
14
|
+
])
|
|
15
|
+
append_cflags(RbConfig::CONFIG["debugflags"]) if RbConfig::CONFIG["debugflags"]
|
|
9
16
|
|
|
10
|
-
|
|
11
|
-
$CFLAGS << %[ -I.. -Wall -O3 #{RbConfig::CONFIG["debugflags"]} -std=gnu99]
|
|
12
|
-
end
|
|
17
|
+
append_cflags("-DRUBY_DEBUG=1") if ENV["MSGPACK_DEBUG"]
|
|
13
18
|
|
|
14
19
|
if RUBY_VERSION.start_with?('3.0.') && RUBY_VERSION <= '3.0.5'
|
|
15
20
|
# https://bugs.ruby-lang.org/issues/18772
|
|
16
|
-
|
|
21
|
+
append_cflags("-DRB_ENC_INTERNED_STR_NULL_CHECK=1")
|
|
17
22
|
end
|
|
18
23
|
|
|
19
24
|
# checking if Hash#[]= (rb_hash_aset) dedupes string keys (Ruby 2.6+)
|
|
@@ -23,35 +28,21 @@ r = rand.to_s
|
|
|
23
28
|
h[%W(#{r}).join('')] = :foo
|
|
24
29
|
x[%W(#{r}).join('')] = :foo
|
|
25
30
|
if x.keys[0].equal?(h.keys[0])
|
|
26
|
-
|
|
31
|
+
append_cflags("-DHASH_ASET_DEDUPE=1")
|
|
27
32
|
else
|
|
28
|
-
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
# checking if String#-@ (str_uminus) dedupes... ' (Ruby 2.5+)
|
|
33
|
-
begin
|
|
34
|
-
a = -(%w(t e s t).join)
|
|
35
|
-
b = -(%w(t e s t).join)
|
|
36
|
-
if a.equal?(b)
|
|
37
|
-
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=1 '
|
|
38
|
-
else
|
|
39
|
-
$CFLAGS += ' -DSTR_UMINUS_DEDUPE=0 '
|
|
40
|
-
end
|
|
41
|
-
rescue NoMethodError
|
|
42
|
-
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
|
|
33
|
+
append_cflags("-DHASH_ASET_DEDUPE=0")
|
|
43
34
|
end
|
|
44
35
|
|
|
45
36
|
# checking if String#-@ (str_uminus) directly interns frozen strings... ' (Ruby 3.0+)
|
|
46
37
|
begin
|
|
47
38
|
s = rand.to_s.freeze
|
|
48
39
|
if (-s).equal?(s) && (-s.dup).equal?(s)
|
|
49
|
-
|
|
40
|
+
append_cflags("-DSTR_UMINUS_DEDUPE_FROZEN=1")
|
|
50
41
|
else
|
|
51
|
-
|
|
42
|
+
append_cflags("-DSTR_UMINUS_DEDUPE_FROZEN=0")
|
|
52
43
|
end
|
|
53
44
|
rescue NoMethodError
|
|
54
|
-
|
|
45
|
+
append_cflags("-DSTR_UMINUS_DEDUPE_FROZEN=0")
|
|
55
46
|
end
|
|
56
47
|
|
|
57
48
|
if warnflags = CONFIG['warnflags']
|
data/ext/msgpack/factory_class.c
CHANGED
|
@@ -212,7 +212,7 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
|
212
212
|
VALUE packer_proc, unpacker_proc;
|
|
213
213
|
|
|
214
214
|
if (OBJ_FROZEN(self)) {
|
|
215
|
-
rb_raise(
|
|
215
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Factory");
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
switch (argc) {
|
|
@@ -222,11 +222,12 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
|
222
222
|
unpacker_arg = ID2SYM(rb_intern("from_msgpack_ext"));
|
|
223
223
|
break;
|
|
224
224
|
case 3:
|
|
225
|
-
/* register_type(0x7f, Time, packer: proc-like,
|
|
225
|
+
/* register_type(0x7f, Time, packer: proc-like, unpacker: proc-like) */
|
|
226
226
|
options = argv[2];
|
|
227
227
|
if(rb_type(options) != T_HASH) {
|
|
228
228
|
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
|
|
229
229
|
}
|
|
230
|
+
|
|
230
231
|
packer_arg = rb_hash_aref(options, ID2SYM(rb_intern("packer")));
|
|
231
232
|
unpacker_arg = rb_hash_aref(options, ID2SYM(rb_intern("unpacker")));
|
|
232
233
|
break;
|
|
@@ -266,7 +267,9 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
|
266
267
|
}
|
|
267
268
|
|
|
268
269
|
if(ext_module == rb_cSymbol) {
|
|
269
|
-
|
|
270
|
+
if(NIL_P(options) || RTEST(rb_hash_aref(options, ID2SYM(rb_intern("packer"))))) {
|
|
271
|
+
fc->has_symbol_ext_type = true;
|
|
272
|
+
}
|
|
270
273
|
if(RTEST(options) && RTEST(rb_hash_aref(options, ID2SYM(rb_intern("optimized_symbols_parsing"))))) {
|
|
271
274
|
fc->optimized_symbol_ext_type = true;
|
|
272
275
|
}
|
data/ext/msgpack/packer_class.c
CHANGED
|
@@ -233,7 +233,12 @@ static VALUE Packer_write_extension(VALUE self, VALUE obj)
|
|
|
233
233
|
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
|
234
234
|
Check_Type(obj, T_STRUCT);
|
|
235
235
|
|
|
236
|
-
|
|
236
|
+
VALUE rb_ext_type = RSTRUCT_GET(obj, 0);
|
|
237
|
+
if(!RB_TYPE_P(rb_ext_type, T_FIXNUM)) {
|
|
238
|
+
rb_raise(rb_eRangeError, "integer %s too big to convert to `signed char'", RSTRING_PTR(rb_String(rb_ext_type)));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
int ext_type = FIX2INT(rb_ext_type);
|
|
237
242
|
if(ext_type < -128 || ext_type > 127) {
|
|
238
243
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
|
239
244
|
}
|
|
@@ -349,6 +354,10 @@ static VALUE Packer_registered_types_internal(VALUE self)
|
|
|
349
354
|
|
|
350
355
|
static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
|
|
351
356
|
{
|
|
357
|
+
if (OBJ_FROZEN(self)) {
|
|
358
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Packer");
|
|
359
|
+
}
|
|
360
|
+
|
|
352
361
|
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
|
353
362
|
|
|
354
363
|
int ext_type;
|
data/ext/msgpack/rmem.c
CHANGED
|
@@ -65,11 +65,10 @@ void* _msgpack_rmem_alloc2(msgpack_rmem_t* pm)
|
|
|
65
65
|
/* allocate new chunk */
|
|
66
66
|
c = pm->array_last++;
|
|
67
67
|
|
|
68
|
-
/* move to
|
|
69
|
-
|
|
70
|
-
pm->head = *c;
|
|
71
|
-
*c = tmp;
|
|
68
|
+
/* move head to array */
|
|
69
|
+
*c = pm->head;
|
|
72
70
|
|
|
71
|
+
pm->head.pages = NULL; /* make sure we don't point to another chunk's pages in case xmalloc triggers GC */
|
|
73
72
|
pm->head.mask = 0xffffffff & (~1); /* "& (~1)" means first chunk is already allocated */
|
|
74
73
|
pm->head.pages = xmalloc(MSGPACK_RMEM_PAGE_SIZE * 32);
|
|
75
74
|
|
data/ext/msgpack/unpacker.c
CHANGED
|
@@ -19,20 +19,14 @@
|
|
|
19
19
|
#include "unpacker.h"
|
|
20
20
|
#include "rmem.h"
|
|
21
21
|
#include "extension_value_class.h"
|
|
22
|
-
|
|
23
|
-
#if !defined(DISABLE_UNPACKER_STACK_RMEM) && \
|
|
24
|
-
MSGPACK_UNPACKER_STACK_CAPACITY * MSGPACK_UNPACKER_STACK_SIZE <= MSGPACK_RMEM_PAGE_SIZE
|
|
25
|
-
#define UNPACKER_STACK_RMEM
|
|
26
|
-
#endif
|
|
22
|
+
#include <assert.h>
|
|
27
23
|
|
|
28
24
|
static int RAW_TYPE_STRING = 256;
|
|
29
25
|
static int RAW_TYPE_BINARY = 257;
|
|
30
26
|
|
|
31
27
|
static ID s_call;
|
|
32
28
|
|
|
33
|
-
#ifdef UNPACKER_STACK_RMEM
|
|
34
29
|
static msgpack_rmem_t s_stack_rmem;
|
|
35
|
-
#endif
|
|
36
30
|
|
|
37
31
|
#if !defined(HAVE_RB_HASH_NEW_CAPA)
|
|
38
32
|
static inline VALUE rb_hash_new_capa(long capa)
|
|
@@ -43,18 +37,16 @@ static inline VALUE rb_hash_new_capa(long capa)
|
|
|
43
37
|
|
|
44
38
|
void msgpack_unpacker_static_init(void)
|
|
45
39
|
{
|
|
46
|
-
|
|
40
|
+
assert(sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE);
|
|
41
|
+
|
|
47
42
|
msgpack_rmem_init(&s_stack_rmem);
|
|
48
|
-
#endif
|
|
49
43
|
|
|
50
44
|
s_call = rb_intern("call");
|
|
51
45
|
}
|
|
52
46
|
|
|
53
47
|
void msgpack_unpacker_static_destroy(void)
|
|
54
48
|
{
|
|
55
|
-
#ifdef UNPACKER_STACK_RMEM
|
|
56
49
|
msgpack_rmem_destroy(&s_stack_rmem);
|
|
57
|
-
#endif
|
|
58
50
|
}
|
|
59
51
|
|
|
60
52
|
#define HEAD_BYTE_REQUIRED 0xc1
|
|
@@ -62,13 +54,8 @@ void msgpack_unpacker_static_destroy(void)
|
|
|
62
54
|
static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
|
|
63
55
|
msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
|
|
64
56
|
stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
|
65
|
-
#ifdef UNPACKER_STACK_RMEM
|
|
66
57
|
stack->data = msgpack_rmem_alloc(&s_stack_rmem);
|
|
67
58
|
/*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
|
|
68
|
-
#else
|
|
69
|
-
/*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_entry_t));*/
|
|
70
|
-
stack->data = xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_entry_t));
|
|
71
|
-
#endif
|
|
72
59
|
return stack;
|
|
73
60
|
}
|
|
74
61
|
|
|
@@ -85,11 +72,9 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
|
|
85
72
|
}
|
|
86
73
|
|
|
87
74
|
static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
xfree(stack->data);
|
|
92
|
-
#endif
|
|
75
|
+
if (!msgpack_rmem_free(&s_stack_rmem, stack->data)) {
|
|
76
|
+
rb_bug("Failed to free an rmem pointer, memory leak?");
|
|
77
|
+
}
|
|
93
78
|
xfree(stack);
|
|
94
79
|
}
|
|
95
80
|
|
data/ext/msgpack/unpacker.h
CHANGED
|
@@ -21,9 +21,7 @@
|
|
|
21
21
|
#include "buffer.h"
|
|
22
22
|
#include "unpacker_ext_registry.h"
|
|
23
23
|
|
|
24
|
-
#ifndef MSGPACK_UNPACKER_STACK_CAPACITY
|
|
25
24
|
#define MSGPACK_UNPACKER_STACK_CAPACITY 128
|
|
26
|
-
#endif
|
|
27
25
|
|
|
28
26
|
struct msgpack_unpacker_t;
|
|
29
27
|
typedef struct msgpack_unpacker_t msgpack_unpacker_t;
|
|
@@ -49,8 +47,6 @@ struct msgpack_unpacker_stack_t {
|
|
|
49
47
|
msgpack_unpacker_stack_t *parent;
|
|
50
48
|
};
|
|
51
49
|
|
|
52
|
-
#define MSGPACK_UNPACKER_STACK_SIZE (8+4+8+8) /* assumes size_t <= 64bit, enum <= 32bit, VALUE <= 64bit */
|
|
53
|
-
|
|
54
50
|
struct msgpack_unpacker_t {
|
|
55
51
|
msgpack_buffer_t buffer;
|
|
56
52
|
msgpack_unpacker_stack_t *stack;
|
|
@@ -249,18 +249,6 @@ static VALUE Unpacker_read_map_header(VALUE self)
|
|
|
249
249
|
return ULONG2NUM(size); // long at least 32 bits
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
-
|
|
253
|
-
static VALUE Unpacker_feed(VALUE self, VALUE data)
|
|
254
|
-
{
|
|
255
|
-
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
|
256
|
-
|
|
257
|
-
StringValue(data);
|
|
258
|
-
|
|
259
|
-
msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), data);
|
|
260
|
-
|
|
261
|
-
return self;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
252
|
static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
|
|
265
253
|
{
|
|
266
254
|
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
|
@@ -360,6 +348,10 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
|
|
|
360
348
|
|
|
361
349
|
static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
|
362
350
|
{
|
|
351
|
+
if (OBJ_FROZEN(self)) {
|
|
352
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Unpacker");
|
|
353
|
+
}
|
|
354
|
+
|
|
363
355
|
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
|
364
356
|
|
|
365
357
|
int ext_type;
|
|
@@ -457,8 +449,8 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
|
457
449
|
rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
|
|
458
450
|
rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
|
|
459
451
|
rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
|
|
460
|
-
rb_define_method(cMessagePack_Unpacker, "feed",
|
|
461
|
-
|
|
452
|
+
rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed_reference, 1);
|
|
453
|
+
rb_define_alias(cMessagePack_Unpacker, "feed_reference", "feed");
|
|
462
454
|
rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
|
|
463
455
|
rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1);
|
|
464
456
|
rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
|
data/lib/msgpack/factory.rb
CHANGED
|
@@ -88,33 +88,34 @@ module MessagePack
|
|
|
88
88
|
|
|
89
89
|
class Pool
|
|
90
90
|
if RUBY_ENGINE == "ruby"
|
|
91
|
-
class
|
|
91
|
+
class MemberPool
|
|
92
92
|
def initialize(size, &block)
|
|
93
93
|
@size = size
|
|
94
94
|
@new_member = block
|
|
95
95
|
@members = []
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
def
|
|
99
|
-
@members.pop || @new_member.call
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
98
|
+
def with
|
|
99
|
+
member = @members.pop || @new_member.call
|
|
100
|
+
begin
|
|
101
|
+
yield member
|
|
102
|
+
ensure
|
|
103
|
+
# If the pool is already full, we simply drop the extra member.
|
|
104
|
+
# This is because contrary to a connection pool, creating an extra instance
|
|
105
|
+
# is extremely unlikely to cause some kind of resource exhaustion.
|
|
106
|
+
#
|
|
107
|
+
# We could cycle the members (keep the newer one) but first It's more work and second
|
|
108
|
+
# the older member might have been created pre-fork, so it might be at least partially
|
|
109
|
+
# in shared memory.
|
|
110
|
+
if member && @members.size < @size
|
|
111
|
+
member.reset
|
|
112
|
+
@members << member
|
|
113
|
+
end
|
|
113
114
|
end
|
|
114
115
|
end
|
|
115
116
|
end
|
|
116
117
|
else
|
|
117
|
-
class
|
|
118
|
+
class MemberPool
|
|
118
119
|
def initialize(size, &block)
|
|
119
120
|
@size = size
|
|
120
121
|
@new_member = block
|
|
@@ -122,63 +123,50 @@ module MessagePack
|
|
|
122
123
|
@mutex = Mutex.new
|
|
123
124
|
end
|
|
124
125
|
|
|
125
|
-
def
|
|
126
|
-
@mutex.synchronize { @members.pop } || @new_member.call
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
member.
|
|
133
|
-
|
|
126
|
+
def with
|
|
127
|
+
member = @mutex.synchronize { @members.pop } || @new_member.call
|
|
128
|
+
begin
|
|
129
|
+
yield member
|
|
130
|
+
ensure
|
|
131
|
+
member.reset
|
|
132
|
+
@mutex.synchronize do
|
|
133
|
+
if member && @members.size < @size
|
|
134
|
+
@members << member
|
|
135
|
+
end
|
|
134
136
|
end
|
|
135
137
|
end
|
|
136
138
|
end
|
|
137
139
|
end
|
|
138
140
|
end
|
|
139
141
|
|
|
140
|
-
class PackerPool < AbstractPool
|
|
141
|
-
private
|
|
142
|
-
|
|
143
|
-
def reset(packer)
|
|
144
|
-
packer.clear
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
class UnpackerPool < AbstractPool
|
|
149
|
-
private
|
|
150
|
-
|
|
151
|
-
def reset(unpacker)
|
|
152
|
-
unpacker.reset
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
|
|
156
142
|
def initialize(factory, size, options = nil)
|
|
157
143
|
options = nil if !options || options.empty?
|
|
158
144
|
@factory = factory
|
|
159
|
-
@packers =
|
|
160
|
-
@unpackers =
|
|
145
|
+
@packers = MemberPool.new(size) { factory.packer(options).freeze }
|
|
146
|
+
@unpackers = MemberPool.new(size) { factory.unpacker(options).freeze }
|
|
161
147
|
end
|
|
162
148
|
|
|
163
149
|
def load(data)
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
unpacker.feed_reference(data)
|
|
150
|
+
@unpackers.with do |unpacker|
|
|
151
|
+
unpacker.feed(data)
|
|
167
152
|
unpacker.full_unpack
|
|
168
|
-
ensure
|
|
169
|
-
@unpackers.checkin(unpacker)
|
|
170
153
|
end
|
|
171
154
|
end
|
|
172
155
|
|
|
173
156
|
def dump(object)
|
|
174
|
-
|
|
175
|
-
begin
|
|
157
|
+
@packers.with do |packer|
|
|
176
158
|
packer.write(object)
|
|
177
159
|
packer.full_pack
|
|
178
|
-
ensure
|
|
179
|
-
@packers.checkin(packer)
|
|
180
160
|
end
|
|
181
161
|
end
|
|
162
|
+
|
|
163
|
+
def unpacker(&block)
|
|
164
|
+
@unpackers.with(&block)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def packer(&block)
|
|
168
|
+
@packers.with(&block)
|
|
169
|
+
end
|
|
182
170
|
end
|
|
183
171
|
end
|
|
184
172
|
end
|
data/lib/msgpack/version.rb
CHANGED
data/msgpack.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: msgpack
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.7.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sadayuki Furuhashi
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2023-
|
|
13
|
+
date: 2023-05-19 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: bundler
|
|
@@ -201,14 +201,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
201
201
|
requirements:
|
|
202
202
|
- - ">="
|
|
203
203
|
- !ruby/object:Gem::Version
|
|
204
|
-
version: '2.
|
|
204
|
+
version: '2.5'
|
|
205
205
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
206
|
requirements:
|
|
207
207
|
- - ">="
|
|
208
208
|
- !ruby/object:Gem::Version
|
|
209
209
|
version: '0'
|
|
210
210
|
requirements: []
|
|
211
|
-
rubygems_version: 3.
|
|
211
|
+
rubygems_version: 3.1.2
|
|
212
212
|
signing_key:
|
|
213
213
|
specification_version: 4
|
|
214
214
|
summary: MessagePack, a binary-based efficient data interchange format.
|