msgpack 1.4.2 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +85 -0
  3. data/README.md +52 -1
  4. data/ext/java/org/msgpack/jruby/Buffer.java +26 -19
  5. data/ext/java/org/msgpack/jruby/Decoder.java +29 -21
  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 +80 -73
  12. data/ext/msgpack/buffer.c +54 -74
  13. data/ext/msgpack/buffer.h +21 -18
  14. data/ext/msgpack/buffer_class.c +161 -52
  15. data/ext/msgpack/buffer_class.h +1 -0
  16. data/ext/msgpack/compat.h +0 -99
  17. data/ext/msgpack/extconf.rb +25 -46
  18. data/ext/msgpack/factory_class.c +143 -87
  19. data/ext/msgpack/packer.c +66 -43
  20. data/ext/msgpack/packer.h +25 -20
  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 +126 -108
  29. data/ext/msgpack/unpacker.h +16 -13
  30. data/ext/msgpack/unpacker_class.c +86 -126
  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 +1 -1
  42. data/lib/msgpack.rb +6 -7
  43. data/msgpack.gemspec +8 -5
  44. metadata +37 -82
  45. data/.gitignore +0 -23
  46. data/.rubocop.yml +0 -36
  47. data/.travis.yml +0 -39
  48. data/Gemfile +0 -9
  49. data/Rakefile +0 -71
  50. data/appveyor.yml +0 -18
  51. data/bench/pack.rb +0 -23
  52. data/bench/pack_log.rb +0 -33
  53. data/bench/pack_log_long.rb +0 -65
  54. data/bench/pack_symbols.rb +0 -28
  55. data/bench/run.sh +0 -14
  56. data/bench/run_long.sh +0 -35
  57. data/bench/run_symbols.sh +0 -26
  58. data/bench/unpack.rb +0 -21
  59. data/bench/unpack_log.rb +0 -34
  60. data/bench/unpack_log_long.rb +0 -67
  61. data/doclib/msgpack/buffer.rb +0 -193
  62. data/doclib/msgpack/core_ext.rb +0 -101
  63. data/doclib/msgpack/error.rb +0 -19
  64. data/doclib/msgpack/extension_value.rb +0 -9
  65. data/doclib/msgpack/factory.rb +0 -101
  66. data/doclib/msgpack/packer.rb +0 -208
  67. data/doclib/msgpack/time.rb +0 -22
  68. data/doclib/msgpack/timestamp.rb +0 -44
  69. data/doclib/msgpack/unpacker.rb +0 -183
  70. data/doclib/msgpack.rb +0 -87
  71. data/msgpack.org.md +0 -46
  72. data/spec/cases.json +0 -1
  73. data/spec/cases.msg +0 -0
  74. data/spec/cases_compact.msg +0 -0
  75. data/spec/cases_spec.rb +0 -39
  76. data/spec/cruby/buffer_io_spec.rb +0 -255
  77. data/spec/cruby/buffer_packer.rb +0 -29
  78. data/spec/cruby/buffer_spec.rb +0 -575
  79. data/spec/cruby/buffer_unpacker.rb +0 -19
  80. data/spec/cruby/unpacker_spec.rb +0 -70
  81. data/spec/ext_value_spec.rb +0 -99
  82. data/spec/exttypes.rb +0 -51
  83. data/spec/factory_spec.rb +0 -367
  84. data/spec/format_spec.rb +0 -301
  85. data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
  86. data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
  87. data/spec/jruby/unpacker_spec.rb +0 -186
  88. data/spec/msgpack_spec.rb +0 -214
  89. data/spec/pack_spec.rb +0 -61
  90. data/spec/packer_spec.rb +0 -557
  91. data/spec/random_compat.rb +0 -24
  92. data/spec/spec_helper.rb +0 -55
  93. data/spec/timestamp_spec.rb +0 -121
  94. data/spec/unpack_spec.rb +0 -57
  95. data/spec/unpacker_spec.rb +0 -819
@@ -21,12 +21,11 @@
21
21
  #include "buffer.h"
22
22
  #include "unpacker_ext_registry.h"
23
23
 
24
- #ifndef MSGPACK_UNPACKER_STACK_CAPACITY
25
24
  #define MSGPACK_UNPACKER_STACK_CAPACITY 128
26
- #endif
27
25
 
28
26
  struct msgpack_unpacker_t;
29
27
  typedef struct msgpack_unpacker_t msgpack_unpacker_t;
28
+ typedef struct msgpack_unpacker_stack_t msgpack_unpacker_stack_t;
30
29
 
31
30
  enum stack_type_t {
32
31
  STACK_TYPE_ARRAY,
@@ -39,19 +38,21 @@ typedef struct {
39
38
  enum stack_type_t type;
40
39
  VALUE object;
41
40
  VALUE key;
42
- } msgpack_unpacker_stack_t;
41
+ } msgpack_unpacker_stack_entry_t;
43
42
 
44
- #define MSGPACK_UNPACKER_STACK_SIZE (8+4+8+8) /* assumes size_t <= 64bit, enum <= 32bit, VALUE <= 64bit */
43
+ struct msgpack_unpacker_stack_t {
44
+ size_t depth;
45
+ size_t capacity;
46
+ msgpack_unpacker_stack_entry_t *data;
47
+ msgpack_unpacker_stack_t *parent;
48
+ };
45
49
 
46
50
  struct msgpack_unpacker_t {
47
51
  msgpack_buffer_t buffer;
48
-
52
+ msgpack_unpacker_stack_t *stack;
49
53
  unsigned int head_byte;
50
54
 
51
- msgpack_unpacker_stack_t* stack;
52
- size_t stack_depth;
53
- size_t stack_capacity;
54
-
55
+ VALUE self;
55
56
  VALUE last_object;
56
57
 
57
58
  VALUE reading_raw;
@@ -60,12 +61,14 @@ struct msgpack_unpacker_t {
60
61
 
61
62
  VALUE buffer_ref;
62
63
 
63
- msgpack_unpacker_ext_registry_t ext_registry;
64
+ msgpack_unpacker_ext_registry_t *ext_registry;
64
65
 
65
66
  /* options */
66
67
  bool symbolize_keys;
67
68
  bool freeze;
68
69
  bool allow_unknown_ext;
70
+ bool optimized_symbol_ext_type;
71
+ int symbol_ext_type;
69
72
  };
70
73
 
71
74
  #define UNPACKER_BUFFER_(uk) (&(uk)->buffer)
@@ -80,11 +83,11 @@ enum msgpack_unpacker_object_type {
80
83
  TYPE_MAP,
81
84
  };
82
85
 
83
- void msgpack_unpacker_static_init();
86
+ void msgpack_unpacker_static_init(void);
84
87
 
85
- void msgpack_unpacker_static_destroy();
88
+ void msgpack_unpacker_static_destroy(void);
86
89
 
87
- void _msgpack_unpacker_init(msgpack_unpacker_t* uk);
90
+ void _msgpack_unpacker_init(msgpack_unpacker_t*);
88
91
 
89
92
  void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk);
90
93
 
@@ -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
57
  }
58
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);
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
+
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,23 +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("freeze")));
131
+ v = rb_hash_aref(options, sym_freeze);
109
132
  msgpack_unpacker_set_freeze(uk, RTEST(v));
110
133
 
111
- v = rb_hash_aref(options, ID2SYM(rb_intern("allow_unknown_ext")));
134
+ v = rb_hash_aref(options, sym_allow_unknown_ext);
112
135
  msgpack_unpacker_set_allow_unknown_ext(uk, RTEST(v));
113
136
  }
114
137
 
@@ -117,23 +140,23 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
117
140
 
118
141
  static VALUE Unpacker_symbolized_keys_p(VALUE self)
119
142
  {
120
- UNPACKER(self, uk);
143
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
121
144
  return uk->symbolize_keys ? Qtrue : Qfalse;
122
145
  }
123
146
 
124
147
  static VALUE Unpacker_freeze_p(VALUE self)
125
148
  {
126
- UNPACKER(self, uk);
149
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
127
150
  return uk->freeze ? Qtrue : Qfalse;
128
151
  }
129
152
 
130
153
  static VALUE Unpacker_allow_unknown_ext_p(VALUE self)
131
154
  {
132
- UNPACKER(self, uk);
155
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
133
156
  return uk->allow_unknown_ext ? Qtrue : Qfalse;
134
157
  }
135
158
 
136
- static void raise_unpacker_error(int r)
159
+ NORETURN(static void raise_unpacker_error(int r))
137
160
  {
138
161
  switch(r) {
139
162
  case PRIMITIVE_EOF:
@@ -145,6 +168,7 @@ static void raise_unpacker_error(int r)
145
168
  case PRIMITIVE_UNEXPECTED_TYPE:
146
169
  rb_raise(eUnexpectedTypeError, "unexpected type");
147
170
  case PRIMITIVE_UNEXPECTED_EXT_TYPE:
171
+ // rb_bug("unexpected extension type");
148
172
  rb_raise(eUnknownExtTypeError, "unexpected extension type");
149
173
  default:
150
174
  rb_raise(eUnpackError, "logically unknown error %d", r);
@@ -153,13 +177,16 @@ static void raise_unpacker_error(int r)
153
177
 
154
178
  static VALUE Unpacker_buffer(VALUE self)
155
179
  {
156
- 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
+ }
157
184
  return uk->buffer_ref;
158
185
  }
159
186
 
160
187
  static VALUE Unpacker_read(VALUE self)
161
188
  {
162
- UNPACKER(self, uk);
189
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
163
190
 
164
191
  int r = msgpack_unpacker_read(uk, 0);
165
192
  if(r < 0) {
@@ -171,7 +198,7 @@ static VALUE Unpacker_read(VALUE self)
171
198
 
172
199
  static VALUE Unpacker_skip(VALUE self)
173
200
  {
174
- UNPACKER(self, uk);
201
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
175
202
 
176
203
  int r = msgpack_unpacker_skip(uk, 0);
177
204
  if(r < 0) {
@@ -183,7 +210,7 @@ static VALUE Unpacker_skip(VALUE self)
183
210
 
184
211
  static VALUE Unpacker_skip_nil(VALUE self)
185
212
  {
186
- UNPACKER(self, uk);
213
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
187
214
 
188
215
  int r = msgpack_unpacker_skip_nil(uk);
189
216
  if(r < 0) {
@@ -198,7 +225,7 @@ static VALUE Unpacker_skip_nil(VALUE self)
198
225
 
199
226
  static VALUE Unpacker_read_array_header(VALUE self)
200
227
  {
201
- UNPACKER(self, uk);
228
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
202
229
 
203
230
  uint32_t size;
204
231
  int r = msgpack_unpacker_read_array_header(uk, &size);
@@ -206,12 +233,12 @@ static VALUE Unpacker_read_array_header(VALUE self)
206
233
  raise_unpacker_error(r);
207
234
  }
208
235
 
209
- return ULONG2NUM(size);
236
+ return ULONG2NUM(size); // long at least 32 bits
210
237
  }
211
238
 
212
239
  static VALUE Unpacker_read_map_header(VALUE self)
213
240
  {
214
- UNPACKER(self, uk);
241
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
215
242
 
216
243
  uint32_t size;
217
244
  int r = msgpack_unpacker_read_map_header(uk, &size);
@@ -219,52 +246,12 @@ static VALUE Unpacker_read_map_header(VALUE self)
219
246
  raise_unpacker_error((int)r);
220
247
  }
221
248
 
222
- return ULONG2NUM(size);
223
- }
224
-
225
- static VALUE Unpacker_peek_next_type(VALUE self)
226
- {
227
- UNPACKER(self, uk);
228
-
229
- int r = msgpack_unpacker_peek_next_object_type(uk);
230
- if(r < 0) {
231
- raise_unpacker_error(r);
232
- }
233
-
234
- switch((enum msgpack_unpacker_object_type) r) {
235
- case TYPE_NIL:
236
- return rb_intern("nil");
237
- case TYPE_BOOLEAN:
238
- return rb_intern("boolean");
239
- case TYPE_INTEGER:
240
- return rb_intern("integer");
241
- case TYPE_FLOAT:
242
- return rb_intern("float");
243
- case TYPE_RAW:
244
- return rb_intern("raw");
245
- case TYPE_ARRAY:
246
- return rb_intern("array");
247
- case TYPE_MAP:
248
- return rb_intern("map");
249
- default:
250
- rb_raise(eUnpackError, "logically unknown type %d", r);
251
- }
252
- }
253
-
254
- static VALUE Unpacker_feed(VALUE self, VALUE data)
255
- {
256
- UNPACKER(self, uk);
257
-
258
- StringValue(data);
259
-
260
- msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), data);
261
-
262
- return self;
249
+ return ULONG2NUM(size); // long at least 32 bits
263
250
  }
264
251
 
265
252
  static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
266
253
  {
267
- UNPACKER(self, uk);
254
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
268
255
 
269
256
  StringValue(data);
270
257
 
@@ -275,7 +262,7 @@ static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
275
262
 
276
263
  static VALUE Unpacker_each_impl(VALUE self)
277
264
  {
278
- UNPACKER(self, uk);
265
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
279
266
 
280
267
  while(true) {
281
268
  int r = msgpack_unpacker_read(uk, 0);
@@ -296,15 +283,16 @@ static VALUE Unpacker_each_impl(VALUE self)
296
283
  }
297
284
  }
298
285
 
299
- static VALUE Unpacker_rescue_EOFError(VALUE self)
286
+ static VALUE Unpacker_rescue_EOFError(VALUE args, VALUE error)
300
287
  {
301
- UNUSED(self);
288
+ UNUSED(args);
289
+ UNUSED(error);
302
290
  return Qnil;
303
291
  }
304
292
 
305
293
  static VALUE Unpacker_each(VALUE self)
306
294
  {
307
- UNPACKER(self, uk);
295
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
308
296
 
309
297
  #ifdef RETURN_ENUMERATOR
310
298
  RETURN_ENUMERATOR(self, 0, 0);
@@ -335,7 +323,7 @@ static VALUE Unpacker_feed_each(VALUE self, VALUE data)
335
323
 
336
324
  static VALUE Unpacker_reset(VALUE self)
337
325
  {
338
- UNPACKER(self, uk);
326
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
339
327
 
340
328
  _msgpack_unpacker_reset(uk);
341
329
 
@@ -344,63 +332,40 @@ static VALUE Unpacker_reset(VALUE self)
344
332
 
345
333
  static VALUE Unpacker_registered_types_internal(VALUE self)
346
334
  {
347
- UNPACKER(self, uk);
335
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
348
336
 
349
337
  VALUE mapping = rb_hash_new();
350
- for(int i=0; i < 256; i++) {
351
- if(uk->ext_registry.array[i] != Qnil) {
352
- 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
+ }
353
343
  }
354
344
  }
355
345
 
356
346
  return mapping;
357
347
  }
358
348
 
359
- 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)
360
350
  {
361
- UNPACKER(self, uk);
362
-
363
- int ext_type;
364
- VALUE proc;
365
- VALUE arg;
366
- VALUE ext_module;
367
-
368
- switch (argc) {
369
- case 1:
370
- /* register_type(0x7f) {|data| block... } */
371
- rb_need_block();
372
- #ifdef HAVE_RB_BLOCK_LAMBDA
373
- proc = rb_block_lambda();
374
- #else
375
- /* MRI 1.8 */
376
- proc = rb_block_proc();
377
- #endif
378
- arg = proc;
379
- ext_module = Qnil;
380
- break;
381
- case 3:
382
- /* register_type(0x7f, Time, :from_msgpack_ext) */
383
- ext_module = argv[1];
384
- arg = argv[2];
385
- proc = rb_obj_method(ext_module, arg);
386
- break;
387
- default:
388
- 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");
389
353
  }
390
354
 
391
- ext_type = NUM2INT(argv[0]);
355
+ int ext_type = NUM2INT(rb_ext_type);
392
356
  if(ext_type < -128 || ext_type > 127) {
393
357
  rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
394
358
  }
395
359
 
396
- 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);
397
362
 
398
363
  return Qnil;
399
364
  }
400
365
 
401
366
  static VALUE Unpacker_full_unpack(VALUE self)
402
367
  {
403
- UNPACKER(self, uk);
368
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
404
369
 
405
370
  int r = msgpack_unpacker_read(uk, 0);
406
371
  if(r < 0) {
@@ -426,7 +391,6 @@ VALUE MessagePack_Unpacker_new(int argc, VALUE* argv)
426
391
  void MessagePack_Unpacker_module_init(VALUE mMessagePack)
427
392
  {
428
393
  msgpack_unpacker_static_init();
429
- msgpack_unpacker_ext_registry_static_init();
430
394
 
431
395
  mTypeError = rb_define_module_under(mMessagePack, "TypeError");
432
396
 
@@ -443,6 +407,10 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
443
407
 
444
408
  eUnknownExtTypeError = rb_define_class_under(mMessagePack, "UnknownExtTypeError", eUnpackError);
445
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
+
446
414
  rb_define_alloc_func(cMessagePack_Unpacker, MessagePack_Unpacker_alloc);
447
415
 
448
416
  rb_define_method(cMessagePack_Unpacker, "initialize", MessagePack_Unpacker_initialize, -1);
@@ -456,22 +424,14 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
456
424
  rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
457
425
  rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
458
426
  rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
459
- //rb_define_method(cMessagePack_Unpacker, "peek_next_type", Unpacker_peek_next_type, 0); // TODO
460
- rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed, 1);
461
- 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");
462
429
  rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
463
430
  rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1);
464
431
  rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
465
432
 
466
433
  rb_define_private_method(cMessagePack_Unpacker, "registered_types_internal", Unpacker_registered_types_internal, 0);
467
- rb_define_method(cMessagePack_Unpacker, "register_type", Unpacker_register_type, -1);
468
-
469
- //s_unpacker_value = MessagePack_Unpacker_alloc(cMessagePack_Unpacker);
470
- //rb_gc_register_address(&s_unpacker_value);
471
- //Data_Get_Struct(s_unpacker_value, msgpack_unpacker_t, s_unpacker);
472
- /* prefer reference than copying */
473
- //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);
474
435
 
475
436
  rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
476
437
  }
477
-
@@ -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