msgpack 1.3.3 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +99 -0
  3. data/README.md +293 -0
  4. data/ext/java/org/msgpack/jruby/Buffer.java +26 -19
  5. data/ext/java/org/msgpack/jruby/Decoder.java +46 -23
  6. data/ext/java/org/msgpack/jruby/Encoder.java +68 -30
  7. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +43 -64
  8. data/ext/java/org/msgpack/jruby/ExtensionValue.java +6 -9
  9. data/ext/java/org/msgpack/jruby/Factory.java +43 -42
  10. data/ext/java/org/msgpack/jruby/Packer.java +37 -40
  11. data/ext/java/org/msgpack/jruby/Unpacker.java +86 -68
  12. data/ext/msgpack/buffer.c +58 -85
  13. data/ext/msgpack/buffer.h +59 -20
  14. data/ext/msgpack/buffer_class.c +161 -52
  15. data/ext/msgpack/buffer_class.h +1 -0
  16. data/ext/msgpack/compat.h +1 -111
  17. data/ext/msgpack/extconf.rb +41 -23
  18. data/ext/msgpack/factory_class.c +143 -87
  19. data/ext/msgpack/packer.c +66 -43
  20. data/ext/msgpack/packer.h +25 -27
  21. data/ext/msgpack/packer_class.c +102 -130
  22. data/ext/msgpack/packer_class.h +11 -0
  23. data/ext/msgpack/packer_ext_registry.c +35 -40
  24. data/ext/msgpack/packer_ext_registry.h +41 -38
  25. data/ext/msgpack/rbinit.c +1 -1
  26. data/ext/msgpack/rmem.c +3 -4
  27. data/ext/msgpack/sysdep.h +5 -2
  28. data/ext/msgpack/unpacker.c +130 -126
  29. data/ext/msgpack/unpacker.h +22 -13
  30. data/ext/msgpack/unpacker_class.c +94 -124
  31. data/ext/msgpack/unpacker_class.h +11 -0
  32. data/ext/msgpack/unpacker_ext_registry.c +40 -28
  33. data/ext/msgpack/unpacker_ext_registry.h +21 -18
  34. data/lib/msgpack/bigint.rb +69 -0
  35. data/lib/msgpack/buffer.rb +9 -0
  36. data/lib/msgpack/factory.rb +140 -10
  37. data/lib/msgpack/packer.rb +10 -1
  38. data/lib/msgpack/symbol.rb +21 -4
  39. data/lib/msgpack/time.rb +1 -1
  40. data/lib/msgpack/unpacker.rb +14 -1
  41. data/lib/msgpack/version.rb +4 -8
  42. data/lib/msgpack.rb +7 -12
  43. data/msgpack.gemspec +9 -8
  44. metadata +37 -96
  45. data/.gitignore +0 -23
  46. data/.rubocop.yml +0 -36
  47. data/.travis.yml +0 -43
  48. data/Gemfile +0 -9
  49. data/README.rdoc +0 -225
  50. data/Rakefile +0 -78
  51. data/appveyor.yml +0 -18
  52. data/bench/pack.rb +0 -23
  53. data/bench/pack_log.rb +0 -33
  54. data/bench/pack_log_long.rb +0 -65
  55. data/bench/pack_symbols.rb +0 -28
  56. data/bench/run.sh +0 -14
  57. data/bench/run_long.sh +0 -35
  58. data/bench/run_symbols.sh +0 -26
  59. data/bench/unpack.rb +0 -21
  60. data/bench/unpack_log.rb +0 -34
  61. data/bench/unpack_log_long.rb +0 -67
  62. data/doclib/msgpack/buffer.rb +0 -193
  63. data/doclib/msgpack/core_ext.rb +0 -101
  64. data/doclib/msgpack/error.rb +0 -19
  65. data/doclib/msgpack/extension_value.rb +0 -9
  66. data/doclib/msgpack/factory.rb +0 -101
  67. data/doclib/msgpack/packer.rb +0 -208
  68. data/doclib/msgpack/time.rb +0 -22
  69. data/doclib/msgpack/timestamp.rb +0 -44
  70. data/doclib/msgpack/unpacker.rb +0 -183
  71. data/doclib/msgpack.rb +0 -87
  72. data/msgpack.org.md +0 -46
  73. data/spec/cases.json +0 -1
  74. data/spec/cases.msg +0 -0
  75. data/spec/cases_compact.msg +0 -0
  76. data/spec/cases_spec.rb +0 -39
  77. data/spec/cruby/buffer_io_spec.rb +0 -255
  78. data/spec/cruby/buffer_packer.rb +0 -29
  79. data/spec/cruby/buffer_spec.rb +0 -575
  80. data/spec/cruby/buffer_unpacker.rb +0 -19
  81. data/spec/cruby/unpacker_spec.rb +0 -70
  82. data/spec/ext_value_spec.rb +0 -99
  83. data/spec/exttypes.rb +0 -51
  84. data/spec/factory_spec.rb +0 -367
  85. data/spec/format_spec.rb +0 -301
  86. data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
  87. data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
  88. data/spec/jruby/unpacker_spec.rb +0 -186
  89. data/spec/msgpack_spec.rb +0 -214
  90. data/spec/pack_spec.rb +0 -61
  91. data/spec/packer_spec.rb +0 -557
  92. data/spec/random_compat.rb +0 -24
  93. data/spec/spec_helper.rb +0 -38
  94. data/spec/timestamp_spec.rb +0 -121
  95. data/spec/unpack_spec.rb +0 -57
  96. data/spec/unpacker_spec.rb +0 -716
@@ -33,35 +33,59 @@ static VALUE eUnexpectedTypeError;
33
33
  static VALUE eUnknownExtTypeError;
34
34
  static VALUE mTypeError; // obsoleted. only for backward compatibility. See #86.
35
35
 
36
- #define UNPACKER(from, name) \
37
- msgpack_unpacker_t *name = NULL; \
38
- Data_Get_Struct(from, msgpack_unpacker_t, name); \
39
- if(name == NULL) { \
40
- rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be."); \
41
- }
36
+ static VALUE sym_symbolize_keys;
37
+ static VALUE sym_freeze;
38
+ static VALUE sym_allow_unknown_ext;
42
39
 
43
- static void Unpacker_free(msgpack_unpacker_t* uk)
40
+ static void Unpacker_free(void *ptr)
44
41
  {
42
+ msgpack_unpacker_t* uk = ptr;
45
43
  if(uk == NULL) {
46
44
  return;
47
45
  }
48
- msgpack_unpacker_ext_registry_destroy(&uk->ext_registry);
46
+ msgpack_unpacker_ext_registry_release(uk->ext_registry);
49
47
  _msgpack_unpacker_destroy(uk);
50
48
  xfree(uk);
51
49
  }
52
50
 
53
- static void Unpacker_mark(msgpack_unpacker_t* uk)
51
+ static void Unpacker_mark(void *ptr)
54
52
  {
53
+ msgpack_unpacker_t* uk = ptr;
54
+ msgpack_buffer_mark(uk);
55
55
  msgpack_unpacker_mark(uk);
56
- msgpack_unpacker_ext_registry_mark(&uk->ext_registry);
56
+ msgpack_unpacker_ext_registry_mark(uk->ext_registry);
57
+ }
58
+
59
+ static size_t Unpacker_memsize(const void *ptr)
60
+ {
61
+ size_t total_size = sizeof(msgpack_unpacker_t);
62
+
63
+ const msgpack_unpacker_t* uk = ptr;
64
+ if (uk->ext_registry) {
65
+ total_size += sizeof(msgpack_unpacker_ext_registry_t) / (uk->ext_registry->borrow_count + 1);
66
+ }
67
+
68
+ total_size += (uk->stack->depth + 1) * sizeof(msgpack_unpacker_stack_t);
69
+
70
+ return total_size + msgpack_buffer_memsize(&uk->buffer);
57
71
  }
58
72
 
73
+ const rb_data_type_t unpacker_data_type = {
74
+ .wrap_struct_name = "msgpack:unpacker",
75
+ .function = {
76
+ .dmark = Unpacker_mark,
77
+ .dfree = Unpacker_free,
78
+ .dsize = Unpacker_memsize,
79
+ },
80
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
81
+ };
82
+
59
83
  VALUE MessagePack_Unpacker_alloc(VALUE klass)
60
84
  {
61
- msgpack_unpacker_t* uk = ZALLOC_N(msgpack_unpacker_t, 1);
85
+ msgpack_unpacker_t* uk;
86
+ VALUE self = TypedData_Make_Struct(klass, msgpack_unpacker_t, &unpacker_data_type, uk);
62
87
  _msgpack_unpacker_init(uk);
63
-
64
- VALUE self = Data_Wrap_Struct(klass, Unpacker_mark, Unpacker_free, uk);
88
+ uk->self = self;
65
89
  return self;
66
90
  }
67
91
 
@@ -84,7 +108,7 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
84
108
  } else if(argc == 2) {
85
109
  io = argv[0];
86
110
  options = argv[1];
87
- if(rb_type(options) != T_HASH) {
111
+ if(options != Qnil && rb_type(options) != T_HASH) {
88
112
  rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
89
113
  }
90
114
 
@@ -92,20 +116,22 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
92
116
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
93
117
  }
94
118
 
95
- UNPACKER(self, uk);
119
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
96
120
 
97
- msgpack_unpacker_ext_registry_init(&uk->ext_registry);
98
- uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
121
+ uk->buffer_ref = Qnil;
99
122
 
100
123
  MessagePack_Buffer_set_options(UNPACKER_BUFFER_(uk), io, options);
101
124
 
102
125
  if(options != Qnil) {
103
126
  VALUE v;
104
127
 
105
- v = rb_hash_aref(options, ID2SYM(rb_intern("symbolize_keys")));
128
+ v = rb_hash_aref(options, sym_symbolize_keys);
106
129
  msgpack_unpacker_set_symbolized_keys(uk, RTEST(v));
107
130
 
108
- v = rb_hash_aref(options, ID2SYM(rb_intern("allow_unknown_ext")));
131
+ v = rb_hash_aref(options, sym_freeze);
132
+ msgpack_unpacker_set_freeze(uk, RTEST(v));
133
+
134
+ v = rb_hash_aref(options, sym_allow_unknown_ext);
109
135
  msgpack_unpacker_set_allow_unknown_ext(uk, RTEST(v));
110
136
  }
111
137
 
@@ -114,17 +140,23 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
114
140
 
115
141
  static VALUE Unpacker_symbolized_keys_p(VALUE self)
116
142
  {
117
- UNPACKER(self, uk);
143
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
118
144
  return uk->symbolize_keys ? Qtrue : Qfalse;
119
145
  }
120
146
 
147
+ static VALUE Unpacker_freeze_p(VALUE self)
148
+ {
149
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
150
+ return uk->freeze ? Qtrue : Qfalse;
151
+ }
152
+
121
153
  static VALUE Unpacker_allow_unknown_ext_p(VALUE self)
122
154
  {
123
- UNPACKER(self, uk);
155
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
124
156
  return uk->allow_unknown_ext ? Qtrue : Qfalse;
125
157
  }
126
158
 
127
- static void raise_unpacker_error(int r)
159
+ NORETURN(static void raise_unpacker_error(int r))
128
160
  {
129
161
  switch(r) {
130
162
  case PRIMITIVE_EOF:
@@ -136,6 +168,7 @@ static void raise_unpacker_error(int r)
136
168
  case PRIMITIVE_UNEXPECTED_TYPE:
137
169
  rb_raise(eUnexpectedTypeError, "unexpected type");
138
170
  case PRIMITIVE_UNEXPECTED_EXT_TYPE:
171
+ // rb_bug("unexpected extension type");
139
172
  rb_raise(eUnknownExtTypeError, "unexpected extension type");
140
173
  default:
141
174
  rb_raise(eUnpackError, "logically unknown error %d", r);
@@ -144,13 +177,16 @@ static void raise_unpacker_error(int r)
144
177
 
145
178
  static VALUE Unpacker_buffer(VALUE self)
146
179
  {
147
- UNPACKER(self, uk);
180
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
181
+ if (!RTEST(uk->buffer_ref)) {
182
+ uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
183
+ }
148
184
  return uk->buffer_ref;
149
185
  }
150
186
 
151
187
  static VALUE Unpacker_read(VALUE self)
152
188
  {
153
- UNPACKER(self, uk);
189
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
154
190
 
155
191
  int r = msgpack_unpacker_read(uk, 0);
156
192
  if(r < 0) {
@@ -162,7 +198,7 @@ static VALUE Unpacker_read(VALUE self)
162
198
 
163
199
  static VALUE Unpacker_skip(VALUE self)
164
200
  {
165
- UNPACKER(self, uk);
201
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
166
202
 
167
203
  int r = msgpack_unpacker_skip(uk, 0);
168
204
  if(r < 0) {
@@ -174,7 +210,7 @@ static VALUE Unpacker_skip(VALUE self)
174
210
 
175
211
  static VALUE Unpacker_skip_nil(VALUE self)
176
212
  {
177
- UNPACKER(self, uk);
213
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
178
214
 
179
215
  int r = msgpack_unpacker_skip_nil(uk);
180
216
  if(r < 0) {
@@ -189,7 +225,7 @@ static VALUE Unpacker_skip_nil(VALUE self)
189
225
 
190
226
  static VALUE Unpacker_read_array_header(VALUE self)
191
227
  {
192
- UNPACKER(self, uk);
228
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
193
229
 
194
230
  uint32_t size;
195
231
  int r = msgpack_unpacker_read_array_header(uk, &size);
@@ -197,12 +233,12 @@ static VALUE Unpacker_read_array_header(VALUE self)
197
233
  raise_unpacker_error(r);
198
234
  }
199
235
 
200
- return ULONG2NUM(size);
236
+ return ULONG2NUM(size); // long at least 32 bits
201
237
  }
202
238
 
203
239
  static VALUE Unpacker_read_map_header(VALUE self)
204
240
  {
205
- UNPACKER(self, uk);
241
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
206
242
 
207
243
  uint32_t size;
208
244
  int r = msgpack_unpacker_read_map_header(uk, &size);
@@ -210,52 +246,12 @@ static VALUE Unpacker_read_map_header(VALUE self)
210
246
  raise_unpacker_error((int)r);
211
247
  }
212
248
 
213
- return ULONG2NUM(size);
214
- }
215
-
216
- static VALUE Unpacker_peek_next_type(VALUE self)
217
- {
218
- UNPACKER(self, uk);
219
-
220
- int r = msgpack_unpacker_peek_next_object_type(uk);
221
- if(r < 0) {
222
- raise_unpacker_error(r);
223
- }
224
-
225
- switch((enum msgpack_unpacker_object_type) r) {
226
- case TYPE_NIL:
227
- return rb_intern("nil");
228
- case TYPE_BOOLEAN:
229
- return rb_intern("boolean");
230
- case TYPE_INTEGER:
231
- return rb_intern("integer");
232
- case TYPE_FLOAT:
233
- return rb_intern("float");
234
- case TYPE_RAW:
235
- return rb_intern("raw");
236
- case TYPE_ARRAY:
237
- return rb_intern("array");
238
- case TYPE_MAP:
239
- return rb_intern("map");
240
- default:
241
- rb_raise(eUnpackError, "logically unknown type %d", r);
242
- }
243
- }
244
-
245
- static VALUE Unpacker_feed(VALUE self, VALUE data)
246
- {
247
- UNPACKER(self, uk);
248
-
249
- StringValue(data);
250
-
251
- msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), data);
252
-
253
- return self;
249
+ return ULONG2NUM(size); // long at least 32 bits
254
250
  }
255
251
 
256
252
  static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
257
253
  {
258
- UNPACKER(self, uk);
254
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
259
255
 
260
256
  StringValue(data);
261
257
 
@@ -266,7 +262,7 @@ static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
266
262
 
267
263
  static VALUE Unpacker_each_impl(VALUE self)
268
264
  {
269
- UNPACKER(self, uk);
265
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
270
266
 
271
267
  while(true) {
272
268
  int r = msgpack_unpacker_read(uk, 0);
@@ -287,15 +283,16 @@ static VALUE Unpacker_each_impl(VALUE self)
287
283
  }
288
284
  }
289
285
 
290
- static VALUE Unpacker_rescue_EOFError(VALUE self)
286
+ static VALUE Unpacker_rescue_EOFError(VALUE args, VALUE error)
291
287
  {
292
- UNUSED(self);
288
+ UNUSED(args);
289
+ UNUSED(error);
293
290
  return Qnil;
294
291
  }
295
292
 
296
293
  static VALUE Unpacker_each(VALUE self)
297
294
  {
298
- UNPACKER(self, uk);
295
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
299
296
 
300
297
  #ifdef RETURN_ENUMERATOR
301
298
  RETURN_ENUMERATOR(self, 0, 0);
@@ -326,7 +323,7 @@ static VALUE Unpacker_feed_each(VALUE self, VALUE data)
326
323
 
327
324
  static VALUE Unpacker_reset(VALUE self)
328
325
  {
329
- UNPACKER(self, uk);
326
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
330
327
 
331
328
  _msgpack_unpacker_reset(uk);
332
329
 
@@ -335,63 +332,40 @@ static VALUE Unpacker_reset(VALUE self)
335
332
 
336
333
  static VALUE Unpacker_registered_types_internal(VALUE self)
337
334
  {
338
- UNPACKER(self, uk);
335
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
339
336
 
340
337
  VALUE mapping = rb_hash_new();
341
- for(int i=0; i < 256; i++) {
342
- if(uk->ext_registry.array[i] != Qnil) {
343
- rb_hash_aset(mapping, INT2FIX(i - 128), uk->ext_registry.array[i]);
338
+ if (uk->ext_registry) {
339
+ for(int i=0; i < 256; i++) {
340
+ if(uk->ext_registry->array[i] != Qnil) {
341
+ rb_hash_aset(mapping, INT2FIX(i - 128), uk->ext_registry->array[i]);
342
+ }
344
343
  }
345
344
  }
346
345
 
347
346
  return mapping;
348
347
  }
349
348
 
350
- static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
349
+ static VALUE Unpacker_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
351
350
  {
352
- UNPACKER(self, uk);
353
-
354
- int ext_type;
355
- VALUE proc;
356
- VALUE arg;
357
- VALUE ext_module;
358
-
359
- switch (argc) {
360
- case 1:
361
- /* register_type(0x7f) {|data| block... } */
362
- rb_need_block();
363
- #ifdef HAVE_RB_BLOCK_LAMBDA
364
- proc = rb_block_lambda();
365
- #else
366
- /* MRI 1.8 */
367
- proc = rb_block_proc();
368
- #endif
369
- arg = proc;
370
- ext_module = Qnil;
371
- break;
372
- case 3:
373
- /* register_type(0x7f, Time, :from_msgpack_ext) */
374
- ext_module = argv[1];
375
- arg = argv[2];
376
- proc = rb_obj_method(ext_module, arg);
377
- break;
378
- default:
379
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 3)", argc);
351
+ if (OBJ_FROZEN(self)) {
352
+ rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Unpacker");
380
353
  }
381
354
 
382
- ext_type = NUM2INT(argv[0]);
355
+ int ext_type = NUM2INT(rb_ext_type);
383
356
  if(ext_type < -128 || ext_type > 127) {
384
357
  rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
385
358
  }
386
359
 
387
- msgpack_unpacker_ext_registry_put(&uk->ext_registry, ext_module, ext_type, proc, arg);
360
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
361
+ msgpack_unpacker_ext_registry_put(self, &uk->ext_registry, ext_module, ext_type, 0, proc);
388
362
 
389
363
  return Qnil;
390
364
  }
391
365
 
392
366
  static VALUE Unpacker_full_unpack(VALUE self)
393
367
  {
394
- UNPACKER(self, uk);
368
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
395
369
 
396
370
  int r = msgpack_unpacker_read(uk, 0);
397
371
  if(r < 0) {
@@ -417,7 +391,6 @@ VALUE MessagePack_Unpacker_new(int argc, VALUE* argv)
417
391
  void MessagePack_Unpacker_module_init(VALUE mMessagePack)
418
392
  {
419
393
  msgpack_unpacker_static_init();
420
- msgpack_unpacker_ext_registry_static_init();
421
394
 
422
395
  mTypeError = rb_define_module_under(mMessagePack, "TypeError");
423
396
 
@@ -434,10 +407,15 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
434
407
 
435
408
  eUnknownExtTypeError = rb_define_class_under(mMessagePack, "UnknownExtTypeError", eUnpackError);
436
409
 
410
+ sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys"));
411
+ sym_freeze = ID2SYM(rb_intern("freeze"));
412
+ sym_allow_unknown_ext = ID2SYM(rb_intern("allow_unknown_ext"));
413
+
437
414
  rb_define_alloc_func(cMessagePack_Unpacker, MessagePack_Unpacker_alloc);
438
415
 
439
416
  rb_define_method(cMessagePack_Unpacker, "initialize", MessagePack_Unpacker_initialize, -1);
440
417
  rb_define_method(cMessagePack_Unpacker, "symbolize_keys?", Unpacker_symbolized_keys_p, 0);
418
+ rb_define_method(cMessagePack_Unpacker, "freeze?", Unpacker_freeze_p, 0);
441
419
  rb_define_method(cMessagePack_Unpacker, "allow_unknown_ext?", Unpacker_allow_unknown_ext_p, 0);
442
420
  rb_define_method(cMessagePack_Unpacker, "buffer", Unpacker_buffer, 0);
443
421
  rb_define_method(cMessagePack_Unpacker, "read", Unpacker_read, 0);
@@ -446,22 +424,14 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
446
424
  rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
447
425
  rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
448
426
  rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
449
- //rb_define_method(cMessagePack_Unpacker, "peek_next_type", Unpacker_peek_next_type, 0); // TODO
450
- rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1);
451
- rb_define_method(cMessagePack_Unpacker, "feed_reference", Unpacker_feed_reference, 1);
427
+ rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed_reference, 1);
428
+ rb_define_alias(cMessagePack_Unpacker, "feed_reference", "feed");
452
429
  rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
453
430
  rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1);
454
431
  rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
455
432
 
456
433
  rb_define_private_method(cMessagePack_Unpacker, "registered_types_internal", Unpacker_registered_types_internal, 0);
457
- rb_define_method(cMessagePack_Unpacker, "register_type", Unpacker_register_type, -1);
458
-
459
- //s_unpacker_value = MessagePack_Unpacker_alloc(cMessagePack_Unpacker);
460
- //rb_gc_register_address(&s_unpacker_value);
461
- //Data_Get_Struct(s_unpacker_value, msgpack_unpacker_t, s_unpacker);
462
- /* prefer reference than copying */
463
- //msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(s_unpacker), 0);
434
+ rb_define_private_method(cMessagePack_Unpacker, "register_type_internal", Unpacker_register_type_internal, 3);
464
435
 
465
436
  rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
466
437
  }
467
-
@@ -20,6 +20,17 @@
20
20
 
21
21
  #include "unpacker.h"
22
22
 
23
+ extern const rb_data_type_t unpacker_data_type;
24
+
25
+ static inline msgpack_unpacker_t *MessagePack_Unpacker_get(VALUE object) {
26
+ msgpack_unpacker_t *unpacker;
27
+ TypedData_Get_Struct(object, msgpack_unpacker_t, &unpacker_data_type, unpacker);
28
+ if (!unpacker) {
29
+ rb_raise(rb_eArgError, "Uninitialized Unpacker object");
30
+ }
31
+ return unpacker;
32
+ }
33
+
23
34
  extern VALUE cMessagePack_Unpacker;
24
35
 
25
36
  void MessagePack_Unpacker_module_init(VALUE mMessagePack);
@@ -18,45 +18,57 @@
18
18
 
19
19
  #include "unpacker_ext_registry.h"
20
20
 
21
- static ID s_call;
22
- static ID s_dup;
23
-
24
- void msgpack_unpacker_ext_registry_static_init()
25
- {
26
- s_call = rb_intern("call");
27
- s_dup = rb_intern("dup");
28
- }
29
-
30
- void msgpack_unpacker_ext_registry_static_destroy()
31
- { }
32
-
33
- void msgpack_unpacker_ext_registry_init(msgpack_unpacker_ext_registry_t* ukrg)
21
+ void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg)
34
22
  {
35
- for(int i=0; i < 256; i++) {
36
- ukrg->array[i] = Qnil;
23
+ if (ukrg) {
24
+ for(int i=0; i < 256; i++) {
25
+ if (ukrg->array[i] != Qnil) {
26
+ rb_gc_mark(ukrg->array[i]);
27
+ }
28
+ }
37
29
  }
38
30
  }
39
31
 
40
- void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg)
32
+ msgpack_unpacker_ext_registry_t* msgpack_unpacker_ext_registry_cow(msgpack_unpacker_ext_registry_t* src)
41
33
  {
42
- for(int i=0; i < 256; i++) {
43
- rb_gc_mark(ukrg->array[i]);
34
+ msgpack_unpacker_ext_registry_t* dst;
35
+ if (src) {
36
+ if (src->borrow_count) {
37
+ dst = ALLOC(msgpack_unpacker_ext_registry_t);
38
+ dst->borrow_count = 0;
39
+ MEMCPY(dst->array, src->array, VALUE, 256);
40
+ msgpack_unpacker_ext_registry_release(src);
41
+ return dst;
42
+ } else {
43
+ return src;
44
+ }
45
+ } else {
46
+ dst = ALLOC(msgpack_unpacker_ext_registry_t);
47
+ dst->borrow_count = 0;
48
+ for(int i=0; i < 256; i++) {
49
+ dst->array[i] = Qnil;
50
+ }
51
+ return dst;
44
52
  }
45
53
  }
46
54
 
47
- void msgpack_unpacker_ext_registry_dup(msgpack_unpacker_ext_registry_t* src,
48
- msgpack_unpacker_ext_registry_t* dst)
55
+ void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg)
49
56
  {
50
- for(int i=0; i < 256; i++) {
51
- dst->array[i] = src->array[i];
57
+ if (ukrg) {
58
+ if (ukrg->borrow_count) {
59
+ ukrg->borrow_count--;
60
+ } else {
61
+ xfree(ukrg);
62
+ }
52
63
  }
53
64
  }
54
65
 
55
- VALUE msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t* ukrg,
56
- VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
66
+ void msgpack_unpacker_ext_registry_put(VALUE owner, msgpack_unpacker_ext_registry_t** ukrg,
67
+ VALUE ext_module, int ext_type, int flags, VALUE proc)
57
68
  {
58
- VALUE e = rb_ary_new3(3, ext_module, proc, arg);
59
- VALUE before = ukrg->array[ext_type + 128];
60
- ukrg->array[ext_type + 128] = e;
61
- return before;
69
+ msgpack_unpacker_ext_registry_t* ext_registry = msgpack_unpacker_ext_registry_cow(*ukrg);
70
+
71
+ VALUE entry = rb_ary_new3(3, ext_module, proc, INT2FIX(flags));
72
+ RB_OBJ_WRITE(owner, &ext_registry->array[ext_type + 128], entry);
73
+ *ukrg = ext_registry;
62
74
  }
@@ -21,39 +21,42 @@
21
21
  #include "compat.h"
22
22
  #include "ruby.h"
23
23
 
24
+ #define MSGPACK_EXT_RECURSIVE 0b0001
25
+
24
26
  struct msgpack_unpacker_ext_registry_t;
25
27
  typedef struct msgpack_unpacker_ext_registry_t msgpack_unpacker_ext_registry_t;
26
28
 
27
29
  struct msgpack_unpacker_ext_registry_t {
30
+ unsigned int borrow_count;
28
31
  VALUE array[256];
29
- //int bitmap;
30
32
  };
31
33
 
32
- void msgpack_unpacker_ext_registry_static_init();
33
-
34
- void msgpack_unpacker_ext_registry_static_destroy();
34
+ void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg);
35
35
 
36
- void msgpack_unpacker_ext_registry_init(msgpack_unpacker_ext_registry_t* ukrg);
37
-
38
- static inline void msgpack_unpacker_ext_registry_destroy(msgpack_unpacker_ext_registry_t* ukrg)
39
- { }
36
+ static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_registry_t* src, msgpack_unpacker_ext_registry_t** dst)
37
+ {
38
+ if (src) {
39
+ src->borrow_count++;
40
+ *dst = src;
41
+ }
42
+ }
40
43
 
41
44
  void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg);
42
45
 
43
- void msgpack_unpacker_ext_registry_dup(msgpack_unpacker_ext_registry_t* src,
44
- msgpack_unpacker_ext_registry_t* dst);
45
-
46
- VALUE msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t* ukrg,
47
- VALUE ext_module, int ext_type, VALUE proc, VALUE arg);
46
+ void msgpack_unpacker_ext_registry_put(VALUE owner, msgpack_unpacker_ext_registry_t** ukrg,
47
+ VALUE ext_module, int ext_type, int flags, VALUE proc);
48
48
 
49
49
  static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_registry_t* ukrg,
50
- int ext_type)
50
+ int ext_type, int* ext_flags_result)
51
51
  {
52
- VALUE e = ukrg->array[ext_type + 128];
53
- if(e == Qnil) {
54
- return Qnil;
52
+ if (ukrg) {
53
+ VALUE entry = ukrg->array[ext_type + 128];
54
+ if (entry != Qnil) {
55
+ *ext_flags_result = FIX2INT(rb_ary_entry(entry, 2));
56
+ return rb_ary_entry(entry, 1);
57
+ }
55
58
  }
56
- return rb_ary_entry(e, 1);
59
+ return Qnil;
57
60
  }
58
61
 
59
62
  #endif
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MessagePack
4
+ module Bigint
5
+ # We split the bigint in 32bits chunks so that individual part fits into
6
+ # a MRI immediate Integer.
7
+ CHUNK_BITLENGTH = 32
8
+ FORMAT = 'CL>*'
9
+
10
+ if Integer.instance_method(:[]).arity != 1 # Ruby 2.7 and newer
11
+ # Starting from Ruby 2.7 we can address arbitrary bitranges inside an Integer with Integer#[]
12
+ # This allows to not allocate any Integer.
13
+ def self.to_msgpack_ext(bigint)
14
+ members = []
15
+
16
+ if bigint < 0
17
+ bigint = -bigint
18
+ members << 1
19
+ else
20
+ members << 0
21
+ end
22
+
23
+ offset = 0
24
+ length = bigint.bit_length
25
+ while offset < length
26
+ members << bigint[offset, CHUNK_BITLENGTH]
27
+ offset += CHUNK_BITLENGTH
28
+ end
29
+
30
+ members.pack(FORMAT)
31
+ end
32
+ else
33
+ # On 2.6 and older since we can't address arbitrary bitranges, so we fallback to shifting the bigint.
34
+ # This means that after each shift, we may allocate another Integer instance.
35
+ BASE = (2**CHUNK_BITLENGTH) - 1
36
+ def self.to_msgpack_ext(bigint)
37
+ members = []
38
+
39
+ if bigint < 0
40
+ bigint = -bigint
41
+ members << 1
42
+ else
43
+ members << 0
44
+ end
45
+
46
+ while bigint > 0
47
+ members << (bigint & BASE)
48
+ bigint = bigint >> CHUNK_BITLENGTH
49
+ end
50
+
51
+ members.pack(FORMAT)
52
+ end
53
+ end
54
+
55
+ def self.from_msgpack_ext(data)
56
+ parts = data.unpack(FORMAT)
57
+
58
+ sign = parts.shift
59
+ sum = parts.pop.to_i
60
+
61
+ parts.reverse_each do |part|
62
+ sum = sum << CHUNK_BITLENGTH
63
+ sum += part
64
+ end
65
+
66
+ sign == 0 ? sum : -sum
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,9 @@
1
+ module MessagePack
2
+ class Buffer
3
+ # see ext for other methods
4
+
5
+ # The semantic of duping a buffer is just too weird.
6
+ undef_method :dup
7
+ undef_method :clone
8
+ end
9
+ end