ed-precompiled_msgpack 1.8.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 +7 -0
- data/ChangeLog +368 -0
- data/LICENSE +177 -0
- data/README.md +302 -0
- data/ext/java/org/msgpack/jruby/Buffer.java +233 -0
- data/ext/java/org/msgpack/jruby/Decoder.java +307 -0
- data/ext/java/org/msgpack/jruby/Encoder.java +456 -0
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +167 -0
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +128 -0
- data/ext/java/org/msgpack/jruby/Factory.java +130 -0
- data/ext/java/org/msgpack/jruby/MessagePackLibrary.java +45 -0
- data/ext/java/org/msgpack/jruby/Packer.java +266 -0
- data/ext/java/org/msgpack/jruby/Types.java +37 -0
- data/ext/java/org/msgpack/jruby/Unpacker.java +336 -0
- data/ext/msgpack/buffer.c +669 -0
- data/ext/msgpack/buffer.h +604 -0
- data/ext/msgpack/buffer_class.c +616 -0
- data/ext/msgpack/buffer_class.h +33 -0
- data/ext/msgpack/compat.h +26 -0
- data/ext/msgpack/extconf.rb +53 -0
- data/ext/msgpack/extension_value_class.c +34 -0
- data/ext/msgpack/extension_value_class.h +31 -0
- data/ext/msgpack/factory_class.c +276 -0
- data/ext/msgpack/factory_class.h +33 -0
- data/ext/msgpack/packer.c +199 -0
- data/ext/msgpack/packer.h +513 -0
- data/ext/msgpack/packer_class.c +442 -0
- data/ext/msgpack/packer_class.h +43 -0
- data/ext/msgpack/packer_ext_registry.c +74 -0
- data/ext/msgpack/packer_ext_registry.h +140 -0
- data/ext/msgpack/rbinit.c +35 -0
- data/ext/msgpack/rmem.c +93 -0
- data/ext/msgpack/rmem.h +109 -0
- data/ext/msgpack/sysdep.h +118 -0
- data/ext/msgpack/sysdep_endian.h +50 -0
- data/ext/msgpack/sysdep_types.h +46 -0
- data/ext/msgpack/unpacker.c +986 -0
- data/ext/msgpack/unpacker.h +152 -0
- data/ext/msgpack/unpacker_class.c +447 -0
- data/ext/msgpack/unpacker_class.h +43 -0
- data/ext/msgpack/unpacker_ext_registry.c +74 -0
- data/ext/msgpack/unpacker_ext_registry.h +62 -0
- data/lib/msgpack/bigint.rb +69 -0
- data/lib/msgpack/buffer.rb +9 -0
- data/lib/msgpack/core_ext.rb +139 -0
- data/lib/msgpack/factory.rb +211 -0
- data/lib/msgpack/packer.rb +37 -0
- data/lib/msgpack/symbol.rb +26 -0
- data/lib/msgpack/time.rb +29 -0
- data/lib/msgpack/timestamp.rb +76 -0
- data/lib/msgpack/unpacker.rb +41 -0
- data/lib/msgpack/version.rb +6 -0
- data/lib/msgpack.rb +53 -0
- data/msgpack.gemspec +41 -0
- metadata +216 -0
@@ -0,0 +1,442 @@
|
|
1
|
+
/*
|
2
|
+
* MessagePack for Ruby
|
3
|
+
*
|
4
|
+
* Copyright (C) 2008-2013 Sadayuki Furuhashi
|
5
|
+
*
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
* you may not use this file except in compliance with the License.
|
8
|
+
* You may obtain a copy of the License at
|
9
|
+
*
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
*
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
* See the License for the specific language governing permissions and
|
16
|
+
* limitations under the License.
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include "compat.h"
|
20
|
+
#include "ruby.h"
|
21
|
+
#include "packer.h"
|
22
|
+
#include "packer_class.h"
|
23
|
+
#include "buffer_class.h"
|
24
|
+
#include "factory_class.h"
|
25
|
+
|
26
|
+
VALUE cMessagePack_Packer;
|
27
|
+
|
28
|
+
static ID s_to_msgpack;
|
29
|
+
static ID s_write;
|
30
|
+
|
31
|
+
static VALUE sym_compatibility_mode;
|
32
|
+
|
33
|
+
//static VALUE s_packer_value;
|
34
|
+
//static msgpack_packer_t* s_packer;
|
35
|
+
|
36
|
+
static void Packer_free(void *ptr)
|
37
|
+
{
|
38
|
+
msgpack_packer_t* pk = ptr;
|
39
|
+
if(pk == NULL) {
|
40
|
+
return;
|
41
|
+
}
|
42
|
+
msgpack_packer_ext_registry_destroy(&pk->ext_registry);
|
43
|
+
msgpack_packer_destroy(pk);
|
44
|
+
xfree(pk);
|
45
|
+
}
|
46
|
+
|
47
|
+
static void Packer_mark(void *ptr)
|
48
|
+
{
|
49
|
+
msgpack_packer_t* pk = ptr;
|
50
|
+
msgpack_buffer_mark(pk);
|
51
|
+
msgpack_packer_mark(pk);
|
52
|
+
msgpack_packer_ext_registry_mark(&pk->ext_registry);
|
53
|
+
}
|
54
|
+
|
55
|
+
static size_t Packer_memsize(const void *ptr)
|
56
|
+
{
|
57
|
+
const msgpack_packer_t* pk = ptr;
|
58
|
+
return sizeof(msgpack_packer_t) + msgpack_buffer_memsize(&pk->buffer);
|
59
|
+
}
|
60
|
+
|
61
|
+
const rb_data_type_t packer_data_type = {
|
62
|
+
.wrap_struct_name = "msgpack:packer",
|
63
|
+
.function = {
|
64
|
+
.dmark = Packer_mark,
|
65
|
+
.dfree = Packer_free,
|
66
|
+
.dsize = Packer_memsize,
|
67
|
+
},
|
68
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
69
|
+
};
|
70
|
+
|
71
|
+
|
72
|
+
VALUE MessagePack_Packer_alloc(VALUE klass)
|
73
|
+
{
|
74
|
+
msgpack_packer_t* pk;
|
75
|
+
VALUE self = TypedData_Make_Struct(klass, msgpack_packer_t, &packer_data_type, pk);
|
76
|
+
msgpack_packer_init(pk);
|
77
|
+
msgpack_packer_set_to_msgpack_method(pk, s_to_msgpack, self);
|
78
|
+
return self;
|
79
|
+
}
|
80
|
+
|
81
|
+
VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
|
82
|
+
{
|
83
|
+
if(argc > 2) {
|
84
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
|
85
|
+
}
|
86
|
+
|
87
|
+
VALUE io = Qnil;
|
88
|
+
VALUE options = Qnil;
|
89
|
+
|
90
|
+
if(argc >= 1) {
|
91
|
+
io = argv[0];
|
92
|
+
}
|
93
|
+
|
94
|
+
if(argc == 2) {
|
95
|
+
options = argv[1];
|
96
|
+
}
|
97
|
+
|
98
|
+
if (options == Qnil && rb_type(io) == T_HASH) {
|
99
|
+
options = io;
|
100
|
+
io = Qnil;
|
101
|
+
}
|
102
|
+
|
103
|
+
if(options != Qnil) {
|
104
|
+
Check_Type(options, T_HASH);
|
105
|
+
}
|
106
|
+
|
107
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
108
|
+
|
109
|
+
msgpack_packer_ext_registry_init(self, &pk->ext_registry);
|
110
|
+
pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self);
|
111
|
+
|
112
|
+
MessagePack_Buffer_set_options(PACKER_BUFFER_(pk), io, options);
|
113
|
+
|
114
|
+
if(options != Qnil) {
|
115
|
+
VALUE v;
|
116
|
+
|
117
|
+
v = rb_hash_aref(options, sym_compatibility_mode);
|
118
|
+
msgpack_packer_set_compat(pk, RTEST(v));
|
119
|
+
}
|
120
|
+
|
121
|
+
return self;
|
122
|
+
}
|
123
|
+
|
124
|
+
static VALUE Packer_compatibility_mode_p(VALUE self)
|
125
|
+
{
|
126
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
127
|
+
return pk->compatibility_mode ? Qtrue : Qfalse;
|
128
|
+
}
|
129
|
+
|
130
|
+
static VALUE Packer_buffer(VALUE self)
|
131
|
+
{
|
132
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
133
|
+
if (!RTEST(pk->buffer_ref)) {
|
134
|
+
pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self);
|
135
|
+
}
|
136
|
+
return pk->buffer_ref;
|
137
|
+
}
|
138
|
+
|
139
|
+
static VALUE Packer_write(VALUE self, VALUE v)
|
140
|
+
{
|
141
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
142
|
+
msgpack_packer_write_value(pk, v);
|
143
|
+
return self;
|
144
|
+
}
|
145
|
+
|
146
|
+
static VALUE Packer_write_nil(VALUE self)
|
147
|
+
{
|
148
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
149
|
+
msgpack_packer_write_nil(pk);
|
150
|
+
return self;
|
151
|
+
}
|
152
|
+
|
153
|
+
static VALUE Packer_write_true(VALUE self)
|
154
|
+
{
|
155
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
156
|
+
msgpack_packer_write_true(pk);
|
157
|
+
return self;
|
158
|
+
}
|
159
|
+
|
160
|
+
static VALUE Packer_write_false(VALUE self)
|
161
|
+
{
|
162
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
163
|
+
msgpack_packer_write_false(pk);
|
164
|
+
return self;
|
165
|
+
}
|
166
|
+
|
167
|
+
static VALUE Packer_write_float(VALUE self, VALUE obj)
|
168
|
+
{
|
169
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
170
|
+
msgpack_packer_write_float_value(pk, obj);
|
171
|
+
return self;
|
172
|
+
}
|
173
|
+
|
174
|
+
static VALUE Packer_write_string(VALUE self, VALUE obj)
|
175
|
+
{
|
176
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
177
|
+
Check_Type(obj, T_STRING);
|
178
|
+
msgpack_packer_write_string_value(pk, obj);
|
179
|
+
return self;
|
180
|
+
}
|
181
|
+
|
182
|
+
static VALUE Packer_write_bin(VALUE self, VALUE obj)
|
183
|
+
{
|
184
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
185
|
+
Check_Type(obj, T_STRING);
|
186
|
+
|
187
|
+
VALUE enc = rb_enc_from_encoding(rb_ascii8bit_encoding());
|
188
|
+
obj = rb_str_encode(obj, enc, 0, Qnil);
|
189
|
+
|
190
|
+
msgpack_packer_write_string_value(pk, obj);
|
191
|
+
return self;
|
192
|
+
}
|
193
|
+
|
194
|
+
static VALUE Packer_write_array(VALUE self, VALUE obj)
|
195
|
+
{
|
196
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
197
|
+
Check_Type(obj, T_ARRAY);
|
198
|
+
msgpack_packer_write_array_value(pk, obj);
|
199
|
+
return self;
|
200
|
+
}
|
201
|
+
|
202
|
+
static VALUE Packer_write_hash(VALUE self, VALUE obj)
|
203
|
+
{
|
204
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
205
|
+
Check_Type(obj, T_HASH);
|
206
|
+
msgpack_packer_write_hash_value(pk, obj);
|
207
|
+
return self;
|
208
|
+
}
|
209
|
+
|
210
|
+
static VALUE Packer_write_symbol(VALUE self, VALUE obj)
|
211
|
+
{
|
212
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
213
|
+
Check_Type(obj, T_SYMBOL);
|
214
|
+
msgpack_packer_write_symbol_value(pk, obj);
|
215
|
+
return self;
|
216
|
+
}
|
217
|
+
|
218
|
+
static VALUE Packer_write_int(VALUE self, VALUE obj)
|
219
|
+
{
|
220
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
221
|
+
|
222
|
+
if (FIXNUM_P(obj)) {
|
223
|
+
msgpack_packer_write_fixnum_value(pk, obj);
|
224
|
+
} else {
|
225
|
+
Check_Type(obj, T_BIGNUM);
|
226
|
+
msgpack_packer_write_bignum_value(pk, obj);
|
227
|
+
}
|
228
|
+
return self;
|
229
|
+
}
|
230
|
+
|
231
|
+
static VALUE Packer_write_extension(VALUE self, VALUE obj)
|
232
|
+
{
|
233
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
234
|
+
Check_Type(obj, T_STRUCT);
|
235
|
+
|
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);
|
242
|
+
if(ext_type < -128 || ext_type > 127) {
|
243
|
+
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
244
|
+
}
|
245
|
+
VALUE payload = RSTRUCT_GET(obj, 1);
|
246
|
+
StringValue(payload);
|
247
|
+
msgpack_packer_write_ext(pk, ext_type, payload);
|
248
|
+
|
249
|
+
return self;
|
250
|
+
}
|
251
|
+
|
252
|
+
static VALUE Packer_write_array_header(VALUE self, VALUE n)
|
253
|
+
{
|
254
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
255
|
+
msgpack_packer_write_array_header(pk, NUM2UINT(n));
|
256
|
+
return self;
|
257
|
+
}
|
258
|
+
|
259
|
+
static VALUE Packer_write_map_header(VALUE self, VALUE n)
|
260
|
+
{
|
261
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
262
|
+
msgpack_packer_write_map_header(pk, NUM2UINT(n));
|
263
|
+
return self;
|
264
|
+
}
|
265
|
+
|
266
|
+
static VALUE Packer_write_bin_header(VALUE self, VALUE n)
|
267
|
+
{
|
268
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
269
|
+
msgpack_packer_write_bin_header(pk, NUM2UINT(n));
|
270
|
+
return self;
|
271
|
+
}
|
272
|
+
|
273
|
+
static VALUE Packer_write_float32(VALUE self, VALUE numeric)
|
274
|
+
{
|
275
|
+
if(!rb_obj_is_kind_of(numeric, rb_cNumeric)) {
|
276
|
+
rb_raise(rb_eArgError, "Expected numeric");
|
277
|
+
}
|
278
|
+
|
279
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
280
|
+
msgpack_packer_write_float(pk, (float)rb_num2dbl(numeric));
|
281
|
+
return self;
|
282
|
+
}
|
283
|
+
|
284
|
+
static VALUE Packer_write_ext(VALUE self, VALUE type, VALUE data)
|
285
|
+
{
|
286
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
287
|
+
int ext_type = NUM2INT(type);
|
288
|
+
if(ext_type < -128 || ext_type > 127) {
|
289
|
+
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
290
|
+
}
|
291
|
+
StringValue(data);
|
292
|
+
msgpack_packer_write_ext(pk, ext_type, data);
|
293
|
+
return self;
|
294
|
+
}
|
295
|
+
|
296
|
+
static VALUE Packer_flush(VALUE self)
|
297
|
+
{
|
298
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
299
|
+
msgpack_buffer_flush(PACKER_BUFFER_(pk));
|
300
|
+
return self;
|
301
|
+
}
|
302
|
+
|
303
|
+
static VALUE Packer_reset(VALUE self)
|
304
|
+
{
|
305
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
306
|
+
msgpack_buffer_clear(PACKER_BUFFER_(pk));
|
307
|
+
return Qnil;
|
308
|
+
}
|
309
|
+
|
310
|
+
static VALUE Packer_size(VALUE self)
|
311
|
+
{
|
312
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
313
|
+
size_t size = msgpack_buffer_all_readable_size(PACKER_BUFFER_(pk));
|
314
|
+
return SIZET2NUM(size);
|
315
|
+
}
|
316
|
+
|
317
|
+
static VALUE Packer_empty_p(VALUE self)
|
318
|
+
{
|
319
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
320
|
+
if(msgpack_buffer_top_readable_size(PACKER_BUFFER_(pk)) == 0) {
|
321
|
+
return Qtrue;
|
322
|
+
} else {
|
323
|
+
return Qfalse;
|
324
|
+
}
|
325
|
+
}
|
326
|
+
|
327
|
+
static VALUE Packer_to_str(VALUE self)
|
328
|
+
{
|
329
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
330
|
+
return msgpack_buffer_all_as_string(PACKER_BUFFER_(pk));
|
331
|
+
}
|
332
|
+
|
333
|
+
static VALUE Packer_to_a(VALUE self)
|
334
|
+
{
|
335
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
336
|
+
return msgpack_buffer_all_as_string_array(PACKER_BUFFER_(pk));
|
337
|
+
}
|
338
|
+
|
339
|
+
static VALUE Packer_write_to(VALUE self, VALUE io)
|
340
|
+
{
|
341
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
342
|
+
size_t sz = msgpack_buffer_flush_to_io(PACKER_BUFFER_(pk), io, s_write, true);
|
343
|
+
return SIZET2NUM(sz);
|
344
|
+
}
|
345
|
+
|
346
|
+
static VALUE Packer_registered_types_internal(VALUE self)
|
347
|
+
{
|
348
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
349
|
+
if (RTEST(pk->ext_registry.hash)) {
|
350
|
+
return rb_hash_dup(pk->ext_registry.hash);
|
351
|
+
}
|
352
|
+
return rb_hash_new();
|
353
|
+
}
|
354
|
+
|
355
|
+
static VALUE Packer_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
|
356
|
+
{
|
357
|
+
if (OBJ_FROZEN(self)) {
|
358
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Packer");
|
359
|
+
}
|
360
|
+
|
361
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
362
|
+
|
363
|
+
int ext_type = NUM2INT(rb_ext_type);
|
364
|
+
if(ext_type < -128 || ext_type > 127) {
|
365
|
+
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
366
|
+
}
|
367
|
+
|
368
|
+
msgpack_packer_ext_registry_put(self, &pk->ext_registry, ext_module, ext_type, 0, proc);
|
369
|
+
|
370
|
+
if (ext_module == rb_cSymbol) {
|
371
|
+
pk->has_symbol_ext_type = true;
|
372
|
+
}
|
373
|
+
|
374
|
+
return Qnil;
|
375
|
+
}
|
376
|
+
|
377
|
+
VALUE Packer_full_pack(VALUE self)
|
378
|
+
{
|
379
|
+
VALUE retval;
|
380
|
+
|
381
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
382
|
+
|
383
|
+
if(msgpack_buffer_has_io(PACKER_BUFFER_(pk))) {
|
384
|
+
msgpack_buffer_flush(PACKER_BUFFER_(pk));
|
385
|
+
retval = Qnil;
|
386
|
+
} else {
|
387
|
+
retval = msgpack_buffer_all_as_string(PACKER_BUFFER_(pk));
|
388
|
+
}
|
389
|
+
|
390
|
+
msgpack_buffer_clear(PACKER_BUFFER_(pk)); /* to free rmem before GC */
|
391
|
+
|
392
|
+
return retval;
|
393
|
+
}
|
394
|
+
|
395
|
+
void MessagePack_Packer_module_init(VALUE mMessagePack)
|
396
|
+
{
|
397
|
+
s_to_msgpack = rb_intern("to_msgpack");
|
398
|
+
s_write = rb_intern("write");
|
399
|
+
|
400
|
+
sym_compatibility_mode = ID2SYM(rb_intern("compatibility_mode"));
|
401
|
+
cMessagePack_Packer = rb_define_class_under(mMessagePack, "Packer", rb_cObject);
|
402
|
+
|
403
|
+
rb_define_alloc_func(cMessagePack_Packer, MessagePack_Packer_alloc);
|
404
|
+
|
405
|
+
rb_define_method(cMessagePack_Packer, "initialize", MessagePack_Packer_initialize, -1);
|
406
|
+
rb_define_method(cMessagePack_Packer, "compatibility_mode?", Packer_compatibility_mode_p, 0);
|
407
|
+
rb_define_method(cMessagePack_Packer, "buffer", Packer_buffer, 0);
|
408
|
+
rb_define_method(cMessagePack_Packer, "write", Packer_write, 1);
|
409
|
+
rb_define_alias(cMessagePack_Packer, "pack", "write");
|
410
|
+
rb_define_method(cMessagePack_Packer, "write_nil", Packer_write_nil, 0);
|
411
|
+
rb_define_method(cMessagePack_Packer, "write_true", Packer_write_true, 0);
|
412
|
+
rb_define_method(cMessagePack_Packer, "write_false", Packer_write_false, 0);
|
413
|
+
rb_define_method(cMessagePack_Packer, "write_float", Packer_write_float, 1);
|
414
|
+
rb_define_method(cMessagePack_Packer, "write_string", Packer_write_string, 1);
|
415
|
+
rb_define_method(cMessagePack_Packer, "write_bin", Packer_write_bin, 1);
|
416
|
+
rb_define_method(cMessagePack_Packer, "write_array", Packer_write_array, 1);
|
417
|
+
rb_define_method(cMessagePack_Packer, "write_hash", Packer_write_hash, 1);
|
418
|
+
rb_define_method(cMessagePack_Packer, "write_symbol", Packer_write_symbol, 1);
|
419
|
+
rb_define_method(cMessagePack_Packer, "write_int", Packer_write_int, 1);
|
420
|
+
rb_define_method(cMessagePack_Packer, "write_extension", Packer_write_extension, 1);
|
421
|
+
rb_define_method(cMessagePack_Packer, "write_array_header", Packer_write_array_header, 1);
|
422
|
+
rb_define_method(cMessagePack_Packer, "write_map_header", Packer_write_map_header, 1);
|
423
|
+
rb_define_method(cMessagePack_Packer, "write_bin_header", Packer_write_bin_header, 1);
|
424
|
+
rb_define_method(cMessagePack_Packer, "write_ext", Packer_write_ext, 2);
|
425
|
+
rb_define_method(cMessagePack_Packer, "write_float32", Packer_write_float32, 1);
|
426
|
+
rb_define_method(cMessagePack_Packer, "flush", Packer_flush, 0);
|
427
|
+
|
428
|
+
/* delegation methods */
|
429
|
+
rb_define_method(cMessagePack_Packer, "reset", Packer_reset, 0);
|
430
|
+
rb_define_alias(cMessagePack_Packer, "clear", "reset");
|
431
|
+
rb_define_method(cMessagePack_Packer, "size", Packer_size, 0);
|
432
|
+
rb_define_method(cMessagePack_Packer, "empty?", Packer_empty_p, 0);
|
433
|
+
rb_define_method(cMessagePack_Packer, "write_to", Packer_write_to, 1);
|
434
|
+
rb_define_method(cMessagePack_Packer, "to_str", Packer_to_str, 0);
|
435
|
+
rb_define_alias(cMessagePack_Packer, "to_s", "to_str");
|
436
|
+
rb_define_method(cMessagePack_Packer, "to_a", Packer_to_a, 0);
|
437
|
+
|
438
|
+
rb_define_private_method(cMessagePack_Packer, "registered_types_internal", Packer_registered_types_internal, 0);
|
439
|
+
rb_define_method(cMessagePack_Packer, "register_type_internal", Packer_register_type_internal, 3);
|
440
|
+
|
441
|
+
rb_define_method(cMessagePack_Packer, "full_pack", Packer_full_pack, 0);
|
442
|
+
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
/*
|
2
|
+
* MessagePack for Ruby
|
3
|
+
*
|
4
|
+
* Copyright (C) 2008-2013 Sadayuki Furuhashi
|
5
|
+
*
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
* you may not use this file except in compliance with the License.
|
8
|
+
* You may obtain a copy of the License at
|
9
|
+
*
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
*
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
* See the License for the specific language governing permissions and
|
16
|
+
* limitations under the License.
|
17
|
+
*/
|
18
|
+
#ifndef MSGPACK_RUBY_PACKER_CLASS_H__
|
19
|
+
#define MSGPACK_RUBY_PACKER_CLASS_H__
|
20
|
+
|
21
|
+
#include "packer.h"
|
22
|
+
|
23
|
+
extern VALUE cMessagePack_Packer;
|
24
|
+
|
25
|
+
extern const rb_data_type_t packer_data_type;
|
26
|
+
|
27
|
+
static inline msgpack_packer_t *MessagePack_Packer_get(VALUE object) {
|
28
|
+
msgpack_packer_t *packer;
|
29
|
+
TypedData_Get_Struct(object, msgpack_packer_t, &packer_data_type, packer);
|
30
|
+
if (!packer) {
|
31
|
+
rb_raise(rb_eArgError, "Uninitialized Packer object");
|
32
|
+
}
|
33
|
+
return packer;
|
34
|
+
}
|
35
|
+
|
36
|
+
void MessagePack_Packer_module_init(VALUE mMessagePack);
|
37
|
+
|
38
|
+
VALUE MessagePack_Packer_alloc(VALUE klass);
|
39
|
+
|
40
|
+
VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self);
|
41
|
+
|
42
|
+
#endif
|
43
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
/*
|
2
|
+
* MessagePack for Ruby
|
3
|
+
*
|
4
|
+
* Copyright (C) 2008-2015 Sadayuki Furuhashi
|
5
|
+
*
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
* you may not use this file except in compliance with the License.
|
8
|
+
* You may obtain a copy of the License at
|
9
|
+
*
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
*
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
* See the License for the specific language governing permissions and
|
16
|
+
* limitations under the License.
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include "packer_ext_registry.h"
|
20
|
+
|
21
|
+
void msgpack_packer_ext_registry_init(VALUE owner, msgpack_packer_ext_registry_t* pkrg)
|
22
|
+
{
|
23
|
+
RB_OBJ_WRITE(owner, &pkrg->hash, Qnil);
|
24
|
+
RB_OBJ_WRITE(owner, &pkrg->cache, Qnil);
|
25
|
+
}
|
26
|
+
|
27
|
+
void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
|
28
|
+
{
|
29
|
+
rb_gc_mark(pkrg->hash);
|
30
|
+
rb_gc_mark(pkrg->cache);
|
31
|
+
}
|
32
|
+
|
33
|
+
void msgpack_packer_ext_registry_borrow(VALUE owner, msgpack_packer_ext_registry_t* src,
|
34
|
+
msgpack_packer_ext_registry_t* dst)
|
35
|
+
{
|
36
|
+
if(RTEST(src->hash)) {
|
37
|
+
if(rb_obj_frozen_p(src->hash)) {
|
38
|
+
// If the type registry is frozen we can safely share it, and share the cache as well.
|
39
|
+
RB_OBJ_WRITE(owner, &dst->hash, src->hash);
|
40
|
+
RB_OBJ_WRITE(owner, &dst->cache, src->cache);
|
41
|
+
} else {
|
42
|
+
RB_OBJ_WRITE(owner, &dst->hash, rb_hash_dup(src->hash));
|
43
|
+
RB_OBJ_WRITE(owner, &dst->cache, NIL_P(src->cache) ? Qnil : rb_hash_dup(src->cache));
|
44
|
+
}
|
45
|
+
} else {
|
46
|
+
RB_OBJ_WRITE(owner, &dst->hash, Qnil);
|
47
|
+
RB_OBJ_WRITE(owner, &dst->cache, Qnil);
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
void msgpack_packer_ext_registry_dup(VALUE owner, msgpack_packer_ext_registry_t* src,
|
52
|
+
msgpack_packer_ext_registry_t* dst)
|
53
|
+
{
|
54
|
+
RB_OBJ_WRITE(owner, &dst->hash, NIL_P(src->hash) ? Qnil : rb_hash_dup(src->hash));
|
55
|
+
RB_OBJ_WRITE(owner, &dst->cache, NIL_P(src->cache) ? Qnil : rb_hash_dup(src->cache));
|
56
|
+
}
|
57
|
+
|
58
|
+
void msgpack_packer_ext_registry_put(VALUE owner, msgpack_packer_ext_registry_t* pkrg,
|
59
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc)
|
60
|
+
{
|
61
|
+
if(NIL_P(pkrg->hash)) {
|
62
|
+
RB_OBJ_WRITE(owner, &pkrg->hash, rb_hash_new());
|
63
|
+
}
|
64
|
+
|
65
|
+
if(NIL_P(pkrg->cache)) {
|
66
|
+
RB_OBJ_WRITE(owner, &pkrg->cache, rb_hash_new());
|
67
|
+
} else {
|
68
|
+
/* clear lookup cache not to miss added type */
|
69
|
+
rb_hash_clear(pkrg->cache);
|
70
|
+
}
|
71
|
+
|
72
|
+
VALUE entry = rb_ary_new3(3, INT2FIX(ext_type), proc, INT2FIX(flags));
|
73
|
+
rb_hash_aset(pkrg->hash, ext_module, entry);
|
74
|
+
}
|
@@ -0,0 +1,140 @@
|
|
1
|
+
/*
|
2
|
+
* MessagePack for Ruby
|
3
|
+
*
|
4
|
+
* Copyright (C) 2008-2015 Sadayuki Furuhashi
|
5
|
+
*
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
* you may not use this file except in compliance with the License.
|
8
|
+
* You may obtain a copy of the License at
|
9
|
+
*
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
*
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
* See the License for the specific language governing permissions and
|
16
|
+
* limitations under the License.
|
17
|
+
*/
|
18
|
+
#ifndef MSGPACK_RUBY_PACKER_EXT_REGISTRY_H__
|
19
|
+
#define MSGPACK_RUBY_PACKER_EXT_REGISTRY_H__
|
20
|
+
|
21
|
+
#include "compat.h"
|
22
|
+
#include "ruby.h"
|
23
|
+
|
24
|
+
#define MSGPACK_EXT_RECURSIVE 0b0001
|
25
|
+
|
26
|
+
struct msgpack_packer_ext_registry_t;
|
27
|
+
typedef struct msgpack_packer_ext_registry_t msgpack_packer_ext_registry_t;
|
28
|
+
|
29
|
+
struct msgpack_packer_ext_registry_t {
|
30
|
+
VALUE hash;
|
31
|
+
VALUE cache; // lookup cache for ext types inherited from a super class
|
32
|
+
};
|
33
|
+
|
34
|
+
void msgpack_packer_ext_registry_init(VALUE owner, msgpack_packer_ext_registry_t* pkrg);
|
35
|
+
|
36
|
+
static inline void msgpack_packer_ext_registry_destroy(msgpack_packer_ext_registry_t* pkrg)
|
37
|
+
{ }
|
38
|
+
|
39
|
+
void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg);
|
40
|
+
|
41
|
+
void msgpack_packer_ext_registry_borrow(VALUE owner, msgpack_packer_ext_registry_t* src,
|
42
|
+
msgpack_packer_ext_registry_t* dst);
|
43
|
+
|
44
|
+
void msgpack_packer_ext_registry_dup(VALUE owner, msgpack_packer_ext_registry_t* src,
|
45
|
+
msgpack_packer_ext_registry_t* dst);
|
46
|
+
|
47
|
+
void msgpack_packer_ext_registry_put(VALUE owner, msgpack_packer_ext_registry_t* pkrg,
|
48
|
+
VALUE ext_module, int ext_type, int flags, VALUE proc);
|
49
|
+
|
50
|
+
static int msgpack_packer_ext_find_superclass(VALUE key, VALUE value, VALUE arg)
|
51
|
+
{
|
52
|
+
VALUE *args = (VALUE *) arg;
|
53
|
+
if(key == Qundef) {
|
54
|
+
return ST_CONTINUE;
|
55
|
+
}
|
56
|
+
if(rb_class_inherited_p(args[0], key) == Qtrue) {
|
57
|
+
args[1] = key;
|
58
|
+
return ST_STOP;
|
59
|
+
}
|
60
|
+
return ST_CONTINUE;
|
61
|
+
}
|
62
|
+
|
63
|
+
static inline VALUE msgpack_packer_ext_registry_fetch(msgpack_packer_ext_registry_t* pkrg,
|
64
|
+
VALUE lookup_class, int* ext_type_result, int* ext_flags_result)
|
65
|
+
{
|
66
|
+
// fetch lookup_class from hash, which is a hash to register classes
|
67
|
+
VALUE type = rb_hash_lookup(pkrg->hash, lookup_class);
|
68
|
+
if(type != Qnil) {
|
69
|
+
*ext_type_result = FIX2INT(rb_ary_entry(type, 0));
|
70
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(type, 2));
|
71
|
+
return rb_ary_entry(type, 1);
|
72
|
+
}
|
73
|
+
|
74
|
+
// fetch lookup_class from cache, which stores results of searching ancestors from pkrg->hash
|
75
|
+
if (RTEST(pkrg->cache)) {
|
76
|
+
VALUE type_inht = rb_hash_lookup(pkrg->cache, lookup_class);
|
77
|
+
if(type_inht != Qnil) {
|
78
|
+
*ext_type_result = FIX2INT(rb_ary_entry(type_inht, 0));
|
79
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(type_inht, 2));
|
80
|
+
return rb_ary_entry(type_inht, 1);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
return Qnil;
|
85
|
+
}
|
86
|
+
|
87
|
+
static inline VALUE msgpack_packer_ext_registry_lookup(msgpack_packer_ext_registry_t* pkrg,
|
88
|
+
VALUE instance, int* ext_type_result, int* ext_flags_result)
|
89
|
+
{
|
90
|
+
VALUE type;
|
91
|
+
|
92
|
+
if (pkrg->hash == Qnil) { // No extensions registered
|
93
|
+
return Qnil;
|
94
|
+
}
|
95
|
+
|
96
|
+
/*
|
97
|
+
* 1. check whether singleton_class or class of this instance is registered (or resolved in past) or not.
|
98
|
+
*
|
99
|
+
* Objects of type Integer (Fixnum, Bignum), Float, Symbol and frozen
|
100
|
+
* `rb_class_of` returns the singleton_class if the object has one, or the "real class" otherwise.
|
101
|
+
*/
|
102
|
+
VALUE lookup_class = rb_class_of(instance);
|
103
|
+
type = msgpack_packer_ext_registry_fetch(pkrg, lookup_class, ext_type_result, ext_flags_result);
|
104
|
+
if(type != Qnil) {
|
105
|
+
return type;
|
106
|
+
}
|
107
|
+
|
108
|
+
/*
|
109
|
+
* 2. If the object had a singleton_class check if the real class of instance is registered
|
110
|
+
* (or resolved in past) or not.
|
111
|
+
*/
|
112
|
+
VALUE real_class = rb_obj_class(instance);
|
113
|
+
if(lookup_class != real_class) {
|
114
|
+
type = msgpack_packer_ext_registry_fetch(pkrg, real_class, ext_type_result, ext_flags_result);
|
115
|
+
if(type != Qnil) {
|
116
|
+
return type;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
/*
|
121
|
+
* 3. check all keys whether it is an ancestor of lookup_class, or not
|
122
|
+
*/
|
123
|
+
VALUE args[2];
|
124
|
+
args[0] = lookup_class;
|
125
|
+
args[1] = Qnil;
|
126
|
+
rb_hash_foreach(pkrg->hash, msgpack_packer_ext_find_superclass, (VALUE) args);
|
127
|
+
|
128
|
+
VALUE superclass = args[1];
|
129
|
+
if(superclass != Qnil) {
|
130
|
+
VALUE superclass_type = rb_hash_lookup(pkrg->hash, superclass);
|
131
|
+
rb_hash_aset(pkrg->cache, lookup_class, superclass_type);
|
132
|
+
*ext_type_result = FIX2INT(rb_ary_entry(superclass_type, 0));
|
133
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(superclass_type, 2));
|
134
|
+
return rb_ary_entry(superclass_type, 1);
|
135
|
+
}
|
136
|
+
|
137
|
+
return Qnil;
|
138
|
+
}
|
139
|
+
|
140
|
+
#endif
|