msgpack 1.5.4 → 1.6.0

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.
@@ -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