msgpack 1.4.2 → 1.7.3

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 (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
  }