msgpack 1.5.1 → 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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +55 -0
  3. data/README.md +30 -1
  4. data/ext/java/org/msgpack/jruby/Buffer.java +3 -3
  5. data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +11 -20
  6. data/ext/java/org/msgpack/jruby/ExtensionValue.java +1 -1
  7. data/ext/java/org/msgpack/jruby/Factory.java +11 -50
  8. data/ext/java/org/msgpack/jruby/Packer.java +9 -24
  9. data/ext/java/org/msgpack/jruby/Unpacker.java +15 -32
  10. data/ext/msgpack/buffer.c +54 -69
  11. data/ext/msgpack/buffer.h +16 -18
  12. data/ext/msgpack/buffer_class.c +138 -37
  13. data/ext/msgpack/buffer_class.h +1 -0
  14. data/ext/msgpack/compat.h +0 -99
  15. data/ext/msgpack/extconf.rb +25 -39
  16. data/ext/msgpack/factory_class.c +75 -86
  17. data/ext/msgpack/packer.c +12 -39
  18. data/ext/msgpack/packer.h +1 -11
  19. data/ext/msgpack/packer_class.c +73 -99
  20. data/ext/msgpack/packer_class.h +11 -0
  21. data/ext/msgpack/packer_ext_registry.c +31 -28
  22. data/ext/msgpack/packer_ext_registry.h +10 -14
  23. data/ext/msgpack/rbinit.c +1 -1
  24. data/ext/msgpack/rmem.c +3 -4
  25. data/ext/msgpack/sysdep.h +5 -2
  26. data/ext/msgpack/unpacker.c +66 -94
  27. data/ext/msgpack/unpacker.h +13 -12
  28. data/ext/msgpack/unpacker_class.c +64 -80
  29. data/ext/msgpack/unpacker_class.h +11 -0
  30. data/ext/msgpack/unpacker_ext_registry.c +4 -16
  31. data/ext/msgpack/unpacker_ext_registry.h +3 -7
  32. data/lib/msgpack/buffer.rb +9 -0
  33. data/lib/msgpack/factory.rb +90 -63
  34. data/lib/msgpack/packer.rb +10 -1
  35. data/lib/msgpack/unpacker.rb +14 -1
  36. data/lib/msgpack/version.rb +1 -1
  37. data/lib/msgpack.rb +1 -0
  38. data/msgpack.gemspec +7 -3
  39. metadata +33 -56
  40. data/.github/workflows/ci.yaml +0 -57
  41. data/.gitignore +0 -23
  42. data/.rubocop.yml +0 -36
  43. data/Gemfile +0 -9
  44. data/Rakefile +0 -70
  45. data/appveyor.yml +0 -18
  46. data/bench/pack.rb +0 -23
  47. data/bench/pack_log.rb +0 -33
  48. data/bench/pack_log_long.rb +0 -65
  49. data/bench/pack_symbols.rb +0 -28
  50. data/bench/run.sh +0 -14
  51. data/bench/run_long.sh +0 -35
  52. data/bench/run_symbols.sh +0 -26
  53. data/bench/unpack.rb +0 -21
  54. data/bench/unpack_log.rb +0 -34
  55. data/bench/unpack_log_long.rb +0 -67
  56. data/doclib/msgpack/buffer.rb +0 -193
  57. data/doclib/msgpack/core_ext.rb +0 -101
  58. data/doclib/msgpack/error.rb +0 -19
  59. data/doclib/msgpack/extension_value.rb +0 -9
  60. data/doclib/msgpack/factory.rb +0 -145
  61. data/doclib/msgpack/packer.rb +0 -209
  62. data/doclib/msgpack/time.rb +0 -22
  63. data/doclib/msgpack/timestamp.rb +0 -44
  64. data/doclib/msgpack/unpacker.rb +0 -183
  65. data/doclib/msgpack.rb +0 -87
  66. data/msgpack.org.md +0 -46
  67. data/spec/bigint_spec.rb +0 -26
  68. data/spec/cases.json +0 -1
  69. data/spec/cases.msg +0 -0
  70. data/spec/cases_compact.msg +0 -0
  71. data/spec/cases_spec.rb +0 -39
  72. data/spec/cruby/buffer_io_spec.rb +0 -255
  73. data/spec/cruby/buffer_packer.rb +0 -29
  74. data/spec/cruby/buffer_spec.rb +0 -575
  75. data/spec/cruby/buffer_unpacker.rb +0 -19
  76. data/spec/cruby/unpacker_spec.rb +0 -70
  77. data/spec/ext_value_spec.rb +0 -99
  78. data/spec/exttypes.rb +0 -51
  79. data/spec/factory_spec.rb +0 -654
  80. data/spec/format_spec.rb +0 -301
  81. data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
  82. data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
  83. data/spec/jruby/unpacker_spec.rb +0 -186
  84. data/spec/msgpack_spec.rb +0 -214
  85. data/spec/pack_spec.rb +0 -61
  86. data/spec/packer_spec.rb +0 -575
  87. data/spec/random_compat.rb +0 -24
  88. data/spec/spec_helper.rb +0 -65
  89. data/spec/timestamp_spec.rb +0 -159
  90. data/spec/unpack_spec.rb +0 -57
  91. data/spec/unpacker_spec.rb +0 -847
@@ -37,15 +37,9 @@ static VALUE sym_symbolize_keys;
37
37
  static VALUE sym_freeze;
38
38
  static VALUE sym_allow_unknown_ext;
39
39
 
40
- #define UNPACKER(from, name) \
41
- msgpack_unpacker_t *name = NULL; \
42
- Data_Get_Struct(from, msgpack_unpacker_t, name); \
43
- if(name == NULL) { \
44
- rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be."); \
45
- }
46
-
47
- static void Unpacker_free(msgpack_unpacker_t* uk)
40
+ static void Unpacker_free(void *ptr)
48
41
  {
42
+ msgpack_unpacker_t* uk = ptr;
49
43
  if(uk == NULL) {
50
44
  return;
51
45
  }
@@ -54,17 +48,44 @@ static void Unpacker_free(msgpack_unpacker_t* uk)
54
48
  xfree(uk);
55
49
  }
56
50
 
57
- static void Unpacker_mark(msgpack_unpacker_t* uk)
51
+ static void Unpacker_mark(void *ptr)
58
52
  {
53
+ msgpack_unpacker_t* uk = ptr;
54
+ msgpack_buffer_mark(uk);
59
55
  msgpack_unpacker_mark(uk);
60
56
  msgpack_unpacker_ext_registry_mark(uk->ext_registry);
61
57
  }
62
58
 
63
- VALUE MessagePack_Unpacker_alloc(VALUE klass)
59
+ static size_t Unpacker_memsize(const void *ptr)
64
60
  {
65
- msgpack_unpacker_t* uk = _msgpack_unpacker_new();
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);
66
69
 
67
- VALUE self = Data_Wrap_Struct(klass, Unpacker_mark, Unpacker_free, uk);
70
+ return total_size + msgpack_buffer_memsize(&uk->buffer);
71
+ }
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
+
83
+ VALUE MessagePack_Unpacker_alloc(VALUE klass)
84
+ {
85
+ msgpack_unpacker_t* uk;
86
+ VALUE self = TypedData_Make_Struct(klass, msgpack_unpacker_t, &unpacker_data_type, uk);
87
+ _msgpack_unpacker_init(uk);
88
+ uk->self = self;
68
89
  return self;
69
90
  }
70
91
 
@@ -95,9 +116,9 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
95
116
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
96
117
  }
97
118
 
98
- UNPACKER(self, uk);
119
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
99
120
 
100
- uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
121
+ uk->buffer_ref = Qnil;
101
122
 
102
123
  MessagePack_Buffer_set_options(UNPACKER_BUFFER_(uk), io, options);
103
124
 
@@ -119,19 +140,19 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
119
140
 
120
141
  static VALUE Unpacker_symbolized_keys_p(VALUE self)
121
142
  {
122
- UNPACKER(self, uk);
143
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
123
144
  return uk->symbolize_keys ? Qtrue : Qfalse;
124
145
  }
125
146
 
126
147
  static VALUE Unpacker_freeze_p(VALUE self)
127
148
  {
128
- UNPACKER(self, uk);
149
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
129
150
  return uk->freeze ? Qtrue : Qfalse;
130
151
  }
131
152
 
132
153
  static VALUE Unpacker_allow_unknown_ext_p(VALUE self)
133
154
  {
134
- UNPACKER(self, uk);
155
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
135
156
  return uk->allow_unknown_ext ? Qtrue : Qfalse;
136
157
  }
137
158
 
@@ -156,13 +177,16 @@ NORETURN(static void raise_unpacker_error(int r))
156
177
 
157
178
  static VALUE Unpacker_buffer(VALUE self)
158
179
  {
159
- 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
+ }
160
184
  return uk->buffer_ref;
161
185
  }
162
186
 
163
187
  static VALUE Unpacker_read(VALUE self)
164
188
  {
165
- UNPACKER(self, uk);
189
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
166
190
 
167
191
  int r = msgpack_unpacker_read(uk, 0);
168
192
  if(r < 0) {
@@ -174,7 +198,7 @@ static VALUE Unpacker_read(VALUE self)
174
198
 
175
199
  static VALUE Unpacker_skip(VALUE self)
176
200
  {
177
- UNPACKER(self, uk);
201
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
178
202
 
179
203
  int r = msgpack_unpacker_skip(uk, 0);
180
204
  if(r < 0) {
@@ -186,7 +210,7 @@ static VALUE Unpacker_skip(VALUE self)
186
210
 
187
211
  static VALUE Unpacker_skip_nil(VALUE self)
188
212
  {
189
- UNPACKER(self, uk);
213
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
190
214
 
191
215
  int r = msgpack_unpacker_skip_nil(uk);
192
216
  if(r < 0) {
@@ -201,7 +225,7 @@ static VALUE Unpacker_skip_nil(VALUE self)
201
225
 
202
226
  static VALUE Unpacker_read_array_header(VALUE self)
203
227
  {
204
- UNPACKER(self, uk);
228
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
205
229
 
206
230
  uint32_t size;
207
231
  int r = msgpack_unpacker_read_array_header(uk, &size);
@@ -209,12 +233,12 @@ static VALUE Unpacker_read_array_header(VALUE self)
209
233
  raise_unpacker_error(r);
210
234
  }
211
235
 
212
- return ULONG2NUM(size);
236
+ return ULONG2NUM(size); // long at least 32 bits
213
237
  }
214
238
 
215
239
  static VALUE Unpacker_read_map_header(VALUE self)
216
240
  {
217
- UNPACKER(self, uk);
241
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
218
242
 
219
243
  uint32_t size;
220
244
  int r = msgpack_unpacker_read_map_header(uk, &size);
@@ -222,24 +246,12 @@ static VALUE Unpacker_read_map_header(VALUE self)
222
246
  raise_unpacker_error((int)r);
223
247
  }
224
248
 
225
- return ULONG2NUM(size);
226
- }
227
-
228
-
229
- static VALUE Unpacker_feed(VALUE self, VALUE data)
230
- {
231
- UNPACKER(self, uk);
232
-
233
- StringValue(data);
234
-
235
- msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), data);
236
-
237
- return self;
249
+ return ULONG2NUM(size); // long at least 32 bits
238
250
  }
239
251
 
240
252
  static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
241
253
  {
242
- UNPACKER(self, uk);
254
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
243
255
 
244
256
  StringValue(data);
245
257
 
@@ -250,7 +262,7 @@ static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
250
262
 
251
263
  static VALUE Unpacker_each_impl(VALUE self)
252
264
  {
253
- UNPACKER(self, uk);
265
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
254
266
 
255
267
  while(true) {
256
268
  int r = msgpack_unpacker_read(uk, 0);
@@ -280,7 +292,7 @@ static VALUE Unpacker_rescue_EOFError(VALUE args, VALUE error)
280
292
 
281
293
  static VALUE Unpacker_each(VALUE self)
282
294
  {
283
- UNPACKER(self, uk);
295
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
284
296
 
285
297
  #ifdef RETURN_ENUMERATOR
286
298
  RETURN_ENUMERATOR(self, 0, 0);
@@ -311,7 +323,7 @@ static VALUE Unpacker_feed_each(VALUE self, VALUE data)
311
323
 
312
324
  static VALUE Unpacker_reset(VALUE self)
313
325
  {
314
- UNPACKER(self, uk);
326
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
315
327
 
316
328
  _msgpack_unpacker_reset(uk);
317
329
 
@@ -320,7 +332,7 @@ static VALUE Unpacker_reset(VALUE self)
320
332
 
321
333
  static VALUE Unpacker_registered_types_internal(VALUE self)
322
334
  {
323
- UNPACKER(self, uk);
335
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
324
336
 
325
337
  VALUE mapping = rb_hash_new();
326
338
  if (uk->ext_registry) {
@@ -334,46 +346,26 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
334
346
  return mapping;
335
347
  }
336
348
 
337
- 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)
338
350
  {
339
- UNPACKER(self, uk);
340
-
341
- int ext_type;
342
- VALUE proc;
343
- VALUE arg;
344
- VALUE ext_module;
345
-
346
- switch (argc) {
347
- case 1:
348
- /* register_type(0x7f) {|data| block... } */
349
- rb_need_block();
350
- proc = rb_block_lambda();
351
- arg = proc;
352
- ext_module = Qnil;
353
- break;
354
- case 3:
355
- /* register_type(0x7f, Time, :from_msgpack_ext) */
356
- ext_module = argv[1];
357
- arg = argv[2];
358
- proc = rb_obj_method(ext_module, arg);
359
- break;
360
- default:
361
- 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");
362
353
  }
363
354
 
364
- ext_type = NUM2INT(argv[0]);
355
+ int ext_type = NUM2INT(rb_ext_type);
365
356
  if(ext_type < -128 || ext_type > 127) {
366
357
  rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
367
358
  }
368
359
 
369
- msgpack_unpacker_ext_registry_put(&uk->ext_registry, ext_module, ext_type, 0, 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);
370
362
 
371
363
  return Qnil;
372
364
  }
373
365
 
374
366
  static VALUE Unpacker_full_unpack(VALUE self)
375
367
  {
376
- UNPACKER(self, uk);
368
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
377
369
 
378
370
  int r = msgpack_unpacker_read(uk, 0);
379
371
  if(r < 0) {
@@ -399,7 +391,6 @@ VALUE MessagePack_Unpacker_new(int argc, VALUE* argv)
399
391
  void MessagePack_Unpacker_module_init(VALUE mMessagePack)
400
392
  {
401
393
  msgpack_unpacker_static_init();
402
- msgpack_unpacker_ext_registry_static_init();
403
394
 
404
395
  mTypeError = rb_define_module_under(mMessagePack, "TypeError");
405
396
 
@@ -433,21 +424,14 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
433
424
  rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
434
425
  rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
435
426
  rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
436
- rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1);
437
- 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");
438
429
  rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
439
430
  rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1);
440
431
  rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
441
432
 
442
433
  rb_define_private_method(cMessagePack_Unpacker, "registered_types_internal", Unpacker_registered_types_internal, 0);
443
- rb_define_method(cMessagePack_Unpacker, "register_type", Unpacker_register_type, -1);
444
-
445
- //s_unpacker_value = MessagePack_Unpacker_alloc(cMessagePack_Unpacker);
446
- //rb_gc_register_address(&s_unpacker_value);
447
- //Data_Get_Struct(s_unpacker_value, msgpack_unpacker_t, s_unpacker);
448
- /* prefer reference than copying */
449
- //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);
450
435
 
451
436
  rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
452
437
  }
453
-
@@ -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,19 +18,6 @@
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
-
31
- void msgpack_unpacker_ext_registry_static_destroy()
32
- { }
33
-
34
21
  void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg)
35
22
  {
36
23
  if (ukrg) {
@@ -76,11 +63,12 @@ void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg
76
63
  }
77
64
  }
78
65
 
79
- void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
80
- VALUE ext_module, int ext_type, int flags, 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)
81
68
  {
82
69
  msgpack_unpacker_ext_registry_t* ext_registry = msgpack_unpacker_ext_registry_cow(*ukrg);
83
70
 
84
- ext_registry->array[ext_type + 128] = rb_ary_new3(4, ext_module, proc, arg, INT2FIX(flags));
71
+ VALUE entry = rb_ary_new3(3, ext_module, proc, INT2FIX(flags));
72
+ RB_OBJ_WRITE(owner, &ext_registry->array[ext_type + 128], entry);
85
73
  *ukrg = ext_registry;
86
74
  }
@@ -31,10 +31,6 @@ struct msgpack_unpacker_ext_registry_t {
31
31
  VALUE array[256];
32
32
  };
33
33
 
34
- void msgpack_unpacker_ext_registry_static_init();
35
-
36
- void msgpack_unpacker_ext_registry_static_destroy();
37
-
38
34
  void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg);
39
35
 
40
36
  static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_registry_t* src, msgpack_unpacker_ext_registry_t** dst)
@@ -47,8 +43,8 @@ static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_reg
47
43
 
48
44
  void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg);
49
45
 
50
- void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
51
- VALUE ext_module, int ext_type, int flags, 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);
52
48
 
53
49
  static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_registry_t* ukrg,
54
50
  int ext_type, int* ext_flags_result)
@@ -56,7 +52,7 @@ static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_re
56
52
  if (ukrg) {
57
53
  VALUE entry = ukrg->array[ext_type + 128];
58
54
  if (entry != Qnil) {
59
- *ext_flags_result = FIX2INT(rb_ary_entry(entry, 3));
55
+ *ext_flags_result = FIX2INT(rb_ary_entry(entry, 2));
60
56
  return rb_ary_entry(entry, 1);
61
57
  }
62
58
  }
@@ -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
@@ -2,11 +2,46 @@ module MessagePack
2
2
  class Factory
3
3
  # see ext for other methods
4
4
 
5
+ def register_type(type, klass, options = { packer: :to_msgpack_ext, unpacker: :from_msgpack_ext })
6
+ raise FrozenError, "can't modify frozen MessagePack::Factory" if frozen?
7
+
8
+ if options
9
+ options = options.dup
10
+ case packer = options[:packer]
11
+ when nil, Proc
12
+ # all good
13
+ when String, Symbol
14
+ options[:packer] = packer.to_sym.to_proc
15
+ when Method
16
+ options[:packer] = packer.to_proc
17
+ when packer.respond_to?(:call)
18
+ options[:packer] = packer.method(:call).to_proc
19
+ else
20
+ raise ::TypeError, "expected :packer argument to be a callable object, got: #{packer.inspect}"
21
+ end
22
+
23
+ case unpacker = options[:unpacker]
24
+ when nil, Proc
25
+ # all good
26
+ when String, Symbol
27
+ options[:unpacker] = klass.method(unpacker).to_proc
28
+ when Method
29
+ options[:unpacker] = unpacker.to_proc
30
+ when packer.respond_to?(:call)
31
+ options[:unpacker] = unpacker.method(:call).to_proc
32
+ else
33
+ raise ::TypeError, "expected :unpacker argument to be a callable object, got: #{unpacker.inspect}"
34
+ end
35
+ end
36
+
37
+ register_type_internal(type, klass, options)
38
+ end
39
+
5
40
  # [ {type: id, class: Class(or nil), packer: arg, unpacker: arg}, ... ]
6
41
  def registered_types(selector=:both)
7
42
  packer, unpacker = registered_types_internal
8
- # packer: Class -> [tid, proc, arg]
9
- # unpacker: tid -> [klass, proc, arg]
43
+ # packer: Class -> [tid, proc, _flags]
44
+ # unpacker: tid -> [klass, proc, _flags]
10
45
 
11
46
  list = []
12
47
 
@@ -14,27 +49,31 @@ module MessagePack
14
49
  when :both
15
50
  packer.each_pair do |klass, ary|
16
51
  type = ary[0]
17
- packer_arg = ary[2]
18
- unpacker_arg = nil
19
- if unpacker.has_key?(type) && unpacker[type][0] == klass
20
- unpacker_arg = unpacker.delete(type)[2]
52
+ packer_proc = ary[1]
53
+ unpacker_proc = nil
54
+ if unpacker.has_key?(type)
55
+ unpacker_proc = unpacker.delete(type)[1]
21
56
  end
22
- list << {type: type, class: klass, packer: packer_arg, unpacker: unpacker_arg}
57
+ list << {type: type, class: klass, packer: packer_proc, unpacker: unpacker_proc}
23
58
  end
24
59
 
25
60
  # unpacker definition only
26
61
  unpacker.each_pair do |type, ary|
27
- list << {type: type, class: ary[0], packer: nil, unpacker: ary[2]}
62
+ list << {type: type, class: ary[0], packer: nil, unpacker: ary[1]}
28
63
  end
29
64
 
30
65
  when :packer
31
66
  packer.each_pair do |klass, ary|
32
- list << {type: ary[0], class: klass, packer: ary[2]}
67
+ if ary[1]
68
+ list << {type: ary[0], class: klass, packer: ary[1]}
69
+ end
33
70
  end
34
71
 
35
72
  when :unpacker
36
73
  unpacker.each_pair do |type, ary|
37
- list << {type: type, class: ary[0], unpacker: ary[2]}
74
+ if ary[1]
75
+ list << {type: type, class: ary[0], unpacker: ary[1]}
76
+ end
38
77
  end
39
78
 
40
79
  else
@@ -88,33 +127,34 @@ module MessagePack
88
127
 
89
128
  class Pool
90
129
  if RUBY_ENGINE == "ruby"
91
- class AbstractPool
130
+ class MemberPool
92
131
  def initialize(size, &block)
93
132
  @size = size
94
133
  @new_member = block
95
134
  @members = []
96
135
  end
97
136
 
98
- def checkout
99
- @members.pop || @new_member.call
100
- end
101
-
102
- def checkin(member)
103
- # If the pool is already full, we simply drop the extra member.
104
- # This is because contrary to a connection pool, creating an extra instance
105
- # is extremely unlikely to cause some kind of resource exhaustion.
106
- #
107
- # We could cycle the members (keep the newer one) but first It's more work and second
108
- # the older member might have been created pre-fork, so it might be at least partially
109
- # in shared memory.
110
- if member && @members.size < @size
111
- member.reset
112
- @members << member
137
+ def with
138
+ member = @members.pop || @new_member.call
139
+ begin
140
+ yield member
141
+ ensure
142
+ # If the pool is already full, we simply drop the extra member.
143
+ # This is because contrary to a connection pool, creating an extra instance
144
+ # is extremely unlikely to cause some kind of resource exhaustion.
145
+ #
146
+ # We could cycle the members (keep the newer one) but first It's more work and second
147
+ # the older member might have been created pre-fork, so it might be at least partially
148
+ # in shared memory.
149
+ if member && @members.size < @size
150
+ member.reset
151
+ @members << member
152
+ end
113
153
  end
114
154
  end
115
155
  end
116
156
  else
117
- class AbstractPool
157
+ class MemberPool
118
158
  def initialize(size, &block)
119
159
  @size = size
120
160
  @new_member = block
@@ -122,63 +162,50 @@ module MessagePack
122
162
  @mutex = Mutex.new
123
163
  end
124
164
 
125
- def checkout
126
- @mutex.synchronize { @members.pop } || @new_member.call
127
- end
128
-
129
- def checkin(member)
130
- @mutex.synchronize do
131
- if member && @members.size < @size
132
- member.reset
133
- @members << member
165
+ def with
166
+ member = @mutex.synchronize { @members.pop } || @new_member.call
167
+ begin
168
+ yield member
169
+ ensure
170
+ member.reset
171
+ @mutex.synchronize do
172
+ if member && @members.size < @size
173
+ @members << member
174
+ end
134
175
  end
135
176
  end
136
177
  end
137
178
  end
138
179
  end
139
180
 
140
- class PackerPool < AbstractPool
141
- private
142
-
143
- def reset(packer)
144
- packer.clear
145
- end
146
- end
147
-
148
- class UnpackerPool < AbstractPool
149
- private
150
-
151
- def reset(unpacker)
152
- unpacker.reset
153
- end
154
- end
155
-
156
181
  def initialize(factory, size, options = nil)
157
182
  options = nil if !options || options.empty?
158
183
  @factory = factory
159
- @packers = PackerPool.new(size) { factory.packer(options) }
160
- @unpackers = UnpackerPool.new(size) { factory.unpacker(options) }
184
+ @packers = MemberPool.new(size) { factory.packer(options).freeze }
185
+ @unpackers = MemberPool.new(size) { factory.unpacker(options).freeze }
161
186
  end
162
187
 
163
188
  def load(data)
164
- unpacker = @unpackers.checkout
165
- begin
166
- unpacker.feed_reference(data)
189
+ @unpackers.with do |unpacker|
190
+ unpacker.feed(data)
167
191
  unpacker.full_unpack
168
- ensure
169
- @unpackers.checkin(unpacker)
170
192
  end
171
193
  end
172
194
 
173
195
  def dump(object)
174
- packer = @packers.checkout
175
- begin
196
+ @packers.with do |packer|
176
197
  packer.write(object)
177
198
  packer.full_pack
178
- ensure
179
- @packers.checkin(packer)
180
199
  end
181
200
  end
201
+
202
+ def unpacker(&block)
203
+ @unpackers.with(&block)
204
+ end
205
+
206
+ def packer(&block)
207
+ @packers.with(&block)
208
+ end
182
209
  end
183
210
  end
184
211
  end
@@ -2,11 +2,20 @@ module MessagePack
2
2
  class Packer
3
3
  # see ext for other methods
4
4
 
5
+ # The semantic of duping a packer is just too weird.
6
+ undef_method :dup
7
+ undef_method :clone
8
+
9
+ def register_type(type, klass, method_name = nil, &block)
10
+ raise ArgumentError, "expected Module/Class got: #{klass.inspect}" unless klass.is_a?(Module)
11
+ register_type_internal(type, klass, block || method_name.to_proc)
12
+ end
13
+
5
14
  def registered_types
6
15
  list = []
7
16
 
8
17
  registered_types_internal.each_pair do |klass, ary|
9
- list << {type: ary[0], class: klass, packer: ary[2]}
18
+ list << {type: ary[0], class: klass, packer: ary[1]}
10
19
  end
11
20
 
12
21
  list.sort{|a, b| a[:type] <=> b[:type] }
@@ -2,11 +2,24 @@ module MessagePack
2
2
  class Unpacker
3
3
  # see ext for other methods
4
4
 
5
+ # The semantic of duping an unpacker is just too weird.
6
+ undef_method :dup
7
+ undef_method :clone
8
+
9
+ def register_type(type, klass = nil, method_name = nil, &block)
10
+ if klass && method_name
11
+ block = klass.method(method_name).to_proc
12
+ elsif !block_given?
13
+ raise ArgumentError, "register_type takes either 3 arguments or a block"
14
+ end
15
+ register_type_internal(type, klass, block)
16
+ end
17
+
5
18
  def registered_types
6
19
  list = []
7
20
 
8
21
  registered_types_internal.each_pair do |type, ary|
9
- list << {type: type, class: ary[0], unpacker: ary[2]}
22
+ list << {type: type, class: ary[0], unpacker: ary[1]}
10
23
  end
11
24
 
12
25
  list.sort{|a, b| a[:type] <=> b[:type] }
@@ -1,5 +1,5 @@
1
1
  module MessagePack
2
- VERSION = "1.5.1"
2
+ VERSION = "1.7.2"
3
3
  # Note for maintainers:
4
4
  # Don't miss building/releasing the JRuby version (rake buld:java)
5
5
  # See "How to build -java rubygems" in README for more details.