msgpack 1.5.4 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,7 +20,7 @@
20
20
  #include "rmem.h"
21
21
  #include "extension_value_class.h"
22
22
 
23
- #if !defined(DISABLE_RMEM) && !defined(DISABLE_UNPACKER_STACK_RMEM) && \
23
+ #if !defined(DISABLE_UNPACKER_STACK_RMEM) && \
24
24
  MSGPACK_UNPACKER_STACK_CAPACITY * MSGPACK_UNPACKER_STACK_SIZE <= MSGPACK_RMEM_PAGE_SIZE
25
25
  #define UNPACKER_STACK_RMEM
26
26
  #endif
@@ -41,7 +41,7 @@ static inline VALUE rb_hash_new_capa(long capa)
41
41
  }
42
42
  #endif
43
43
 
44
- void msgpack_unpacker_static_init()
44
+ void msgpack_unpacker_static_init(void)
45
45
  {
46
46
  #ifdef UNPACKER_STACK_RMEM
47
47
  msgpack_rmem_init(&s_stack_rmem);
@@ -50,7 +50,7 @@ void msgpack_unpacker_static_init()
50
50
  s_call = rb_intern("call");
51
51
  }
52
52
 
53
- void msgpack_unpacker_static_destroy()
53
+ void msgpack_unpacker_static_destroy(void)
54
54
  {
55
55
  #ifdef UNPACKER_STACK_RMEM
56
56
  msgpack_rmem_destroy(&s_stack_rmem);
@@ -60,19 +60,20 @@ void msgpack_unpacker_static_destroy()
60
60
  #define HEAD_BYTE_REQUIRED 0xc1
61
61
 
62
62
  static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
63
+ msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
64
+ stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
63
65
  #ifdef UNPACKER_STACK_RMEM
64
- return msgpack_rmem_alloc(&s_stack_rmem);
66
+ stack->data = msgpack_rmem_alloc(&s_stack_rmem);
65
67
  /*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
66
68
  #else
67
- /*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_t));*/
68
- return xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_t));
69
+ /*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_entry_t));*/
70
+ stack->data = xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_entry_t));
69
71
  #endif
72
+ return stack;
70
73
  }
71
74
 
72
- msgpack_unpacker_t* _msgpack_unpacker_new(void)
75
+ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
73
76
  {
74
- msgpack_unpacker_t* uk = ZALLOC_N(msgpack_unpacker_t, 1);
75
-
76
77
  msgpack_buffer_init(UNPACKER_BUFFER_(uk));
77
78
 
78
79
  uk->head_byte = HEAD_BYTE_REQUIRED;
@@ -81,17 +82,15 @@ msgpack_unpacker_t* _msgpack_unpacker_new(void)
81
82
  uk->reading_raw = Qnil;
82
83
 
83
84
  uk->stack = _msgpack_unpacker_new_stack();
84
- uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
85
-
86
- return uk;
87
85
  }
88
86
 
89
87
  static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
90
88
  #ifdef UNPACKER_STACK_RMEM
91
- msgpack_rmem_free(&s_stack_rmem, stack);
89
+ msgpack_rmem_free(&s_stack_rmem, stack->data);
92
90
  #else
93
- xfree(stack);
91
+ xfree(stack->data);
94
92
  #endif
93
+ xfree(stack);
95
94
  }
96
95
 
97
96
  void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
@@ -100,18 +99,24 @@ void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
100
99
  msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
101
100
  }
102
101
 
102
+ void msgpack_unpacker_mark_stack(msgpack_unpacker_stack_t* stack)
103
+ {
104
+ while (stack) {
105
+ msgpack_unpacker_stack_entry_t* s = stack->data;
106
+ msgpack_unpacker_stack_entry_t* send = stack->data + stack->depth;
107
+ for(; s < send; s++) {
108
+ rb_gc_mark(s->object);
109
+ rb_gc_mark(s->key);
110
+ }
111
+ stack = stack->parent;
112
+ }
113
+ }
114
+
103
115
  void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
104
116
  {
105
117
  rb_gc_mark(uk->last_object);
106
118
  rb_gc_mark(uk->reading_raw);
107
-
108
- msgpack_unpacker_stack_t* s = uk->stack;
109
- msgpack_unpacker_stack_t* send = uk->stack + uk->stack_depth;
110
- for(; s < send; s++) {
111
- rb_gc_mark(s->object);
112
- rb_gc_mark(s->key);
113
- }
114
-
119
+ msgpack_unpacker_mark_stack(uk->stack);
115
120
  /* See MessagePack_Buffer_wrap */
116
121
  /* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
117
122
  rb_gc_mark(uk->buffer_ref);
@@ -123,9 +128,8 @@ void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
123
128
 
124
129
  uk->head_byte = HEAD_BYTE_REQUIRED;
125
130
 
126
- /*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack_depth);*/
127
- uk->stack_depth = 0;
128
-
131
+ /*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack->depth);*/
132
+ uk->stack->depth = 0;
129
133
  uk->last_object = Qnil;
130
134
  uk->reading_raw = Qnil;
131
135
  uk->reading_raw_remaining = 0;
@@ -201,37 +205,37 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
201
205
  }
202
206
 
203
207
  /* stack funcs */
204
- static inline msgpack_unpacker_stack_t* _msgpack_unpacker_stack_top(msgpack_unpacker_t* uk)
208
+ static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
205
209
  {
206
- return &uk->stack[uk->stack_depth-1];
210
+ return &uk->stack->data[uk->stack->depth-1];
207
211
  }
208
212
 
209
213
  static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
210
214
  {
211
215
  reset_head_byte(uk);
212
216
 
213
- if(uk->stack_capacity - uk->stack_depth <= 0) {
217
+ if(uk->stack->capacity - uk->stack->depth <= 0) {
214
218
  return PRIMITIVE_STACK_TOO_DEEP;
215
219
  }
216
220
 
217
- msgpack_unpacker_stack_t* next = &uk->stack[uk->stack_depth];
221
+ msgpack_unpacker_stack_entry_t* next = &uk->stack->data[uk->stack->depth];
218
222
  next->count = count;
219
223
  next->type = type;
220
224
  next->object = object;
221
225
  next->key = Qnil;
222
226
 
223
- uk->stack_depth++;
227
+ uk->stack->depth++;
224
228
  return PRIMITIVE_CONTAINER_START;
225
229
  }
226
230
 
227
231
  static inline VALUE msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
228
232
  {
229
- return --uk->stack_depth;
233
+ return --uk->stack->depth;
230
234
  }
231
235
 
232
236
  static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
233
237
  {
234
- return uk->stack_depth == 0;
238
+ return uk->stack->depth == 0;
235
239
  }
236
240
 
237
241
  #ifdef USE_CASE_RANGE
@@ -259,8 +263,8 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
259
263
 
260
264
  static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
261
265
  {
262
- if(uk->stack_depth > 0) {
263
- msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk);
266
+ if(uk->stack->depth > 0) {
267
+ msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
264
268
  if(top->type == STACK_TYPE_MAP_KEY) {
265
269
  return true;
266
270
  }
@@ -314,20 +318,14 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
314
318
  reset_head_byte(uk);
315
319
  uk->reading_raw_remaining = 0;
316
320
 
317
- msgpack_unpacker_stack_t* stack = uk->stack;
318
- size_t stack_depth = uk->stack_depth;
319
- size_t stack_capacity = uk->stack_capacity;
320
-
321
- uk->stack = _msgpack_unpacker_new_stack();
322
- uk->stack_depth = 0;
323
- uk->stack_capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
321
+ msgpack_unpacker_stack_t* child_stack = _msgpack_unpacker_new_stack();
322
+ child_stack->parent = uk->stack;
323
+ uk->stack = child_stack;
324
324
 
325
- obj = rb_funcall(proc, s_call, 1, uk->buffer.owner);
325
+ obj = rb_funcall(proc, s_call, 1, uk->self);
326
326
 
327
- _msgpack_unpacker_free_stack(uk->stack);
328
- uk->stack = stack;
329
- uk->stack_depth = stack_depth;
330
- uk->stack_capacity = stack_capacity;
327
+ uk->stack = child_stack->parent;
328
+ _msgpack_unpacker_free_stack(child_stack);
331
329
 
332
330
  return object_complete(uk, obj);
333
331
  }
@@ -737,7 +735,7 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
737
735
 
738
736
  container_completed:
739
737
  {
740
- msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk);
738
+ msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
741
739
  switch(top->type) {
742
740
  case STACK_TYPE_ARRAY:
743
741
  rb_ary_push(top->object, uk->last_object);
@@ -787,7 +785,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
787
785
 
788
786
  container_completed:
789
787
  {
790
- msgpack_unpacker_stack_t* top = _msgpack_unpacker_stack_top(uk);
788
+ msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
791
789
 
792
790
  /* this section optimized out */
793
791
  // TODO object_complete still creates objects which should be optimized out
@@ -27,6 +27,7 @@
27
27
 
28
28
  struct msgpack_unpacker_t;
29
29
  typedef struct msgpack_unpacker_t msgpack_unpacker_t;
30
+ typedef struct msgpack_unpacker_stack_t msgpack_unpacker_stack_t;
30
31
 
31
32
  enum stack_type_t {
32
33
  STACK_TYPE_ARRAY,
@@ -39,19 +40,23 @@ typedef struct {
39
40
  enum stack_type_t type;
40
41
  VALUE object;
41
42
  VALUE key;
42
- } msgpack_unpacker_stack_t;
43
+ } msgpack_unpacker_stack_entry_t;
44
+
45
+ struct msgpack_unpacker_stack_t {
46
+ size_t depth;
47
+ size_t capacity;
48
+ msgpack_unpacker_stack_entry_t *data;
49
+ msgpack_unpacker_stack_t *parent;
50
+ };
43
51
 
44
52
  #define MSGPACK_UNPACKER_STACK_SIZE (8+4+8+8) /* assumes size_t <= 64bit, enum <= 32bit, VALUE <= 64bit */
45
53
 
46
54
  struct msgpack_unpacker_t {
47
55
  msgpack_buffer_t buffer;
48
-
56
+ msgpack_unpacker_stack_t *stack;
49
57
  unsigned int head_byte;
50
58
 
51
- msgpack_unpacker_stack_t* stack;
52
- size_t stack_depth;
53
- size_t stack_capacity;
54
-
59
+ VALUE self;
55
60
  VALUE last_object;
56
61
 
57
62
  VALUE reading_raw;
@@ -82,11 +87,11 @@ enum msgpack_unpacker_object_type {
82
87
  TYPE_MAP,
83
88
  };
84
89
 
85
- void msgpack_unpacker_static_init();
90
+ void msgpack_unpacker_static_init(void);
86
91
 
87
- void msgpack_unpacker_static_destroy();
92
+ void msgpack_unpacker_static_destroy(void);
88
93
 
89
- msgpack_unpacker_t* _msgpack_unpacker_new(void);
94
+ void _msgpack_unpacker_init(msgpack_unpacker_t*);
90
95
 
91
96
  void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk);
92
97
 
@@ -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,43 @@ 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;
59
54
  msgpack_unpacker_mark(uk);
60
55
  msgpack_unpacker_ext_registry_mark(uk->ext_registry);
61
56
  }
62
57
 
63
- VALUE MessagePack_Unpacker_alloc(VALUE klass)
58
+ static size_t Unpacker_memsize(const void *ptr)
64
59
  {
65
- msgpack_unpacker_t* uk = _msgpack_unpacker_new();
60
+ size_t total_size = sizeof(msgpack_unpacker_t);
61
+
62
+ const msgpack_unpacker_t* uk = ptr;
63
+ if (uk->ext_registry) {
64
+ total_size += sizeof(msgpack_unpacker_ext_registry_t) / (uk->ext_registry->borrow_count + 1);
65
+ }
66
66
 
67
- VALUE self = Data_Wrap_Struct(klass, Unpacker_mark, Unpacker_free, uk);
67
+ total_size += (uk->stack->depth + 1) * sizeof(msgpack_unpacker_stack_t);
68
+
69
+ return total_size + msgpack_buffer_memsize(&uk->buffer);
70
+ }
71
+
72
+ const rb_data_type_t unpacker_data_type = {
73
+ .wrap_struct_name = "msgpack:unpacker",
74
+ .function = {
75
+ .dmark = Unpacker_mark,
76
+ .dfree = Unpacker_free,
77
+ .dsize = Unpacker_memsize,
78
+ },
79
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
80
+ };
81
+
82
+ VALUE MessagePack_Unpacker_alloc(VALUE klass)
83
+ {
84
+ msgpack_unpacker_t* uk;
85
+ VALUE self = TypedData_Make_Struct(klass, msgpack_unpacker_t, &unpacker_data_type, uk);
86
+ _msgpack_unpacker_init(uk);
87
+ uk->self = self;
68
88
  return self;
69
89
  }
70
90
 
@@ -95,7 +115,7 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
95
115
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 0..2)", argc);
96
116
  }
97
117
 
98
- UNPACKER(self, uk);
118
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
99
119
 
100
120
  uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
101
121
 
@@ -119,19 +139,19 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
119
139
 
120
140
  static VALUE Unpacker_symbolized_keys_p(VALUE self)
121
141
  {
122
- UNPACKER(self, uk);
142
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
123
143
  return uk->symbolize_keys ? Qtrue : Qfalse;
124
144
  }
125
145
 
126
146
  static VALUE Unpacker_freeze_p(VALUE self)
127
147
  {
128
- UNPACKER(self, uk);
148
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
129
149
  return uk->freeze ? Qtrue : Qfalse;
130
150
  }
131
151
 
132
152
  static VALUE Unpacker_allow_unknown_ext_p(VALUE self)
133
153
  {
134
- UNPACKER(self, uk);
154
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
135
155
  return uk->allow_unknown_ext ? Qtrue : Qfalse;
136
156
  }
137
157
 
@@ -156,13 +176,13 @@ NORETURN(static void raise_unpacker_error(int r))
156
176
 
157
177
  static VALUE Unpacker_buffer(VALUE self)
158
178
  {
159
- UNPACKER(self, uk);
179
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
160
180
  return uk->buffer_ref;
161
181
  }
162
182
 
163
183
  static VALUE Unpacker_read(VALUE self)
164
184
  {
165
- UNPACKER(self, uk);
185
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
166
186
 
167
187
  int r = msgpack_unpacker_read(uk, 0);
168
188
  if(r < 0) {
@@ -174,7 +194,7 @@ static VALUE Unpacker_read(VALUE self)
174
194
 
175
195
  static VALUE Unpacker_skip(VALUE self)
176
196
  {
177
- UNPACKER(self, uk);
197
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
178
198
 
179
199
  int r = msgpack_unpacker_skip(uk, 0);
180
200
  if(r < 0) {
@@ -186,7 +206,7 @@ static VALUE Unpacker_skip(VALUE self)
186
206
 
187
207
  static VALUE Unpacker_skip_nil(VALUE self)
188
208
  {
189
- UNPACKER(self, uk);
209
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
190
210
 
191
211
  int r = msgpack_unpacker_skip_nil(uk);
192
212
  if(r < 0) {
@@ -201,7 +221,7 @@ static VALUE Unpacker_skip_nil(VALUE self)
201
221
 
202
222
  static VALUE Unpacker_read_array_header(VALUE self)
203
223
  {
204
- UNPACKER(self, uk);
224
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
205
225
 
206
226
  uint32_t size;
207
227
  int r = msgpack_unpacker_read_array_header(uk, &size);
@@ -214,7 +234,7 @@ static VALUE Unpacker_read_array_header(VALUE self)
214
234
 
215
235
  static VALUE Unpacker_read_map_header(VALUE self)
216
236
  {
217
- UNPACKER(self, uk);
237
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
218
238
 
219
239
  uint32_t size;
220
240
  int r = msgpack_unpacker_read_map_header(uk, &size);
@@ -228,7 +248,7 @@ static VALUE Unpacker_read_map_header(VALUE self)
228
248
 
229
249
  static VALUE Unpacker_feed(VALUE self, VALUE data)
230
250
  {
231
- UNPACKER(self, uk);
251
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
232
252
 
233
253
  StringValue(data);
234
254
 
@@ -239,7 +259,7 @@ static VALUE Unpacker_feed(VALUE self, VALUE data)
239
259
 
240
260
  static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
241
261
  {
242
- UNPACKER(self, uk);
262
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
243
263
 
244
264
  StringValue(data);
245
265
 
@@ -250,7 +270,7 @@ static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
250
270
 
251
271
  static VALUE Unpacker_each_impl(VALUE self)
252
272
  {
253
- UNPACKER(self, uk);
273
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
254
274
 
255
275
  while(true) {
256
276
  int r = msgpack_unpacker_read(uk, 0);
@@ -280,7 +300,7 @@ static VALUE Unpacker_rescue_EOFError(VALUE args, VALUE error)
280
300
 
281
301
  static VALUE Unpacker_each(VALUE self)
282
302
  {
283
- UNPACKER(self, uk);
303
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
284
304
 
285
305
  #ifdef RETURN_ENUMERATOR
286
306
  RETURN_ENUMERATOR(self, 0, 0);
@@ -311,7 +331,7 @@ static VALUE Unpacker_feed_each(VALUE self, VALUE data)
311
331
 
312
332
  static VALUE Unpacker_reset(VALUE self)
313
333
  {
314
- UNPACKER(self, uk);
334
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
315
335
 
316
336
  _msgpack_unpacker_reset(uk);
317
337
 
@@ -320,7 +340,7 @@ static VALUE Unpacker_reset(VALUE self)
320
340
 
321
341
  static VALUE Unpacker_registered_types_internal(VALUE self)
322
342
  {
323
- UNPACKER(self, uk);
343
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
324
344
 
325
345
  VALUE mapping = rb_hash_new();
326
346
  if (uk->ext_registry) {
@@ -336,7 +356,7 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
336
356
 
337
357
  static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
338
358
  {
339
- UNPACKER(self, uk);
359
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
340
360
 
341
361
  int ext_type;
342
362
  VALUE proc;
@@ -373,7 +393,7 @@ static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
373
393
 
374
394
  static VALUE Unpacker_full_unpack(VALUE self)
375
395
  {
376
- UNPACKER(self, uk);
396
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
377
397
 
378
398
  int r = msgpack_unpacker_read(uk, 0);
379
399
  if(r < 0) {
@@ -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);
@@ -21,14 +21,14 @@
21
21
  static ID s_call;
22
22
  static ID s_dup;
23
23
 
24
- void msgpack_unpacker_ext_registry_static_init()
24
+ void msgpack_unpacker_ext_registry_static_init(void)
25
25
  {
26
26
  s_call = rb_intern("call");
27
27
  s_dup = rb_intern("dup");
28
28
  }
29
29
 
30
30
 
31
- void msgpack_unpacker_ext_registry_static_destroy()
31
+ void msgpack_unpacker_ext_registry_static_destroy(void)
32
32
  { }
33
33
 
34
34
  void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg)
@@ -31,9 +31,9 @@ struct msgpack_unpacker_ext_registry_t {
31
31
  VALUE array[256];
32
32
  };
33
33
 
34
- void msgpack_unpacker_ext_registry_static_init();
34
+ void msgpack_unpacker_ext_registry_static_init(void);
35
35
 
36
- void msgpack_unpacker_ext_registry_static_destroy();
36
+ void msgpack_unpacker_ext_registry_static_destroy(void);
37
37
 
38
38
  void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg);
39
39
 
@@ -1,5 +1,5 @@
1
1
  module MessagePack
2
- VERSION = "1.5.4"
2
+ VERSION = "1.6.0"
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.
@@ -572,4 +572,21 @@ describe Buffer do
572
572
  end
573
573
  }
574
574
  end
575
+
576
+ it "defines a function for ObjectSpace.memsize_of" do
577
+ skip "JRuby doesn't support ObjectSpace.memsize_of" if IS_JRUBY
578
+
579
+ buffer = MessagePack::Buffer.new
580
+ empty_size = ObjectSpace.memsize_of(buffer)
581
+ expect(empty_size).to be < 400
582
+ 10.times do
583
+ buffer << "a" * 500
584
+ end
585
+ memsize = ObjectSpace.memsize_of(buffer)
586
+ expect(memsize).to be > empty_size
587
+ buffer.read(10)
588
+ expect(ObjectSpace.memsize_of(buffer)).to be == memsize
589
+ buffer.read_all
590
+ expect(ObjectSpace.memsize_of(buffer)).to be == empty_size
591
+ end
575
592
  end
data/spec/factory_spec.rb CHANGED
@@ -587,6 +587,48 @@ describe MessagePack::Factory do
587
587
  GC.stress = false
588
588
  end
589
589
  end
590
+
591
+ it 'does not crash in recursive extensions' do
592
+ my_hash_type = Class.new(Hash)
593
+ factory = MessagePack::Factory.new
594
+ factory.register_type(7,
595
+ my_hash_type,
596
+ packer: ->(value, packer) do
597
+ packer.write(value.to_h)
598
+ end,
599
+ unpacker: ->(unpacker) { my_hash_type.new(unpacker.read) },
600
+ recursive: true,
601
+ )
602
+
603
+ payload = factory.dump(
604
+ [my_hash_type.new]
605
+ )
606
+
607
+ begin
608
+ GC.stress = true
609
+ factory.load(payload)
610
+ ensure
611
+ GC.stress = false
612
+ end
613
+ end
614
+ end
615
+
616
+ describe 'memsize' do
617
+ it 'works on a fresh factory' do
618
+ skip "JRuby doesn't support ObjectSpace.memsize_of" if IS_JRUBY
619
+
620
+ f = MessagePack::Factory.new
621
+ expect(ObjectSpace.memsize_of(f)).to be_an(Integer)
622
+ end
623
+
624
+ it 'works on a factory with registered types' do
625
+ skip "JRuby doesn't support ObjectSpace.memsize_of" if IS_JRUBY
626
+
627
+ f = MessagePack::Factory.new
628
+ base_size = ObjectSpace.memsize_of(f)
629
+ f.register_type(0x0a, Symbol)
630
+ expect(ObjectSpace.memsize_of(f)).to be > base_size
631
+ end
590
632
  end
591
633
 
592
634
  describe 'DefaultFactory' do
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "set"
2
+ require "objspace"
2
3
 
3
4
  if ENV['SIMPLE_COV']
4
5
  require 'simplecov'
@@ -664,6 +664,16 @@ describe MessagePack::Unpacker do
664
664
  string *= 256
665
665
  MessagePack.unpack(MessagePack.pack(string)).encoding.should == string.encoding
666
666
  end
667
+
668
+ it 'returns correct size for array16 (issue #127)' do
669
+ unpacker.feed("\xdc\x00\x01\x01")
670
+ unpacker.read_array_header.should == 1
671
+ end
672
+
673
+ it 'returns correct size for map16 (issue #127)' do
674
+ unpacker.feed("\xde\x00\x02\x01\x02\x03\x04")
675
+ unpacker.read_map_header.should == 2
676
+ end
667
677
  end
668
678
 
669
679
  context 'extensions' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: msgpack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.4
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-07-25 00:00:00.000000000 Z
13
+ date: 2022-09-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
@@ -132,6 +132,7 @@ files:
132
132
  - Rakefile
133
133
  - appveyor.yml
134
134
  - bench/bench.rb
135
+ - bin/console
135
136
  - doclib/msgpack.rb
136
137
  - doclib/msgpack/buffer.rb
137
138
  - doclib/msgpack/core_ext.rb