cbor 0.5.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.travis.yml +5 -0
  4. data/ChangeLog +87 -0
  5. data/README.rdoc +180 -0
  6. data/Rakefile +94 -0
  7. data/cbor.gemspec +26 -0
  8. data/doclib/cbor.rb +80 -0
  9. data/doclib/cbor/buffer.rb +193 -0
  10. data/doclib/cbor/core_ext.rb +133 -0
  11. data/doclib/cbor/error.rb +14 -0
  12. data/doclib/cbor/packer.rb +133 -0
  13. data/doclib/cbor/simple.rb +15 -0
  14. data/doclib/cbor/tagged.rb +16 -0
  15. data/doclib/cbor/unpacker.rb +138 -0
  16. data/ext/cbor/buffer.c +693 -0
  17. data/ext/cbor/buffer.h +469 -0
  18. data/ext/cbor/buffer_class.c +516 -0
  19. data/ext/cbor/buffer_class.h +41 -0
  20. data/ext/cbor/cbor.h +69 -0
  21. data/ext/cbor/compat.h +136 -0
  22. data/ext/cbor/core_ext.c +181 -0
  23. data/ext/cbor/core_ext.h +35 -0
  24. data/ext/cbor/extconf.rb +25 -0
  25. data/ext/cbor/packer.c +169 -0
  26. data/ext/cbor/packer.h +337 -0
  27. data/ext/cbor/packer_class.c +304 -0
  28. data/ext/cbor/packer_class.h +39 -0
  29. data/ext/cbor/rbinit.c +51 -0
  30. data/ext/cbor/renamer.h +56 -0
  31. data/ext/cbor/rmem.c +103 -0
  32. data/ext/cbor/rmem.h +118 -0
  33. data/ext/cbor/sysdep.h +135 -0
  34. data/ext/cbor/sysdep_endian.h +59 -0
  35. data/ext/cbor/sysdep_types.h +55 -0
  36. data/ext/cbor/unpacker.c +735 -0
  37. data/ext/cbor/unpacker.h +133 -0
  38. data/ext/cbor/unpacker_class.c +417 -0
  39. data/ext/cbor/unpacker_class.h +39 -0
  40. data/lib/cbor.rb +9 -0
  41. data/lib/cbor/version.rb +3 -0
  42. data/spec/buffer_io_spec.rb +260 -0
  43. data/spec/buffer_spec.rb +576 -0
  44. data/spec/cases.cbor +0 -0
  45. data/spec/cases.cbor_stream +0 -0
  46. data/spec/cases.json +1 -0
  47. data/spec/cases.msg +0 -0
  48. data/spec/cases_compact.msg +0 -0
  49. data/spec/cases_spec.rb +39 -0
  50. data/spec/format_spec.rb +445 -0
  51. data/spec/packer_spec.rb +127 -0
  52. data/spec/random_compat.rb +24 -0
  53. data/spec/spec_helper.rb +45 -0
  54. data/spec/unpacker_spec.rb +238 -0
  55. metadata +196 -0
@@ -0,0 +1,133 @@
1
+ /*
2
+ * CBOR for Ruby
3
+ *
4
+ * Copyright (C) 2013 Carsten Bormann
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License").
7
+ *
8
+ * Based on:
9
+ ***********/
10
+ /*
11
+ * MessagePack for Ruby
12
+ *
13
+ * Copyright (C) 2008-2013 Sadayuki Furuhashi
14
+ *
15
+ * Licensed under the Apache License, Version 2.0 (the "License");
16
+ * you may not use this file except in compliance with the License.
17
+ * You may obtain a copy of the License at
18
+ *
19
+ * http://www.apache.org/licenses/LICENSE-2.0
20
+ *
21
+ * Unless required by applicable law or agreed to in writing, software
22
+ * distributed under the License is distributed on an "AS IS" BASIS,
23
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
+ * See the License for the specific language governing permissions and
25
+ * limitations under the License.
26
+ */
27
+ #ifndef MSGPACK_RUBY_UNPACKER_H__
28
+ #define MSGPACK_RUBY_UNPACKER_H__
29
+
30
+ #include "buffer.h"
31
+
32
+ #ifndef MSGPACK_UNPACKER_STACK_CAPACITY
33
+ #define MSGPACK_UNPACKER_STACK_CAPACITY 128
34
+ #endif
35
+
36
+ struct msgpack_unpacker_t;
37
+ typedef struct msgpack_unpacker_t msgpack_unpacker_t;
38
+
39
+ enum stack_type_t {
40
+ STACK_TYPE_ARRAY,
41
+ STACK_TYPE_MAP_KEY,
42
+ STACK_TYPE_MAP_VALUE,
43
+ STACK_TYPE_TAG, /* > TAG = indef */
44
+ STACK_TYPE_MAP_VALUE_INDEF, /* Cannot BREAK up to here */
45
+ STACK_TYPE_MAP_KEY_INDEF,
46
+ STACK_TYPE_ARRAY_INDEF,
47
+ STACK_TYPE_STRING_INDEF,
48
+ };
49
+
50
+ typedef struct {
51
+ size_t count;
52
+ enum stack_type_t type;
53
+ VALUE object;
54
+ VALUE key;
55
+ uint64_t tag; /* could be union... */
56
+ } msgpack_unpacker_stack_t;
57
+
58
+ #define MSGPACK_UNPACKER_STACK_SIZE (8+4+8+8+8) /* assumes size_t <= 64bit, enum <= 32bit, VALUE <= 64bit */
59
+
60
+ struct msgpack_unpacker_t {
61
+ msgpack_buffer_t buffer;
62
+
63
+ unsigned int head_byte;
64
+
65
+ msgpack_unpacker_stack_t* stack;
66
+ size_t stack_depth;
67
+ size_t stack_capacity;
68
+
69
+ VALUE last_object;
70
+
71
+ VALUE reading_raw;
72
+ size_t reading_raw_remaining;
73
+ int textflag;
74
+
75
+ bool keys_as_symbols; /* Experimental */
76
+
77
+ VALUE buffer_ref;
78
+ };
79
+
80
+ #define UNPACKER_BUFFER_(uk) (&(uk)->buffer)
81
+
82
+ enum msgpack_unpacker_object_type {
83
+ TYPE_NIL = 0,
84
+ TYPE_BOOLEAN,
85
+ TYPE_INTEGER,
86
+ TYPE_FLOAT,
87
+ TYPE_RAW,
88
+ TYPE_ARRAY,
89
+ TYPE_MAP,
90
+ };
91
+
92
+ void msgpack_unpacker_static_init();
93
+
94
+ void msgpack_unpacker_static_destroy();
95
+
96
+ void msgpack_unpacker_init(msgpack_unpacker_t* uk);
97
+
98
+ void msgpack_unpacker_destroy(msgpack_unpacker_t* uk);
99
+
100
+ void msgpack_unpacker_mark(msgpack_unpacker_t* uk);
101
+
102
+ void msgpack_unpacker_reset(msgpack_unpacker_t* uk);
103
+
104
+
105
+ /* error codes */
106
+ #define PRIMITIVE_CONTAINER_START 1
107
+ #define PRIMITIVE_OBJECT_COMPLETE 0
108
+ #define PRIMITIVE_EOF -1
109
+ #define PRIMITIVE_INVALID_BYTE -2
110
+ #define PRIMITIVE_STACK_TOO_DEEP -3
111
+ #define PRIMITIVE_UNEXPECTED_TYPE -4
112
+ #define PRIMITIVE_BREAK 2
113
+
114
+ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth);
115
+
116
+ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth);
117
+
118
+ static inline VALUE msgpack_unpacker_get_last_object(msgpack_unpacker_t* uk)
119
+ {
120
+ return uk->last_object;
121
+ }
122
+
123
+
124
+ int msgpack_unpacker_peek_next_object_type(msgpack_unpacker_t* uk);
125
+
126
+ int msgpack_unpacker_skip_nil(msgpack_unpacker_t* uk);
127
+
128
+ int msgpack_unpacker_read_array_header(msgpack_unpacker_t* uk, uint64_t* result_size);
129
+
130
+ int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint64_t* result_size);
131
+
132
+ #endif
133
+
@@ -0,0 +1,417 @@
1
+ /*
2
+ * CBOR for Ruby
3
+ *
4
+ * Copyright (C) 2013 Carsten Bormann
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License").
7
+ *
8
+ * Based on:
9
+ ***********/
10
+ /*
11
+ * MessagePack for Ruby
12
+ *
13
+ * Copyright (C) 2008-2013 Sadayuki Furuhashi
14
+ *
15
+ * Licensed under the Apache License, Version 2.0 (the "License");
16
+ * you may not use this file except in compliance with the License.
17
+ * You may obtain a copy of the License at
18
+ *
19
+ * http://www.apache.org/licenses/LICENSE-2.0
20
+ *
21
+ * Unless required by applicable law or agreed to in writing, software
22
+ * distributed under the License is distributed on an "AS IS" BASIS,
23
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
+ * See the License for the specific language governing permissions and
25
+ * limitations under the License.
26
+ */
27
+
28
+ #include "unpacker.h"
29
+ #include "unpacker_class.h"
30
+ #include "buffer_class.h"
31
+
32
+ VALUE cMessagePack_Unpacker;
33
+
34
+ //static VALUE s_unpacker_value;
35
+ //static msgpack_unpacker_t* s_unpacker;
36
+
37
+ static VALUE eUnpackError;
38
+ static VALUE eMalformedFormatError;
39
+ static VALUE eStackError;
40
+ static VALUE eTypeError;
41
+
42
+ #define UNPACKER(from, name) \
43
+ msgpack_unpacker_t *name = NULL; \
44
+ Data_Get_Struct(from, msgpack_unpacker_t, name); \
45
+ if(name == NULL) { \
46
+ rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be."); \
47
+ }
48
+
49
+ static void Unpacker_free(msgpack_unpacker_t* uk)
50
+ {
51
+ if(uk == NULL) {
52
+ return;
53
+ }
54
+ msgpack_unpacker_destroy(uk);
55
+ free(uk);
56
+ }
57
+
58
+ static VALUE Unpacker_alloc(VALUE klass)
59
+ {
60
+ msgpack_unpacker_t* uk = ALLOC_N(msgpack_unpacker_t, 1);
61
+ msgpack_unpacker_init(uk);
62
+
63
+ VALUE self = Data_Wrap_Struct(klass, msgpack_unpacker_mark, Unpacker_free, uk);
64
+
65
+ uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
66
+
67
+ return self;
68
+ }
69
+
70
+ static VALUE Unpacker_initialize(int argc, VALUE* argv, VALUE self)
71
+ {
72
+ VALUE io = Qnil;
73
+ VALUE options = Qnil;
74
+
75
+ if(argc == 0 || (argc == 1 && argv[0] == Qnil)) {
76
+ /* Qnil */
77
+
78
+ } else if(argc == 1) {
79
+ VALUE v = argv[0];
80
+ if(rb_type(v) == T_HASH) {
81
+ options = v;
82
+ } else {
83
+ io = v;
84
+ }
85
+
86
+ } else if(argc == 2) {
87
+ io = argv[0];
88
+ options = argv[1];
89
+ if(rb_type(options) != T_HASH) {
90
+ rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(io));
91
+ }
92
+
93
+ } else {
94
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..1)", argc);
95
+ }
96
+
97
+ UNPACKER(self, uk);
98
+ if(io != Qnil || options != Qnil) {
99
+ MessagePack_Buffer_initialize(UNPACKER_BUFFER_(uk), io, options);
100
+ }
101
+
102
+ // TODO options
103
+
104
+ return self;
105
+ }
106
+
107
+ static void raise_unpacker_error(int r)
108
+ {
109
+ switch(r) {
110
+ case PRIMITIVE_EOF:
111
+ rb_raise(rb_eEOFError, "end of buffer reached");
112
+ case PRIMITIVE_INVALID_BYTE:
113
+ rb_raise(eMalformedFormatError, "invalid byte");
114
+ case PRIMITIVE_STACK_TOO_DEEP:
115
+ rb_raise(eStackError, "stack level too deep");
116
+ case PRIMITIVE_UNEXPECTED_TYPE:
117
+ rb_raise(eTypeError, "unexpected type");
118
+ default:
119
+ rb_raise(eUnpackError, "logically unknown error %d", r);
120
+ }
121
+ }
122
+
123
+ static VALUE Unpacker_buffer(VALUE self)
124
+ {
125
+ UNPACKER(self, uk);
126
+ return uk->buffer_ref;
127
+ }
128
+
129
+ static VALUE Unpacker_read(VALUE self)
130
+ {
131
+ UNPACKER(self, uk);
132
+
133
+ int r = msgpack_unpacker_read(uk, 0);
134
+ if(r < 0) {
135
+ raise_unpacker_error(r);
136
+ }
137
+
138
+ return msgpack_unpacker_get_last_object(uk);
139
+ }
140
+
141
+ static VALUE Unpacker_skip(VALUE self)
142
+ {
143
+ UNPACKER(self, uk);
144
+
145
+ int r = msgpack_unpacker_skip(uk, 0);
146
+ if(r < 0) {
147
+ raise_unpacker_error(r);
148
+ }
149
+
150
+ return Qnil;
151
+ }
152
+
153
+ static VALUE Unpacker_skip_nil(VALUE self)
154
+ {
155
+ UNPACKER(self, uk);
156
+
157
+ int r = msgpack_unpacker_skip_nil(uk);
158
+ if(r < 0) {
159
+ raise_unpacker_error(r);
160
+ }
161
+
162
+ if(r) {
163
+ return Qtrue;
164
+ }
165
+ return Qfalse;
166
+ }
167
+
168
+ static VALUE Unpacker_read_array_header(VALUE self)
169
+ {
170
+ UNPACKER(self, uk);
171
+
172
+ uint64_t size;
173
+ int r = msgpack_unpacker_read_array_header(uk, &size);
174
+ if(r < 0) {
175
+ raise_unpacker_error(r);
176
+ }
177
+
178
+ return rb_ull2inum(size);
179
+ }
180
+
181
+ static VALUE Unpacker_read_map_header(VALUE self)
182
+ {
183
+ UNPACKER(self, uk);
184
+
185
+ uint64_t size;
186
+ int r = msgpack_unpacker_read_map_header(uk, &size);
187
+ if(r < 0) {
188
+ raise_unpacker_error((int)r);
189
+ }
190
+
191
+ return rb_ull2inum(size);
192
+ }
193
+
194
+ #if 0
195
+ static VALUE Unpacker_peek_next_type(VALUE self)
196
+ {
197
+ UNPACKER(self, uk);
198
+
199
+ int r = msgpack_unpacker_peek_next_object_type(uk);
200
+ if(r < 0) {
201
+ raise_unpacker_error(r);
202
+ }
203
+
204
+ switch((enum msgpack_unpacker_object_type) r) {
205
+ case TYPE_NIL:
206
+ return rb_intern("nil");
207
+ case TYPE_BOOLEAN:
208
+ return rb_intern("boolean");
209
+ case TYPE_INTEGER:
210
+ return rb_intern("integer");
211
+ case TYPE_FLOAT:
212
+ return rb_intern("float");
213
+ case TYPE_RAW:
214
+ return rb_intern("raw");
215
+ case TYPE_ARRAY:
216
+ return rb_intern("array");
217
+ case TYPE_MAP:
218
+ return rb_intern("map");
219
+ default:
220
+ rb_raise(eUnpackError, "logically unknown type %d", r);
221
+ }
222
+ }
223
+ #endif
224
+
225
+ static VALUE Unpacker_feed(VALUE self, VALUE data)
226
+ {
227
+ UNPACKER(self, uk);
228
+
229
+ StringValue(data);
230
+
231
+ msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), data);
232
+
233
+ return self;
234
+ }
235
+
236
+ static VALUE Unpacker_each_impl(VALUE self)
237
+ {
238
+ UNPACKER(self, uk);
239
+
240
+ while(true) {
241
+ int r = msgpack_unpacker_read(uk, 0);
242
+ if(r < 0) {
243
+ if(r == PRIMITIVE_EOF) {
244
+ return Qnil;
245
+ }
246
+ raise_unpacker_error(r);
247
+ }
248
+ VALUE v = msgpack_unpacker_get_last_object(uk);
249
+ #ifdef JRUBY
250
+ /* TODO JRuby's rb_yield behaves differently from Ruby 1.9.3 or Rubinius. */
251
+ if(rb_type(v) == T_ARRAY) {
252
+ v = rb_ary_new3(1, v);
253
+ }
254
+ #endif
255
+ rb_yield(v);
256
+ }
257
+ }
258
+
259
+ static VALUE Unpacker_rescue_EOFError(VALUE self)
260
+ {
261
+ UNUSED(self);
262
+ return Qnil;
263
+ }
264
+
265
+ static VALUE Unpacker_each(VALUE self)
266
+ {
267
+ UNPACKER(self, uk);
268
+
269
+ #ifdef RETURN_ENUMERATOR
270
+ RETURN_ENUMERATOR(self, 0, 0);
271
+ #endif
272
+
273
+ if(msgpack_buffer_has_io(UNPACKER_BUFFER_(uk))) {
274
+ /* rescue EOFError only if io is set */
275
+ return rb_rescue2(Unpacker_each_impl, self,
276
+ Unpacker_rescue_EOFError, self,
277
+ rb_eEOFError, NULL);
278
+ } else {
279
+ return Unpacker_each_impl(self);
280
+ }
281
+ }
282
+
283
+ static VALUE Unpacker_feed_each(VALUE self, VALUE data)
284
+ {
285
+ // TODO optimize
286
+ Unpacker_feed(self, data);
287
+ return Unpacker_each(self);
288
+ }
289
+
290
+ static VALUE Unpacker_reset(VALUE self)
291
+ {
292
+ UNPACKER(self, uk);
293
+
294
+ msgpack_unpacker_reset(uk);
295
+
296
+ return Qnil;
297
+ }
298
+
299
+ VALUE MessagePack_unpack(int argc, VALUE* argv)
300
+ {
301
+ VALUE src;
302
+ VALUE options = Qnil;
303
+ bool keys_as_symbols = false;
304
+
305
+ switch(argc) {
306
+ case 2:
307
+ options = argv[1]; /* Experimental! */
308
+ if (options == ID2SYM(rb_intern("keys_as_symbols")))
309
+ keys_as_symbols = true;
310
+ else
311
+ rb_raise(rb_eArgError, "unknown option");
312
+ /* fall through */
313
+ case 1:
314
+ src = argv[0];
315
+ break;
316
+ default:
317
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
318
+ }
319
+
320
+ VALUE io = Qnil;
321
+ if(rb_type(src) != T_STRING) {
322
+ io = src;
323
+ src = Qnil;
324
+ }
325
+
326
+ VALUE self = Unpacker_alloc(cMessagePack_Unpacker);
327
+ UNPACKER(self, uk);
328
+ //msgpack_unpacker_reset(s_unpacker);
329
+ //msgpack_buffer_reset_io(UNPACKER_BUFFER_(s_unpacker));
330
+
331
+ /* prefer reference than copying */
332
+ msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(uk), 0);
333
+
334
+ uk->keys_as_symbols = keys_as_symbols;
335
+
336
+ if(io != Qnil) {
337
+ MessagePack_Buffer_initialize(UNPACKER_BUFFER_(uk), io, Qnil);
338
+ }
339
+
340
+ if(src != Qnil) {
341
+ /* prefer reference than copying; see MessagePack_Unpacker_module_init */
342
+ msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), src);
343
+ }
344
+
345
+ int r = msgpack_unpacker_read(uk, 0);
346
+ if(r < 0) {
347
+ raise_unpacker_error(r);
348
+ }
349
+
350
+ /* raise if extra bytes follow */
351
+ if(msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk)) > 0) {
352
+ rb_raise(eMalformedFormatError, "extra bytes follow after a deserialized object");
353
+ }
354
+
355
+ #ifdef RB_GC_GUARD
356
+ /* This prevents compilers from optimizing out the `self` variable
357
+ * from stack. Otherwise GC free()s it. */
358
+ RB_GC_GUARD(self);
359
+ #endif
360
+
361
+ return msgpack_unpacker_get_last_object(uk);
362
+ }
363
+
364
+ static VALUE MessagePack_load_module_method(int argc, VALUE* argv, VALUE mod)
365
+ {
366
+ UNUSED(mod);
367
+ return MessagePack_unpack(argc, argv);
368
+ }
369
+
370
+ static VALUE MessagePack_unpack_module_method(int argc, VALUE* argv, VALUE mod)
371
+ {
372
+ UNUSED(mod);
373
+ return MessagePack_unpack(argc, argv);
374
+ }
375
+
376
+ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
377
+ {
378
+ msgpack_unpacker_static_init();
379
+
380
+ cMessagePack_Unpacker = rb_define_class_under(mMessagePack, "Unpacker", rb_cObject);
381
+
382
+ eUnpackError = rb_define_class_under(mMessagePack, "UnpackError", rb_eStandardError);
383
+
384
+ eMalformedFormatError = rb_define_class_under(mMessagePack, "MalformedFormatError", eUnpackError);
385
+
386
+ eStackError = rb_define_class_under(mMessagePack, "StackError", eUnpackError);
387
+
388
+ eTypeError = rb_define_class_under(mMessagePack, "TypeError", rb_eStandardError);
389
+
390
+ rb_define_alloc_func(cMessagePack_Unpacker, Unpacker_alloc);
391
+
392
+ rb_define_method(cMessagePack_Unpacker, "initialize", Unpacker_initialize, -1);
393
+ rb_define_method(cMessagePack_Unpacker, "buffer", Unpacker_buffer, 0);
394
+ rb_define_method(cMessagePack_Unpacker, "read", Unpacker_read, 0);
395
+ rb_define_alias(cMessagePack_Unpacker, "unpack", "read");
396
+ rb_define_method(cMessagePack_Unpacker, "skip", Unpacker_skip, 0);
397
+ rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
398
+ rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
399
+ rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
400
+ //rb_define_method(cMessagePack_Unpacker, "peek_next_type", Unpacker_peek_next_type, 0); // TODO
401
+ rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1);
402
+ rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
403
+ rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1);
404
+ rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
405
+
406
+ //s_unpacker_value = Unpacker_alloc(cMessagePack_Unpacker);
407
+ //rb_gc_register_address(&s_unpacker_value);
408
+ //Data_Get_Struct(s_unpacker_value, msgpack_unpacker_t, s_unpacker);
409
+ /* prefer reference than copying */
410
+ //msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(s_unpacker), 0);
411
+
412
+ /* MessagePack.unpack(x) */
413
+ rb_define_module_function(mMessagePack, "load", MessagePack_load_module_method, -1);
414
+ rb_define_module_function(mMessagePack, "unpack", MessagePack_unpack_module_method, -1);
415
+ rb_define_module_function(mMessagePack, "decode", MessagePack_unpack_module_method, -1);
416
+ }
417
+