msgpack 1.3.3 → 1.7.2

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.
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