msgpack 1.4.2 → 1.7.3

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 +89 -0
  3. data/README.md +73 -13
  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 +136 -111
  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
@@ -28,18 +28,14 @@ VALUE cMessagePack_Packer;
28
28
  static ID s_to_msgpack;
29
29
  static ID s_write;
30
30
 
31
+ static VALUE sym_compatibility_mode;
32
+
31
33
  //static VALUE s_packer_value;
32
34
  //static msgpack_packer_t* s_packer;
33
35
 
34
- #define PACKER(from, name) \
35
- msgpack_packer_t* name; \
36
- Data_Get_Struct(from, msgpack_packer_t, name); \
37
- if(name == NULL) { \
38
- rb_raise(rb_eArgError, "NULL found for " # name " when shouldn't be."); \
39
- }
40
-
41
- static void Packer_free(msgpack_packer_t* pk)
36
+ static void Packer_free(void *ptr)
42
37
  {
38
+ msgpack_packer_t* pk = ptr;
43
39
  if(pk == NULL) {
44
40
  return;
45
41
  }
@@ -48,54 +44,69 @@ static void Packer_free(msgpack_packer_t* pk)
48
44
  xfree(pk);
49
45
  }
50
46
 
51
- static void Packer_mark(msgpack_packer_t* pk)
47
+ static void Packer_mark(void *ptr)
52
48
  {
49
+ msgpack_packer_t* pk = ptr;
50
+ msgpack_buffer_mark(pk);
53
51
  msgpack_packer_mark(pk);
54
52
  msgpack_packer_ext_registry_mark(&pk->ext_registry);
55
53
  }
56
54
 
57
- VALUE MessagePack_Packer_alloc(VALUE klass)
55
+ static size_t Packer_memsize(const void *ptr)
58
56
  {
59
- msgpack_packer_t* pk = ZALLOC_N(msgpack_packer_t, 1);
60
- msgpack_packer_init(pk);
57
+ const msgpack_packer_t* pk = ptr;
58
+ return sizeof(msgpack_packer_t) + msgpack_buffer_memsize(&pk->buffer);
59
+ }
61
60
 
62
- VALUE self = Data_Wrap_Struct(klass, Packer_mark, Packer_free, pk);
61
+ const rb_data_type_t packer_data_type = {
62
+ .wrap_struct_name = "msgpack:packer",
63
+ .function = {
64
+ .dmark = Packer_mark,
65
+ .dfree = Packer_free,
66
+ .dsize = Packer_memsize,
67
+ },
68
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
69
+ };
63
70
 
64
- msgpack_packer_set_to_msgpack_method(pk, s_to_msgpack, self);
65
71
 
72
+ VALUE MessagePack_Packer_alloc(VALUE klass)
73
+ {
74
+ msgpack_packer_t* pk;
75
+ VALUE self = TypedData_Make_Struct(klass, msgpack_packer_t, &packer_data_type, pk);
76
+ msgpack_packer_init(pk);
77
+ msgpack_packer_set_to_msgpack_method(pk, s_to_msgpack, self);
66
78
  return self;
67
79
  }
68
80
 
69
81
  VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
70
82
  {
83
+ if(argc > 2) {
84
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
85
+ }
86
+
71
87
  VALUE io = Qnil;
72
88
  VALUE options = Qnil;
73
89
 
74
- if(argc == 0 || (argc == 1 && argv[0] == Qnil)) {
75
- /* Qnil */
76
-
77
- } else if(argc == 1) {
78
- VALUE v = argv[0];
79
- if(rb_type(v) == T_HASH) {
80
- options = v;
81
- } else {
82
- io = v;
83
- }
84
-
85
- } else if(argc == 2) {
90
+ if(argc >= 1) {
86
91
  io = argv[0];
92
+ }
93
+
94
+ if(argc == 2) {
87
95
  options = argv[1];
88
- if(rb_type(options) != T_HASH) {
89
- rb_raise(rb_eArgError, "expected Hash but found %s.", rb_obj_classname(options));
90
- }
96
+ }
91
97
 
92
- } else {
93
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
98
+ if (options == Qnil && rb_type(io) == T_HASH) {
99
+ options = io;
100
+ io = Qnil;
101
+ }
102
+
103
+ if(options != Qnil) {
104
+ Check_Type(options, T_HASH);
94
105
  }
95
106
 
96
- PACKER(self, pk);
107
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
97
108
 
98
- msgpack_packer_ext_registry_init(&pk->ext_registry);
109
+ msgpack_packer_ext_registry_init(self, &pk->ext_registry);
99
110
  pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self);
100
111
 
101
112
  MessagePack_Buffer_set_options(PACKER_BUFFER_(pk), io, options);
@@ -103,7 +114,7 @@ VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
103
114
  if(options != Qnil) {
104
115
  VALUE v;
105
116
 
106
- v = rb_hash_aref(options, ID2SYM(rb_intern("compatibility_mode")));
117
+ v = rb_hash_aref(options, sym_compatibility_mode);
107
118
  msgpack_packer_set_compat(pk, RTEST(v));
108
119
  }
109
120
 
@@ -112,54 +123,57 @@ VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
112
123
 
113
124
  static VALUE Packer_compatibility_mode_p(VALUE self)
114
125
  {
115
- PACKER(self, pk);
126
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
116
127
  return pk->compatibility_mode ? Qtrue : Qfalse;
117
128
  }
118
129
 
119
130
  static VALUE Packer_buffer(VALUE self)
120
131
  {
121
- PACKER(self, pk);
132
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
133
+ if (!RTEST(pk->buffer_ref)) {
134
+ pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self);
135
+ }
122
136
  return pk->buffer_ref;
123
137
  }
124
138
 
125
139
  static VALUE Packer_write(VALUE self, VALUE v)
126
140
  {
127
- PACKER(self, pk);
141
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
128
142
  msgpack_packer_write_value(pk, v);
129
143
  return self;
130
144
  }
131
145
 
132
146
  static VALUE Packer_write_nil(VALUE self)
133
147
  {
134
- PACKER(self, pk);
148
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
135
149
  msgpack_packer_write_nil(pk);
136
150
  return self;
137
151
  }
138
152
 
139
153
  static VALUE Packer_write_true(VALUE self)
140
154
  {
141
- PACKER(self, pk);
155
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
142
156
  msgpack_packer_write_true(pk);
143
157
  return self;
144
158
  }
145
159
 
146
160
  static VALUE Packer_write_false(VALUE self)
147
161
  {
148
- PACKER(self, pk);
162
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
149
163
  msgpack_packer_write_false(pk);
150
164
  return self;
151
165
  }
152
166
 
153
167
  static VALUE Packer_write_float(VALUE self, VALUE obj)
154
168
  {
155
- PACKER(self, pk);
169
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
156
170
  msgpack_packer_write_float_value(pk, obj);
157
171
  return self;
158
172
  }
159
173
 
160
174
  static VALUE Packer_write_string(VALUE self, VALUE obj)
161
175
  {
162
- PACKER(self, pk);
176
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
163
177
  Check_Type(obj, T_STRING);
164
178
  msgpack_packer_write_string_value(pk, obj);
165
179
  return self;
@@ -167,7 +181,7 @@ static VALUE Packer_write_string(VALUE self, VALUE obj)
167
181
 
168
182
  static VALUE Packer_write_bin(VALUE self, VALUE obj)
169
183
  {
170
- PACKER(self, pk);
184
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
171
185
  Check_Type(obj, T_STRING);
172
186
 
173
187
  VALUE enc = rb_enc_from_encoding(rb_ascii8bit_encoding());
@@ -179,7 +193,7 @@ static VALUE Packer_write_bin(VALUE self, VALUE obj)
179
193
 
180
194
  static VALUE Packer_write_array(VALUE self, VALUE obj)
181
195
  {
182
- PACKER(self, pk);
196
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
183
197
  Check_Type(obj, T_ARRAY);
184
198
  msgpack_packer_write_array_value(pk, obj);
185
199
  return self;
@@ -187,7 +201,7 @@ static VALUE Packer_write_array(VALUE self, VALUE obj)
187
201
 
188
202
  static VALUE Packer_write_hash(VALUE self, VALUE obj)
189
203
  {
190
- PACKER(self, pk);
204
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
191
205
  Check_Type(obj, T_HASH);
192
206
  msgpack_packer_write_hash_value(pk, obj);
193
207
  return self;
@@ -195,7 +209,7 @@ static VALUE Packer_write_hash(VALUE self, VALUE obj)
195
209
 
196
210
  static VALUE Packer_write_symbol(VALUE self, VALUE obj)
197
211
  {
198
- PACKER(self, pk);
212
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
199
213
  Check_Type(obj, T_SYMBOL);
200
214
  msgpack_packer_write_symbol_value(pk, obj);
201
215
  return self;
@@ -203,7 +217,7 @@ static VALUE Packer_write_symbol(VALUE self, VALUE obj)
203
217
 
204
218
  static VALUE Packer_write_int(VALUE self, VALUE obj)
205
219
  {
206
- PACKER(self, pk);
220
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
207
221
 
208
222
  if (FIXNUM_P(obj)) {
209
223
  msgpack_packer_write_fixnum_value(pk, obj);
@@ -216,10 +230,15 @@ static VALUE Packer_write_int(VALUE self, VALUE obj)
216
230
 
217
231
  static VALUE Packer_write_extension(VALUE self, VALUE obj)
218
232
  {
219
- PACKER(self, pk);
233
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
220
234
  Check_Type(obj, T_STRUCT);
221
235
 
222
- int ext_type = FIX2INT(RSTRUCT_GET(obj, 0));
236
+ VALUE rb_ext_type = RSTRUCT_GET(obj, 0);
237
+ if(!RB_TYPE_P(rb_ext_type, T_FIXNUM)) {
238
+ rb_raise(rb_eRangeError, "integer %s too big to convert to `signed char'", RSTRING_PTR(rb_String(rb_ext_type)));
239
+ }
240
+
241
+ int ext_type = FIX2INT(rb_ext_type);
223
242
  if(ext_type < -128 || ext_type > 127) {
224
243
  rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
225
244
  }
@@ -232,21 +251,21 @@ static VALUE Packer_write_extension(VALUE self, VALUE obj)
232
251
 
233
252
  static VALUE Packer_write_array_header(VALUE self, VALUE n)
234
253
  {
235
- PACKER(self, pk);
254
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
236
255
  msgpack_packer_write_array_header(pk, NUM2UINT(n));
237
256
  return self;
238
257
  }
239
258
 
240
259
  static VALUE Packer_write_map_header(VALUE self, VALUE n)
241
260
  {
242
- PACKER(self, pk);
261
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
243
262
  msgpack_packer_write_map_header(pk, NUM2UINT(n));
244
263
  return self;
245
264
  }
246
265
 
247
266
  static VALUE Packer_write_bin_header(VALUE self, VALUE n)
248
267
  {
249
- PACKER(self, pk);
268
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
250
269
  msgpack_packer_write_bin_header(pk, NUM2UINT(n));
251
270
  return self;
252
271
  }
@@ -257,14 +276,14 @@ static VALUE Packer_write_float32(VALUE self, VALUE numeric)
257
276
  rb_raise(rb_eArgError, "Expected numeric");
258
277
  }
259
278
 
260
- PACKER(self, pk);
279
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
261
280
  msgpack_packer_write_float(pk, (float)rb_num2dbl(numeric));
262
281
  return self;
263
282
  }
264
283
 
265
284
  static VALUE Packer_write_ext(VALUE self, VALUE type, VALUE data)
266
285
  {
267
- PACKER(self, pk);
286
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
268
287
  int ext_type = NUM2INT(type);
269
288
  if(ext_type < -128 || ext_type > 127) {
270
289
  rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
@@ -276,28 +295,28 @@ static VALUE Packer_write_ext(VALUE self, VALUE type, VALUE data)
276
295
 
277
296
  static VALUE Packer_flush(VALUE self)
278
297
  {
279
- PACKER(self, pk);
298
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
280
299
  msgpack_buffer_flush(PACKER_BUFFER_(pk));
281
300
  return self;
282
301
  }
283
302
 
284
- static VALUE Packer_clear(VALUE self)
303
+ static VALUE Packer_reset(VALUE self)
285
304
  {
286
- PACKER(self, pk);
305
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
287
306
  msgpack_buffer_clear(PACKER_BUFFER_(pk));
288
307
  return Qnil;
289
308
  }
290
309
 
291
310
  static VALUE Packer_size(VALUE self)
292
311
  {
293
- PACKER(self, pk);
312
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
294
313
  size_t size = msgpack_buffer_all_readable_size(PACKER_BUFFER_(pk));
295
314
  return SIZET2NUM(size);
296
315
  }
297
316
 
298
317
  static VALUE Packer_empty_p(VALUE self)
299
318
  {
300
- PACKER(self, pk);
319
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
301
320
  if(msgpack_buffer_top_readable_size(PACKER_BUFFER_(pk)) == 0) {
302
321
  return Qtrue;
303
322
  } else {
@@ -307,86 +326,46 @@ static VALUE Packer_empty_p(VALUE self)
307
326
 
308
327
  static VALUE Packer_to_str(VALUE self)
309
328
  {
310
- PACKER(self, pk);
329
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
311
330
  return msgpack_buffer_all_as_string(PACKER_BUFFER_(pk));
312
331
  }
313
332
 
314
333
  static VALUE Packer_to_a(VALUE self)
315
334
  {
316
- PACKER(self, pk);
335
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
317
336
  return msgpack_buffer_all_as_string_array(PACKER_BUFFER_(pk));
318
337
  }
319
338
 
320
339
  static VALUE Packer_write_to(VALUE self, VALUE io)
321
340
  {
322
- PACKER(self, pk);
341
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
323
342
  size_t sz = msgpack_buffer_flush_to_io(PACKER_BUFFER_(pk), io, s_write, true);
324
- return ULONG2NUM(sz);
343
+ return SIZET2NUM(sz);
325
344
  }
326
345
 
327
- //static VALUE Packer_append(VALUE self, VALUE string_or_buffer)
328
- //{
329
- // PACKER(self, pk);
330
- //
331
- // // TODO if string_or_buffer is a Buffer
332
- // VALUE string = string_or_buffer;
333
- //
334
- // msgpack_buffer_append_string(PACKER_BUFFER_(pk), string);
335
- //
336
- // return self;
337
- //}
338
-
339
346
  static VALUE Packer_registered_types_internal(VALUE self)
340
347
  {
341
- PACKER(self, pk);
342
- #ifdef HAVE_RB_HASH_DUP
343
- return rb_hash_dup(pk->ext_registry.hash);
344
- #else
345
- return rb_funcall(pk->ext_registry.hash, rb_intern("dup"), 0);
346
- #endif
347
- }
348
-
349
- static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
350
- {
351
- PACKER(self, pk);
352
-
353
- int ext_type;
354
- VALUE ext_module;
355
- VALUE proc;
356
- VALUE arg;
357
-
358
- switch (argc) {
359
- case 2:
360
- /* register_type(0x7f, Time) {|obj| block... } */
361
- rb_need_block();
362
- #ifdef HAVE_RB_BLOCK_LAMBDA
363
- proc = rb_block_lambda();
364
- #else
365
- /* MRI 1.8 */
366
- proc = rb_block_proc();
367
- #endif
368
- arg = proc;
369
- break;
370
- case 3:
371
- /* register_type(0x7f, Time, :to_msgpack_ext) */
372
- arg = argv[2];
373
- proc = rb_funcall(arg, rb_intern("to_proc"), 0);
374
- break;
375
- default:
376
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 2..3)", argc);
348
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
349
+ if (RTEST(pk->ext_registry.hash)) {
350
+ return rb_hash_dup(pk->ext_registry.hash);
377
351
  }
352
+ return rb_hash_new();
353
+ }
378
354
 
379
- ext_type = NUM2INT(argv[0]);
380
- if(ext_type < -128 || ext_type > 127) {
381
- rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
355
+ static VALUE Packer_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
356
+ {
357
+ if (OBJ_FROZEN(self)) {
358
+ rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Packer");
382
359
  }
383
360
 
384
- ext_module = argv[1];
385
- if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
386
- rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
361
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
362
+
363
+ int ext_type = NUM2INT(rb_ext_type);
364
+ if(ext_type < -128 || ext_type > 127) {
365
+ rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
387
366
  }
388
367
 
389
- msgpack_packer_ext_registry_put(&pk->ext_registry, ext_module, ext_type, proc, arg);
368
+ msgpack_packer_ext_registry_put(self, &pk->ext_registry, ext_module, ext_type, 0, proc);
390
369
 
391
370
  if (ext_module == rb_cSymbol) {
392
371
  pk->has_symbol_ext_type = true;
@@ -399,7 +378,7 @@ VALUE Packer_full_pack(VALUE self)
399
378
  {
400
379
  VALUE retval;
401
380
 
402
- PACKER(self, pk);
381
+ msgpack_packer_t *pk = MessagePack_Packer_get(self);
403
382
 
404
383
  if(msgpack_buffer_has_io(PACKER_BUFFER_(pk))) {
405
384
  msgpack_buffer_flush(PACKER_BUFFER_(pk));
@@ -418,9 +397,7 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
418
397
  s_to_msgpack = rb_intern("to_msgpack");
419
398
  s_write = rb_intern("write");
420
399
 
421
- msgpack_packer_static_init();
422
- msgpack_packer_ext_registry_static_init();
423
-
400
+ sym_compatibility_mode = ID2SYM(rb_intern("compatibility_mode"));
424
401
  cMessagePack_Packer = rb_define_class_under(mMessagePack, "Packer", rb_cObject);
425
402
 
426
403
  rb_define_alloc_func(cMessagePack_Packer, MessagePack_Packer_alloc);
@@ -449,22 +426,17 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
449
426
  rb_define_method(cMessagePack_Packer, "flush", Packer_flush, 0);
450
427
 
451
428
  /* delegation methods */
452
- rb_define_method(cMessagePack_Packer, "clear", Packer_clear, 0);
429
+ rb_define_method(cMessagePack_Packer, "reset", Packer_reset, 0);
430
+ rb_define_alias(cMessagePack_Packer, "clear", "reset");
453
431
  rb_define_method(cMessagePack_Packer, "size", Packer_size, 0);
454
432
  rb_define_method(cMessagePack_Packer, "empty?", Packer_empty_p, 0);
455
433
  rb_define_method(cMessagePack_Packer, "write_to", Packer_write_to, 1);
456
434
  rb_define_method(cMessagePack_Packer, "to_str", Packer_to_str, 0);
457
435
  rb_define_alias(cMessagePack_Packer, "to_s", "to_str");
458
436
  rb_define_method(cMessagePack_Packer, "to_a", Packer_to_a, 0);
459
- //rb_define_method(cMessagePack_Packer, "append", Packer_append, 1);
460
- //rb_define_alias(cMessagePack_Packer, "<<", "append");
461
437
 
462
438
  rb_define_private_method(cMessagePack_Packer, "registered_types_internal", Packer_registered_types_internal, 0);
463
- rb_define_method(cMessagePack_Packer, "register_type", Packer_register_type, -1);
464
-
465
- //s_packer_value = MessagePack_Packer_alloc(cMessagePack_Packer);
466
- //rb_gc_register_address(&s_packer_value);
467
- //Data_Get_Struct(s_packer_value, msgpack_packer_t, s_packer);
439
+ rb_define_method(cMessagePack_Packer, "register_type_internal", Packer_register_type_internal, 3);
468
440
 
469
441
  rb_define_method(cMessagePack_Packer, "full_pack", Packer_full_pack, 0);
470
442
  }
@@ -22,6 +22,17 @@
22
22
 
23
23
  extern VALUE cMessagePack_Packer;
24
24
 
25
+ extern const rb_data_type_t packer_data_type;
26
+
27
+ static inline msgpack_packer_t *MessagePack_Packer_get(VALUE object) {
28
+ msgpack_packer_t *packer;
29
+ TypedData_Get_Struct(object, msgpack_packer_t, &packer_data_type, packer);
30
+ if (!packer) {
31
+ rb_raise(rb_eArgError, "Uninitialized Packer object");
32
+ }
33
+ return packer;
34
+ }
35
+
25
36
  void MessagePack_Packer_module_init(VALUE mMessagePack);
26
37
 
27
38
  VALUE MessagePack_Packer_alloc(VALUE klass);
@@ -18,20 +18,10 @@
18
18
 
19
19
  #include "packer_ext_registry.h"
20
20
 
21
- static ID s_call;
22
-
23
- void msgpack_packer_ext_registry_static_init()
24
- {
25
- s_call = rb_intern("call");
26
- }
27
-
28
- void msgpack_packer_ext_registry_static_destroy()
29
- { }
30
-
31
- void msgpack_packer_ext_registry_init(msgpack_packer_ext_registry_t* pkrg)
21
+ void msgpack_packer_ext_registry_init(VALUE owner, msgpack_packer_ext_registry_t* pkrg)
32
22
  {
33
- pkrg->hash = rb_hash_new();
34
- pkrg->cache = rb_hash_new();
23
+ RB_OBJ_WRITE(owner, &pkrg->hash, Qnil);
24
+ RB_OBJ_WRITE(owner, &pkrg->cache, Qnil);
35
25
  }
36
26
 
37
27
  void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
@@ -40,40 +30,45 @@ void msgpack_packer_ext_registry_mark(msgpack_packer_ext_registry_t* pkrg)
40
30
  rb_gc_mark(pkrg->cache);
41
31
  }
42
32
 
43
- void msgpack_packer_ext_registry_dup(msgpack_packer_ext_registry_t* src,
33
+ void msgpack_packer_ext_registry_borrow(VALUE owner, msgpack_packer_ext_registry_t* src,
44
34
  msgpack_packer_ext_registry_t* dst)
45
35
  {
46
- #ifdef HAVE_RB_HASH_DUP
47
- dst->hash = rb_hash_dup(src->hash);
48
- dst->cache = rb_hash_dup(src->cache);
49
- #else
50
- dst->hash = rb_funcall(src->hash, rb_intern("dup"), 0);
51
- dst->cache = rb_funcall(src->cache, rb_intern("dup"), 0);
52
- #endif
36
+ if(RTEST(src->hash)) {
37
+ if(rb_obj_frozen_p(src->hash)) {
38
+ // If the type registry is frozen we can safely share it, and share the cache as well.
39
+ RB_OBJ_WRITE(owner, &dst->hash, src->hash);
40
+ RB_OBJ_WRITE(owner, &dst->cache, src->cache);
41
+ } else {
42
+ RB_OBJ_WRITE(owner, &dst->hash, rb_hash_dup(src->hash));
43
+ RB_OBJ_WRITE(owner, &dst->cache, NIL_P(src->cache) ? Qnil : rb_hash_dup(src->cache));
44
+ }
45
+ } else {
46
+ RB_OBJ_WRITE(owner, &dst->hash, Qnil);
47
+ RB_OBJ_WRITE(owner, &dst->cache, Qnil);
48
+ }
53
49
  }
54
50
 
55
- #ifndef HAVE_RB_HASH_CLEAR
56
-
57
- static int
58
- __rb_hash_clear_clear_i(key, value, dummy)
59
- VALUE key, value, dummy;
51
+ void msgpack_packer_ext_registry_dup(VALUE owner, msgpack_packer_ext_registry_t* src,
52
+ msgpack_packer_ext_registry_t* dst)
60
53
  {
61
- return ST_DELETE;
54
+ RB_OBJ_WRITE(owner, &dst->hash, NIL_P(src->hash) ? Qnil : rb_hash_dup(src->hash));
55
+ RB_OBJ_WRITE(owner, &dst->cache, NIL_P(src->cache) ? Qnil : rb_hash_dup(src->cache));
62
56
  }
63
57
 
64
- #endif
65
-
66
- VALUE msgpack_packer_ext_registry_put(msgpack_packer_ext_registry_t* pkrg,
67
- VALUE ext_module, int ext_type, VALUE proc, VALUE arg)
58
+ void msgpack_packer_ext_registry_put(VALUE owner, msgpack_packer_ext_registry_t* pkrg,
59
+ VALUE ext_module, int ext_type, int flags, VALUE proc)
68
60
  {
69
- VALUE e = rb_ary_new3(3, INT2FIX(ext_type), proc, arg);
70
- /* clear lookup cache not to miss added type */
71
- #ifdef HAVE_RB_HASH_CLEAR
72
- rb_hash_clear(pkrg->cache);
73
- #else
74
- if(FIX2INT(rb_funcall(pkrg->cache, rb_intern("size"), 0)) > 0) {
75
- rb_hash_foreach(pkrg->cache, __rb_hash_clear_clear_i, 0);
61
+ if(NIL_P(pkrg->hash)) {
62
+ RB_OBJ_WRITE(owner, &pkrg->hash, rb_hash_new());
76
63
  }
77
- #endif
78
- return rb_hash_aset(pkrg->hash, ext_module, e);
64
+
65
+ if(NIL_P(pkrg->cache)) {
66
+ RB_OBJ_WRITE(owner, &pkrg->cache, rb_hash_new());
67
+ } else {
68
+ /* clear lookup cache not to miss added type */
69
+ rb_hash_clear(pkrg->cache);
70
+ }
71
+
72
+ VALUE entry = rb_ary_new3(3, INT2FIX(ext_type), proc, INT2FIX(flags));
73
+ rb_hash_aset(pkrg->hash, ext_module, entry);
79
74
  }