msgpack 1.7.1 → 1.7.3
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 +9 -0
- data/README.md +21 -12
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +5 -9
- data/ext/java/org/msgpack/jruby/Factory.java +7 -50
- data/ext/java/org/msgpack/jruby/Packer.java +3 -20
- data/ext/java/org/msgpack/jruby/Unpacker.java +8 -24
- data/ext/msgpack/buffer.c +7 -5
- data/ext/msgpack/buffer.h +3 -1
- data/ext/msgpack/buffer_class.c +72 -1
- data/ext/msgpack/buffer_class.h +1 -0
- data/ext/msgpack/extconf.rb +1 -2
- data/ext/msgpack/factory_class.c +23 -60
- data/ext/msgpack/packer.c +12 -14
- data/ext/msgpack/packer.h +0 -4
- data/ext/msgpack/packer_class.c +6 -36
- data/ext/msgpack/packer_ext_registry.c +31 -28
- data/ext/msgpack/packer_ext_registry.h +10 -14
- data/ext/msgpack/unpacker.c +20 -12
- data/ext/msgpack/unpacker_class.c +5 -30
- data/ext/msgpack/unpacker_ext_registry.c +4 -16
- data/ext/msgpack/unpacker_ext_registry.h +3 -7
- data/lib/msgpack/factory.rb +49 -10
- data/lib/msgpack/packer.rb +6 -1
- data/lib/msgpack/unpacker.rb +10 -1
- data/lib/msgpack/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe6adcd787be2f8c3e9459d46c3baa4ad81c5b08bdcaeb9bfec9a80c9a4540c6
|
4
|
+
data.tar.gz: 76d6be5a37a2b6e225ad995e6b0f670d0489839a98b678c9332837bd082e7d7e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36b0e748e7b54baad2ecef8c1c071a82cf3e6bd26540fd433a3c71f1e77afe341188594a26bfed817f84af10ef4f613ded14fc0a8448a77dc4978683cf7c35d1
|
7
|
+
data.tar.gz: 45ce3770a12b3580945ba3dd42d40ab8ba24a167f675f71d57bb42af6cf4ab204d7cc7960925ea78556988f523886fd92b431789a174e0529143ab0908d52418
|
data/ChangeLog
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
2024-10-03 1.7.3
|
2
|
+
|
3
|
+
* Limit initial containers pre-allocation to `SHRT_MAX` (32k) entries.
|
4
|
+
|
5
|
+
2023-07-18 1.7.2:
|
6
|
+
|
7
|
+
* Fix a potential GC bug when packing data using recursive extensions and buffers containing over 512KkiB of data (See #341).
|
8
|
+
* Fix a regression where feeding an empty string to an Unpacker would be considered like the end of the buffer.
|
9
|
+
|
1
10
|
2023-05-19 1.7.1:
|
2
11
|
|
3
12
|
* Fix JRuby 9.4 compatibility.
|
data/README.md
CHANGED
@@ -8,15 +8,24 @@ and typical short strings only require an extra byte in addition to the strings
|
|
8
8
|
If you ever wished to use JSON for convenience (storing an image with metadata) but could
|
9
9
|
not for technical reasons (binary data, size, speed...), MessagePack is a perfect replacement.
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
```ruby
|
12
|
+
require 'msgpack'
|
13
|
+
msg = [1,2,3].to_msgpack #=> "\x93\x01\x02\x03"
|
14
|
+
MessagePack.unpack(msg) #=> [1,2,3]
|
15
|
+
```
|
16
|
+
|
17
|
+
Add msgpack to your Gemfile to install with Bundler:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
# Gemfile
|
21
|
+
gem 'msgpack'
|
22
|
+
```
|
14
23
|
|
15
|
-
|
24
|
+
Or, use RubyGems to install:
|
16
25
|
|
17
26
|
gem install msgpack
|
18
27
|
|
19
|
-
|
28
|
+
Or, build msgpack-ruby and install from a checked-out msgpack-ruby repository:
|
20
29
|
|
21
30
|
bundle
|
22
31
|
rake
|
@@ -27,11 +36,11 @@ or build msgpack-ruby and install:
|
|
27
36
|
|
28
37
|
* Create REST API returing MessagePack using Rails + [RABL](https://github.com/nesquena/rabl)
|
29
38
|
* Store objects efficiently serialized by msgpack on memcached or Redis
|
30
|
-
* In fact Redis supports msgpack in [EVAL-scripts](
|
39
|
+
* In fact Redis supports msgpack in [EVAL-scripts](https://redis.io/docs/latest/commands/eval/)
|
31
40
|
* Upload data in efficient format from mobile devices such as smartphones
|
32
41
|
* MessagePack works on iPhone/iPad and Android. See also [Objective-C](https://github.com/msgpack/msgpack-objectivec) and [Java](https://github.com/msgpack/msgpack-java) implementations
|
33
42
|
* Design a portable protocol to communicate with embedded devices
|
34
|
-
* Check also [Fluentd](
|
43
|
+
* Check also [Fluentd](https://www.fluentd.org) which is a log collector which uses msgpack for the log format (they say it uses JSON but actually it's msgpack, which is compatible with JSON)
|
35
44
|
* Exchange objects between software components written in different languages
|
36
45
|
* You'll need a flexible but efficient format so that components exchange objects while keeping compatibility
|
37
46
|
|
@@ -128,9 +137,9 @@ being serialized altogether by throwing an exception:
|
|
128
137
|
|
129
138
|
```ruby
|
130
139
|
class Symbol
|
131
|
-
|
132
|
-
|
133
|
-
|
140
|
+
def to_msgpack_ext
|
141
|
+
raise "Serialization of symbols prohibited"
|
142
|
+
end
|
134
143
|
end
|
135
144
|
|
136
145
|
MessagePack::DefaultFactory.register_type(0x00, Symbol)
|
@@ -276,8 +285,8 @@ If this directory has Gemfile.lock (generated with MRI), remove it beforehand.
|
|
276
285
|
|
277
286
|
## Updating documents
|
278
287
|
|
279
|
-
Online
|
280
|
-
|
288
|
+
Online documentation (https://ruby.msgpack.org) is generated from the gh-pages branch.
|
289
|
+
To update documents in gh-pages branch:
|
281
290
|
|
282
291
|
bundle exec rake doc
|
283
292
|
git checkout gh-pages
|
@@ -54,8 +54,8 @@ public class ExtensionRegistry {
|
|
54
54
|
return hash;
|
55
55
|
}
|
56
56
|
|
57
|
-
public void put(RubyModule mod, int typeId, boolean recursive, IRubyObject packerProc, IRubyObject
|
58
|
-
ExtensionEntry entry = new ExtensionEntry(mod, typeId, recursive, packerProc,
|
57
|
+
public void put(RubyModule mod, int typeId, boolean recursive, IRubyObject packerProc, IRubyObject unpackerProc) {
|
58
|
+
ExtensionEntry entry = new ExtensionEntry(mod, typeId, recursive, packerProc, unpackerProc);
|
59
59
|
extensionsByModule.put(mod, entry);
|
60
60
|
extensionsByTypeId[typeId + 128] = entry;
|
61
61
|
extensionsByAncestor.clear();
|
@@ -114,18 +114,14 @@ public class ExtensionRegistry {
|
|
114
114
|
private final int typeId;
|
115
115
|
private final boolean recursive;
|
116
116
|
private final IRubyObject packerProc;
|
117
|
-
private final IRubyObject packerArg;
|
118
117
|
private final IRubyObject unpackerProc;
|
119
|
-
private final IRubyObject unpackerArg;
|
120
118
|
|
121
|
-
public ExtensionEntry(RubyModule mod, int typeId, boolean recursive, IRubyObject packerProc, IRubyObject
|
119
|
+
public ExtensionEntry(RubyModule mod, int typeId, boolean recursive, IRubyObject packerProc, IRubyObject unpackerProc) {
|
122
120
|
this.mod = mod;
|
123
121
|
this.typeId = typeId;
|
124
122
|
this.recursive = recursive;
|
125
123
|
this.packerProc = packerProc;
|
126
|
-
this.packerArg = packerArg;
|
127
124
|
this.unpackerProc = unpackerProc;
|
128
|
-
this.unpackerArg = unpackerArg;
|
129
125
|
}
|
130
126
|
|
131
127
|
public RubyModule getExtensionModule() {
|
@@ -157,11 +153,11 @@ public class ExtensionRegistry {
|
|
157
153
|
}
|
158
154
|
|
159
155
|
public RubyArray<?> toPackerTuple(ThreadContext ctx) {
|
160
|
-
return ctx.runtime.newArray(new IRubyObject[] {ctx.runtime.newFixnum(typeId), packerProc
|
156
|
+
return ctx.runtime.newArray(new IRubyObject[] {ctx.runtime.newFixnum(typeId), packerProc});
|
161
157
|
}
|
162
158
|
|
163
159
|
public RubyArray<?> toUnpackerTuple(ThreadContext ctx) {
|
164
|
-
return ctx.runtime.newArray(new IRubyObject[] {mod, unpackerProc
|
160
|
+
return ctx.runtime.newArray(new IRubyObject[] {mod, unpackerProc});
|
165
161
|
}
|
166
162
|
|
167
163
|
public IRubyObject[] toPackerProcTypeIdPair(ThreadContext ctx) {
|
@@ -80,43 +80,15 @@ public class Factory extends RubyObject {
|
|
80
80
|
});
|
81
81
|
}
|
82
82
|
|
83
|
-
@JRubyMethod(name = "
|
84
|
-
public IRubyObject
|
83
|
+
@JRubyMethod(name = "register_type_internal", required = 3, visibility = PRIVATE)
|
84
|
+
public IRubyObject registerTypeInternal(ThreadContext ctx, IRubyObject type, IRubyObject mod, IRubyObject opts) {
|
85
85
|
testFrozen("MessagePack::Factory");
|
86
86
|
|
87
87
|
Ruby runtime = ctx.runtime;
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
IRubyObject
|
92
|
-
IRubyObject unpackerArg;
|
93
|
-
|
94
|
-
RubyHash options = null;
|
95
|
-
|
96
|
-
if (args.length == 2) {
|
97
|
-
packerArg = runtime.newSymbol("to_msgpack_ext");
|
98
|
-
unpackerArg = runtime.newSymbol("from_msgpack_ext");
|
99
|
-
} else if (args.length == 3) {
|
100
|
-
if (args[args.length - 1] instanceof RubyHash) {
|
101
|
-
options = (RubyHash) args[args.length - 1];
|
102
|
-
packerArg = options.fastARef(runtime.newSymbol("packer"));
|
103
|
-
if (packerArg != null && packerArg.isNil()) {
|
104
|
-
packerArg = null;
|
105
|
-
}
|
106
|
-
unpackerArg = options.fastARef(runtime.newSymbol("unpacker"));
|
107
|
-
if (unpackerArg != null && unpackerArg.isNil()) {
|
108
|
-
unpackerArg = null;
|
109
|
-
}
|
110
|
-
IRubyObject optimizedSymbolsParsingArg = options.fastARef(runtime.newSymbol("optimized_symbols_parsing"));
|
111
|
-
if (optimizedSymbolsParsingArg != null && optimizedSymbolsParsingArg.isTrue()) {
|
112
|
-
throw runtime.newArgumentError("JRuby implementation does not support the optimized_symbols_parsing option");
|
113
|
-
}
|
114
|
-
} else {
|
115
|
-
throw runtime.newArgumentError(String.format("expected Hash but found %s.", args[args.length - 1].getType().getName()));
|
116
|
-
}
|
117
|
-
} else {
|
118
|
-
throw runtime.newArgumentError(String.format("wrong number of arguments (%d for 2..3)", 2 + args.length));
|
119
|
-
}
|
88
|
+
RubyHash options = (RubyHash) opts;
|
89
|
+
|
90
|
+
IRubyObject packerProc = options.fastARef(runtime.newSymbol("packer"));
|
91
|
+
IRubyObject unpackerProc = options.fastARef(runtime.newSymbol("unpacker"));
|
120
92
|
|
121
93
|
long typeId = ((RubyFixnum) type).getLongValue();
|
122
94
|
if (typeId < -128 || typeId > 127) {
|
@@ -128,21 +100,6 @@ public class Factory extends RubyObject {
|
|
128
100
|
}
|
129
101
|
RubyModule extModule = (RubyModule) mod;
|
130
102
|
|
131
|
-
IRubyObject packerProc = runtime.getNil();
|
132
|
-
IRubyObject unpackerProc = runtime.getNil();
|
133
|
-
if (packerArg != null) {
|
134
|
-
packerProc = packerArg.callMethod(ctx, "to_proc");
|
135
|
-
}
|
136
|
-
if (unpackerArg != null) {
|
137
|
-
if (unpackerArg instanceof RubyString || unpackerArg instanceof RubySymbol) {
|
138
|
-
unpackerProc = extModule.method(unpackerArg.callMethod(ctx, "to_sym"));
|
139
|
-
} else if (unpackerArg instanceof RubyProc || unpackerArg instanceof RubyMethod) {
|
140
|
-
unpackerProc = unpackerArg;
|
141
|
-
} else {
|
142
|
-
unpackerProc = unpackerArg.callMethod(ctx, "method", runtime.newSymbol("call"));
|
143
|
-
}
|
144
|
-
}
|
145
|
-
|
146
103
|
boolean recursive = false;
|
147
104
|
if (options != null) {
|
148
105
|
IRubyObject recursiveExtensionArg = options.fastARef(runtime.newSymbol("recursive"));
|
@@ -151,7 +108,7 @@ public class Factory extends RubyObject {
|
|
151
108
|
}
|
152
109
|
}
|
153
110
|
|
154
|
-
extensionRegistry.put(extModule, (int) typeId, recursive, packerProc,
|
111
|
+
extensionRegistry.put(extModule, (int) typeId, recursive, packerProc, unpackerProc);
|
155
112
|
|
156
113
|
if (extModule == runtime.getSymbol() && !packerProc.isNil()) {
|
157
114
|
hasSymbolExtType = true;
|
@@ -93,28 +93,11 @@ public class Packer extends RubyObject {
|
|
93
93
|
return registry.toInternalPackerRegistry(ctx);
|
94
94
|
}
|
95
95
|
|
96
|
-
@JRubyMethod(name = "
|
97
|
-
public IRubyObject registerType(ThreadContext ctx, IRubyObject
|
96
|
+
@JRubyMethod(name = "register_type_internal", required = 3, visibility = PRIVATE)
|
97
|
+
public IRubyObject registerType(ThreadContext ctx, IRubyObject type, IRubyObject mod, IRubyObject proc) {
|
98
98
|
testFrozen("MessagePack::Packer");
|
99
99
|
|
100
100
|
Ruby runtime = ctx.runtime;
|
101
|
-
IRubyObject type = args[0];
|
102
|
-
IRubyObject mod = args[1];
|
103
|
-
|
104
|
-
IRubyObject arg;
|
105
|
-
IRubyObject proc;
|
106
|
-
if (args.length == 2) {
|
107
|
-
if (! block.isGiven()) {
|
108
|
-
throw runtime.newLocalJumpErrorNoBlock();
|
109
|
-
}
|
110
|
-
proc = block.getProcObject();
|
111
|
-
arg = proc;
|
112
|
-
} else if (args.length == 3) {
|
113
|
-
arg = args[2];
|
114
|
-
proc = arg.callMethod(ctx, "to_proc");
|
115
|
-
} else {
|
116
|
-
throw runtime.newArgumentError(String.format("wrong number of arguments (%d for 2..3)", 2 + args.length));
|
117
|
-
}
|
118
101
|
|
119
102
|
long typeId = ((RubyFixnum) type).getLongValue();
|
120
103
|
if (typeId < -128 || typeId > 127) {
|
@@ -126,7 +109,7 @@ public class Packer extends RubyObject {
|
|
126
109
|
}
|
127
110
|
RubyModule extModule = (RubyModule) mod;
|
128
111
|
|
129
|
-
registry.put(extModule, (int) typeId, false, proc,
|
112
|
+
registry.put(extModule, (int) typeId, false, proc, null);
|
130
113
|
|
131
114
|
if (extModule == runtime.getSymbol() && !proc.isNil()) {
|
132
115
|
encoder.hasSymbolExtType = true;
|
@@ -126,39 +126,23 @@ public class Unpacker extends RubyObject {
|
|
126
126
|
return registry.toInternalUnpackerRegistry(ctx);
|
127
127
|
}
|
128
128
|
|
129
|
-
@JRubyMethod(name = "
|
130
|
-
public IRubyObject
|
129
|
+
@JRubyMethod(name = "register_type_internal", required = 3, visibility = PRIVATE)
|
130
|
+
public IRubyObject registerTypeInternal(ThreadContext ctx, IRubyObject type, IRubyObject mod, IRubyObject proc) {
|
131
131
|
testFrozen("MessagePack::Unpacker");
|
132
132
|
|
133
133
|
Ruby runtime = ctx.runtime;
|
134
|
-
IRubyObject type = args[0];
|
135
|
-
|
136
|
-
RubyModule extModule;
|
137
|
-
IRubyObject arg;
|
138
|
-
IRubyObject proc;
|
139
|
-
if (args.length == 1) {
|
140
|
-
if (! block.isGiven()) {
|
141
|
-
throw runtime.newLocalJumpErrorNoBlock();
|
142
|
-
}
|
143
|
-
proc = RubyProc.newProc(runtime, block, block.type);
|
144
|
-
if (proc == null)
|
145
|
-
System.err.println("proc from Block is null");
|
146
|
-
arg = proc;
|
147
|
-
extModule = null;
|
148
|
-
} else if (args.length == 3) {
|
149
|
-
extModule = (RubyModule) args[1];
|
150
|
-
arg = args[2];
|
151
|
-
proc = extModule.method(arg);
|
152
|
-
} else {
|
153
|
-
throw runtime.newArgumentError(String.format("wrong number of arguments (%d for 1 or 3)", 2 + args.length));
|
154
|
-
}
|
155
134
|
|
156
135
|
long typeId = ((RubyFixnum) type).getLongValue();
|
157
136
|
if (typeId < -128 || typeId > 127) {
|
158
137
|
throw runtime.newRangeError(String.format("integer %d too big to convert to `signed char'", typeId));
|
159
138
|
}
|
160
139
|
|
161
|
-
|
140
|
+
RubyModule extModule = null;
|
141
|
+
if (mod != runtime.getNil()) {
|
142
|
+
extModule = (RubyModule)mod;
|
143
|
+
}
|
144
|
+
|
145
|
+
registry.put(extModule, (int) typeId, false, null, proc);
|
162
146
|
return runtime.getNil();
|
163
147
|
}
|
164
148
|
|
data/ext/msgpack/buffer.c
CHANGED
@@ -251,12 +251,14 @@ bool _msgpack_buffer_read_all2(msgpack_buffer_t* b, char* buffer, size_t length)
|
|
251
251
|
|
252
252
|
static inline msgpack_buffer_chunk_t* _msgpack_buffer_alloc_new_chunk(msgpack_buffer_t* b)
|
253
253
|
{
|
254
|
-
msgpack_buffer_chunk_t*
|
255
|
-
if(
|
256
|
-
|
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));
|
257
259
|
}
|
258
|
-
|
259
|
-
return
|
260
|
+
memset(chunk, 0, sizeof(msgpack_buffer_chunk_t));
|
261
|
+
return chunk;
|
260
262
|
}
|
261
263
|
|
262
264
|
static inline void _msgpack_buffer_add_new_chunk(msgpack_buffer_t* b)
|
data/ext/msgpack/buffer.h
CHANGED
@@ -268,7 +268,9 @@ static inline size_t msgpack_buffer_append_string(msgpack_buffer_t* b, VALUE str
|
|
268
268
|
static inline size_t msgpack_buffer_append_string_reference(msgpack_buffer_t* b, VALUE string)
|
269
269
|
{
|
270
270
|
size_t length = RSTRING_LEN(string);
|
271
|
-
|
271
|
+
if (length > 0) {
|
272
|
+
_msgpack_buffer_append_long_string(b, string);
|
273
|
+
}
|
272
274
|
return length;
|
273
275
|
}
|
274
276
|
|
data/ext/msgpack/buffer_class.c
CHANGED
@@ -21,7 +21,8 @@
|
|
21
21
|
#include "buffer.h"
|
22
22
|
#include "buffer_class.h"
|
23
23
|
|
24
|
-
VALUE cMessagePack_Buffer;
|
24
|
+
VALUE cMessagePack_Buffer = Qnil;
|
25
|
+
VALUE cMessagePack_HeldBuffer = Qnil;
|
25
26
|
|
26
27
|
static ID s_read;
|
27
28
|
static ID s_readpartial;
|
@@ -34,6 +35,73 @@ static VALUE sym_read_reference_threshold;
|
|
34
35
|
static VALUE sym_write_reference_threshold;
|
35
36
|
static VALUE sym_io_buffer_size;
|
36
37
|
|
38
|
+
typedef struct msgpack_held_buffer_t msgpack_held_buffer_t;
|
39
|
+
struct msgpack_held_buffer_t {
|
40
|
+
size_t size;
|
41
|
+
VALUE mapped_strings[];
|
42
|
+
};
|
43
|
+
|
44
|
+
static void HeldBuffer_mark(void *data)
|
45
|
+
{
|
46
|
+
msgpack_held_buffer_t* held_buffer = (msgpack_held_buffer_t*)data;
|
47
|
+
for (size_t index = 0; index < held_buffer->size; index++) {
|
48
|
+
rb_gc_mark(held_buffer->mapped_strings[index]);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
static size_t HeldBuffer_memsize(const void *data)
|
53
|
+
{
|
54
|
+
const msgpack_held_buffer_t* held_buffer = (msgpack_held_buffer_t*)data;
|
55
|
+
return sizeof(size_t) + sizeof(VALUE) * held_buffer->size;
|
56
|
+
}
|
57
|
+
|
58
|
+
static const rb_data_type_t held_buffer_data_type = {
|
59
|
+
.wrap_struct_name = "msgpack:held_buffer",
|
60
|
+
.function = {
|
61
|
+
.dmark = HeldBuffer_mark,
|
62
|
+
.dfree = RUBY_TYPED_DEFAULT_FREE,
|
63
|
+
.dsize = HeldBuffer_memsize,
|
64
|
+
},
|
65
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
66
|
+
};
|
67
|
+
|
68
|
+
VALUE MessagePack_Buffer_hold(msgpack_buffer_t* buffer)
|
69
|
+
{
|
70
|
+
size_t mapped_strings_count = 0;
|
71
|
+
msgpack_buffer_chunk_t* c = buffer->head;
|
72
|
+
while (c != &buffer->tail) {
|
73
|
+
if (c->mapped_string != NO_MAPPED_STRING) {
|
74
|
+
mapped_strings_count++;
|
75
|
+
}
|
76
|
+
c = c->next;
|
77
|
+
}
|
78
|
+
if (c->mapped_string != NO_MAPPED_STRING) {
|
79
|
+
mapped_strings_count++;
|
80
|
+
}
|
81
|
+
|
82
|
+
if (mapped_strings_count == 0) {
|
83
|
+
return Qnil;
|
84
|
+
}
|
85
|
+
|
86
|
+
msgpack_held_buffer_t* held_buffer = xmalloc(sizeof(msgpack_held_buffer_t) + mapped_strings_count * sizeof(VALUE));
|
87
|
+
|
88
|
+
c = buffer->head;
|
89
|
+
mapped_strings_count = 0;
|
90
|
+
while (c != &buffer->tail) {
|
91
|
+
if (c->mapped_string != NO_MAPPED_STRING) {
|
92
|
+
held_buffer->mapped_strings[mapped_strings_count] = c->mapped_string;
|
93
|
+
mapped_strings_count++;
|
94
|
+
}
|
95
|
+
c = c->next;
|
96
|
+
}
|
97
|
+
if (c->mapped_string != NO_MAPPED_STRING) {
|
98
|
+
held_buffer->mapped_strings[mapped_strings_count] = c->mapped_string;
|
99
|
+
mapped_strings_count++;
|
100
|
+
}
|
101
|
+
held_buffer->size = mapped_strings_count;
|
102
|
+
return TypedData_Wrap_Struct(cMessagePack_HeldBuffer, &held_buffer_data_type, held_buffer);
|
103
|
+
}
|
104
|
+
|
37
105
|
|
38
106
|
#define CHECK_STRING_TYPE(value) \
|
39
107
|
value = rb_check_string_type(value); \
|
@@ -520,6 +588,9 @@ void MessagePack_Buffer_module_init(VALUE mMessagePack)
|
|
520
588
|
|
521
589
|
msgpack_buffer_static_init();
|
522
590
|
|
591
|
+
cMessagePack_HeldBuffer = rb_define_class_under(mMessagePack, "HeldBuffer", rb_cBasicObject);
|
592
|
+
rb_undef_alloc_func(cMessagePack_HeldBuffer);
|
593
|
+
|
523
594
|
cMessagePack_Buffer = rb_define_class_under(mMessagePack, "Buffer", rb_cObject);
|
524
595
|
|
525
596
|
rb_define_alloc_func(cMessagePack_Buffer, Buffer_alloc);
|
data/ext/msgpack/buffer_class.h
CHANGED
@@ -25,6 +25,7 @@ extern VALUE cMessagePack_Buffer;
|
|
25
25
|
void MessagePack_Buffer_module_init(VALUE mMessagePack);
|
26
26
|
|
27
27
|
VALUE MessagePack_Buffer_wrap(msgpack_buffer_t* b, VALUE owner);
|
28
|
+
VALUE MessagePack_Buffer_hold(msgpack_buffer_t* b);
|
28
29
|
|
29
30
|
void MessagePack_Buffer_set_options(msgpack_buffer_t* b, VALUE io, VALUE options);
|
30
31
|
|
data/ext/msgpack/extconf.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'mkmf'
|
2
2
|
|
3
|
-
have_header("ruby/st.h")
|
4
|
-
have_header("st.h")
|
5
3
|
have_func("rb_enc_interned_str", "ruby.h") # Ruby 3.0+
|
6
4
|
have_func("rb_hash_new_capa", "ruby.h") # Ruby 3.2+
|
5
|
+
have_func("rb_proc_call_with_block", "ruby.h") # CRuby (TruffleRuby doesn't have it)
|
7
6
|
|
8
7
|
append_cflags([
|
9
8
|
"-fvisibility=hidden",
|
data/ext/msgpack/factory_class.c
CHANGED
@@ -75,7 +75,7 @@ static const rb_data_type_t factory_data_type = {
|
|
75
75
|
.dfree = Factory_free,
|
76
76
|
.dsize = Factory_memsize,
|
77
77
|
},
|
78
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
78
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
79
79
|
};
|
80
80
|
|
81
81
|
static inline msgpack_factory_t *Factory_get(VALUE object)
|
@@ -98,7 +98,7 @@ static VALUE Factory_initialize(int argc, VALUE* argv, VALUE self)
|
|
98
98
|
{
|
99
99
|
msgpack_factory_t *fc = Factory_get(self);
|
100
100
|
|
101
|
-
msgpack_packer_ext_registry_init(&fc->pkrg);
|
101
|
+
msgpack_packer_ext_registry_init(self, &fc->pkrg);
|
102
102
|
// fc->ukrg is lazily initialized
|
103
103
|
|
104
104
|
fc->has_symbol_ext_type = false;
|
@@ -124,7 +124,7 @@ static VALUE Factory_dup(VALUE self)
|
|
124
124
|
cloned_fc->has_symbol_ext_type = fc->has_symbol_ext_type;
|
125
125
|
cloned_fc->pkrg = fc->pkrg;
|
126
126
|
msgpack_unpacker_ext_registry_borrow(fc->ukrg, &cloned_fc->ukrg);
|
127
|
-
msgpack_packer_ext_registry_dup(&fc->pkrg, &cloned_fc->pkrg);
|
127
|
+
msgpack_packer_ext_registry_dup(clone, &fc->pkrg, &cloned_fc->pkrg);
|
128
128
|
|
129
129
|
return clone;
|
130
130
|
}
|
@@ -139,7 +139,7 @@ static VALUE Factory_freeze(VALUE self) {
|
|
139
139
|
// If the factory is frozen, we can safely share the packer cache between
|
140
140
|
// all packers. So we eagerly create it now so it's available when #packer
|
141
141
|
// is called.
|
142
|
-
fc->pkrg.cache
|
142
|
+
RB_OBJ_WRITE(self, &fc->pkrg.cache, rb_hash_new());
|
143
143
|
}
|
144
144
|
}
|
145
145
|
|
@@ -158,7 +158,7 @@ VALUE MessagePack_Factory_packer(int argc, VALUE* argv, VALUE self)
|
|
158
158
|
|
159
159
|
msgpack_packer_t* pk = MessagePack_Packer_get(packer);
|
160
160
|
msgpack_packer_ext_registry_destroy(&pk->ext_registry);
|
161
|
-
|
161
|
+
msgpack_packer_ext_registry_borrow(packer, &fc->pkrg, &pk->ext_registry);
|
162
162
|
pk->has_bigint_ext_type = fc->has_bigint_ext_type;
|
163
163
|
pk->has_symbol_ext_type = fc->has_symbol_ext_type;
|
164
164
|
|
@@ -187,7 +187,7 @@ static VALUE Factory_registered_types_internal(VALUE self)
|
|
187
187
|
VALUE uk_mapping = rb_hash_new();
|
188
188
|
if (fc->ukrg) {
|
189
189
|
for(int i=0; i < 256; i++) {
|
190
|
-
if(fc->ukrg->array[i]
|
190
|
+
if(!NIL_P(fc->ukrg->array[i])) {
|
191
191
|
rb_hash_aset(uk_mapping, INT2FIX(i - 128), fc->ukrg->array[i]);
|
192
192
|
}
|
193
193
|
}
|
@@ -200,72 +200,35 @@ static VALUE Factory_registered_types_internal(VALUE self)
|
|
200
200
|
);
|
201
201
|
}
|
202
202
|
|
203
|
-
static VALUE
|
203
|
+
static VALUE Factory_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE options)
|
204
204
|
{
|
205
205
|
msgpack_factory_t *fc = Factory_get(self);
|
206
206
|
|
207
|
-
|
208
|
-
int flags = 0;
|
209
|
-
VALUE ext_module;
|
210
|
-
VALUE options = Qnil;
|
211
|
-
VALUE packer_arg, unpacker_arg;
|
212
|
-
VALUE packer_proc, unpacker_proc;
|
207
|
+
Check_Type(rb_ext_type, T_FIXNUM);
|
213
208
|
|
214
|
-
if
|
215
|
-
rb_raise(
|
209
|
+
if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
|
210
|
+
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
216
211
|
}
|
217
212
|
|
218
|
-
|
219
|
-
case 2:
|
220
|
-
/* register_type(0x7f, Time) */
|
221
|
-
packer_arg = ID2SYM(rb_intern("to_msgpack_ext"));
|
222
|
-
unpacker_arg = ID2SYM(rb_intern("from_msgpack_ext"));
|
223
|
-
break;
|
224
|
-
case 3:
|
225
|
-
/* register_type(0x7f, Time, packer: proc-like, unpacker: proc-like) */
|
226
|
-
options = argv[2];
|
227
|
-
if(rb_type(options) != T_HASH) {
|
228
|
-
rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
|
229
|
-
}
|
213
|
+
int flags = 0;
|
230
214
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
215
|
+
VALUE packer_proc = Qnil;
|
216
|
+
VALUE unpacker_proc = Qnil;
|
217
|
+
if(!NIL_P(options)) {
|
218
|
+
Check_Type(options, T_HASH);
|
219
|
+
packer_proc = rb_hash_aref(options, ID2SYM(rb_intern("packer")));
|
220
|
+
unpacker_proc = rb_hash_aref(options, ID2SYM(rb_intern("unpacker")));
|
236
221
|
}
|
237
222
|
|
238
|
-
if (
|
239
|
-
|
223
|
+
if (OBJ_FROZEN(self)) {
|
224
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Factory");
|
240
225
|
}
|
241
226
|
|
242
|
-
ext_type = NUM2INT(
|
227
|
+
int ext_type = NUM2INT(rb_ext_type);
|
243
228
|
if(ext_type < -128 || ext_type > 127) {
|
244
229
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
245
230
|
}
|
246
231
|
|
247
|
-
ext_module = argv[1];
|
248
|
-
if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
|
249
|
-
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
250
|
-
}
|
251
|
-
|
252
|
-
packer_proc = Qnil;
|
253
|
-
unpacker_proc = Qnil;
|
254
|
-
|
255
|
-
if(packer_arg != Qnil) {
|
256
|
-
packer_proc = rb_funcall(packer_arg, rb_intern("to_proc"), 0);
|
257
|
-
}
|
258
|
-
|
259
|
-
if(unpacker_arg != Qnil) {
|
260
|
-
if(rb_type(unpacker_arg) == T_SYMBOL || rb_type(unpacker_arg) == T_STRING) {
|
261
|
-
unpacker_proc = rb_obj_method(ext_module, unpacker_arg);
|
262
|
-
} else if (rb_respond_to(unpacker_arg, rb_intern("call"))) {
|
263
|
-
unpacker_proc = unpacker_arg;
|
264
|
-
} else {
|
265
|
-
unpacker_proc = rb_funcall(unpacker_arg, rb_intern("method"), 1, ID2SYM(rb_intern("call")));
|
266
|
-
}
|
267
|
-
}
|
268
|
-
|
269
232
|
if(ext_module == rb_cSymbol) {
|
270
233
|
if(NIL_P(options) || RTEST(rb_hash_aref(options, ID2SYM(rb_intern("packer"))))) {
|
271
234
|
fc->has_symbol_ext_type = true;
|
@@ -289,8 +252,8 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
289
252
|
}
|
290
253
|
}
|
291
254
|
|
292
|
-
msgpack_packer_ext_registry_put(&fc->pkrg, ext_module, ext_type, flags, packer_proc
|
293
|
-
msgpack_unpacker_ext_registry_put(&fc->ukrg, ext_module, ext_type, flags, unpacker_proc
|
255
|
+
msgpack_packer_ext_registry_put(self, &fc->pkrg, ext_module, ext_type, flags, packer_proc);
|
256
|
+
msgpack_unpacker_ext_registry_put(self, &fc->ukrg, ext_module, ext_type, flags, unpacker_proc);
|
294
257
|
|
295
258
|
return Qnil;
|
296
259
|
}
|
@@ -309,5 +272,5 @@ void MessagePack_Factory_module_init(VALUE mMessagePack)
|
|
309
272
|
rb_define_method(cMessagePack_Factory, "unpacker", MessagePack_Factory_unpacker, -1);
|
310
273
|
|
311
274
|
rb_define_private_method(cMessagePack_Factory, "registered_types_internal", Factory_registered_types_internal, 0);
|
312
|
-
|
275
|
+
rb_define_private_method(cMessagePack_Factory, "register_type_internal", Factory_register_type_internal, 3);
|
313
276
|
}
|