yaji 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,7 @@
1
+ === 0.3.2 / 2012-05-25
2
+
3
+ * Don't pass stack variables to enumerator (fixes segfaults)
4
+
1
5
  === 0.3.1 / 2012-05-25
2
6
 
3
7
  * Protect on_object callback from GC
@@ -156,7 +156,7 @@ static int yaji_end_array(void *ctx)
156
156
  return STATUS_CONTINUE;
157
157
  }
158
158
 
159
- static VALUE rb_yaji_each_iter(VALUE chunk, VALUE* params_p);
159
+ static VALUE rb_yaji_each_iter(VALUE chunk, VALUE parser);
160
160
 
161
161
  static VALUE rb_yaji_parser_parse_chunk(VALUE chunk, VALUE self)
162
162
  {
@@ -178,12 +178,10 @@ static VALUE rb_yaji_parser_parse_chunk(VALUE chunk, VALUE self)
178
178
  }
179
179
  for (i=0; i<RARRAY_LEN(p->events); i++) {
180
180
  if (NIL_P(p->input)) {
181
- VALUE params[4];
182
- params[0] = p->on_object_cb;
183
- params[1] = p->object_stack;
184
- params[2] = p->filter;
185
- params[3] = p->with_path ? Qtrue : Qfalse;
186
- rb_yaji_each_iter(RARRAY_PTR(p->events)[i], params);
181
+ p->effective_proc = p->on_object_cb;
182
+ p->effective_filter = p->filter;
183
+ p->effective_with_path = p->with_path ? Qtrue : Qfalse;
184
+ rb_yaji_each_iter(RARRAY_PTR(p->events)[i], self);
187
185
  } else {
188
186
  rb_funcall(p->parser_cb, id_call, 1, RARRAY_PTR(p->events)[i]);
189
187
  }
@@ -335,59 +333,55 @@ static int rb_yaji_str_start_with(VALUE str, VALUE filter)
335
333
  return 0;
336
334
  }
337
335
 
338
- static VALUE rb_yaji_each_iter(VALUE chunk, VALUE* params_p)
336
+ static VALUE rb_yaji_each_iter(VALUE chunk, VALUE parser)
339
337
  {
340
- VALUE* params = (VALUE*)params_p;
338
+ yaji_parser* p = (yaji_parser*) DATA_PTR(parser);
341
339
  VALUE path = rb_ary_shift(chunk);
342
340
  VALUE event = rb_ary_shift(chunk);
343
341
  VALUE value = rb_ary_shift(chunk);
344
- VALUE proc = params[0];
345
- VALUE stack = params[1];
346
- VALUE filter = params[2];
347
- VALUE with_path = params[3];
348
342
  VALUE last_entry, object, container, key, hash;
349
343
 
350
- if (NIL_P(filter) || rb_yaji_str_start_with(path, filter)) {
344
+ if (NIL_P(p->effective_filter) || rb_yaji_str_start_with(path, p->effective_filter)) {
351
345
  if (event == sym_hash_key) {
352
- rb_ary_push(stack, value);
346
+ rb_ary_push(p->object_stack, value);
353
347
  } else if (event == sym_start_hash || event == sym_start_array) {
354
348
  container = (event == sym_start_hash) ? rb_hash_new() : rb_ary_new();
355
- last_entry = rb_ary_entry(stack, -1);
349
+ last_entry = rb_ary_entry(p->object_stack, -1);
356
350
  switch(TYPE(last_entry)) {
357
351
  case T_STRING:
358
- key = rb_ary_pop(stack);
359
- hash = rb_ary_entry(stack, -1);
352
+ key = rb_ary_pop(p->object_stack);
353
+ hash = rb_ary_entry(p->object_stack, -1);
360
354
  rb_hash_aset(hash, key, container);
361
355
  break;
362
356
  case T_ARRAY:
363
357
  rb_ary_push(last_entry, container);
364
358
  }
365
- rb_ary_push(stack, container);
359
+ rb_ary_push(p->object_stack, container);
366
360
  } else if (event == sym_end_hash || event == sym_end_array) {
367
- object = rb_ary_pop(stack);
368
- if (RARRAY_LEN(stack) == 0) {
369
- if (with_path == Qnil || with_path == Qfalse) {
370
- rb_funcall(proc, id_call, 1, object);
361
+ object = rb_ary_pop(p->object_stack);
362
+ if (RARRAY_LEN(p->object_stack) == 0) {
363
+ if (RTEST(p->effective_with_path)) {
364
+ rb_funcall(p->effective_proc, id_call, 1, rb_ary_new3(2, path, object));
371
365
  } else {
372
- rb_funcall(proc, id_call, 1, rb_ary_new3(2, path, object));
366
+ rb_funcall(p->effective_proc, id_call, 1, object);
373
367
  }
374
368
  }
375
369
  } else {
376
- last_entry = rb_ary_entry(stack, -1);
370
+ last_entry = rb_ary_entry(p->object_stack, -1);
377
371
  switch(TYPE(last_entry)) {
378
372
  case T_STRING:
379
- key = rb_ary_pop(stack);
380
- hash = rb_ary_entry(stack, -1);
373
+ key = rb_ary_pop(p->object_stack);
374
+ hash = rb_ary_entry(p->object_stack, -1);
381
375
  rb_hash_aset(hash, key, value);
382
376
  break;
383
377
  case T_ARRAY:
384
378
  rb_ary_push(last_entry, value);
385
379
  break;
386
380
  case T_NIL:
387
- if (with_path == Qnil || with_path == Qfalse) {
388
- rb_funcall(proc, id_call, 1, value);
381
+ if (RTEST(p->effective_with_path)) {
382
+ rb_funcall(p->effective_proc, id_call, 1, rb_ary_new3(2, path, value));
389
383
  } else {
390
- rb_funcall(proc, id_call, 1, rb_ary_new3(2, path, value));
384
+ rb_funcall(p->effective_proc, id_call, 1, value);
391
385
  }
392
386
  break;
393
387
  }
@@ -398,7 +392,7 @@ static VALUE rb_yaji_each_iter(VALUE chunk, VALUE* params_p)
398
392
 
399
393
  static VALUE rb_yaji_parser_each(int argc, VALUE* argv, VALUE self)
400
394
  {
401
- VALUE filter, proc, options, params[4];
395
+ VALUE filter, proc, options;
402
396
  yaji_parser* p = (yaji_parser*) DATA_PTR(self);
403
397
 
404
398
  if (NIL_P(p->input)) {
@@ -406,23 +400,23 @@ static VALUE rb_yaji_parser_each(int argc, VALUE* argv, VALUE self)
406
400
  }
407
401
  RETURN_ENUMERATOR(self, argc, argv);
408
402
  rb_scan_args(argc, argv, "02&", &filter, &options, &proc);
409
- params[0] = proc; // callback
410
- params[1] = rb_ary_new(); // stack
403
+ p->effective_proc = proc;
404
+ p->object_stack = rb_ary_new();
411
405
  if (NIL_P(filter)) {
412
- params[2] = p->filter;
406
+ p->effective_filter = p->filter;
413
407
  } else {
414
- params[2] = filter;
408
+ p->effective_filter = filter;
415
409
  }
416
- params[3] = p->with_path ? Qtrue : Qfalse;
410
+ p->effective_with_path = p->with_path ? Qtrue : Qfalse;
417
411
  if (options != Qnil) {
418
412
  VALUE arg;
419
413
  Check_Type(options, T_HASH);
420
414
  arg = rb_hash_aref(options, sym_with_path);
421
415
  if (!NIL_P(arg)) {
422
- params[3] = arg;
416
+ p->effective_with_path = arg;
423
417
  }
424
418
  }
425
- rb_block_call(self, id_parse, 0, NULL, rb_yaji_each_iter, (VALUE)params);
419
+ rb_block_call(self, id_parse, 0, NULL, rb_yaji_each_iter, self);
426
420
  return Qnil;
427
421
  }
428
422
 
@@ -459,6 +453,10 @@ static void rb_yaji_parser_mark(void *parser)
459
453
  rb_gc_mark(p->parser_cb);
460
454
  rb_gc_mark(p->on_object_cb);
461
455
  rb_gc_mark(p->chunk);
456
+ rb_gc_mark(p->object_stack);
457
+ rb_gc_mark(p->effective_filter);
458
+ rb_gc_mark(p->effective_with_path);
459
+ rb_gc_mark(p->effective_proc);
462
460
  }
463
461
  }
464
462
 
@@ -85,6 +85,9 @@ typedef struct {
85
85
  VALUE filter;
86
86
  VALUE on_object_cb;
87
87
  VALUE object_stack;
88
+ VALUE effective_proc;
89
+ VALUE effective_filter;
90
+ VALUE effective_with_path;
88
91
  yajl_handle handle;
89
92
  yajl_parser_config config;
90
93
  } yaji_parser;
@@ -18,5 +18,5 @@
18
18
  #
19
19
 
20
20
  module YAJI
21
- VERSION = "0.3.1"
21
+ VERSION = "0.3.2"
22
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yaji
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-05-25 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &18195000 !ruby/object:Gem::Requirement
16
+ requirement: &13210100 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.8.7
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *18195000
24
+ version_requirements: *13210100
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake-compiler
27
- requirement: &18175940 !ruby/object:Gem::Requirement
27
+ requirement: &13209100 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *18175940
35
+ version_requirements: *13209100
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: minitest
38
- requirement: &18175000 !ruby/object:Gem::Requirement
38
+ requirement: &13207760 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *18175000
46
+ version_requirements: *13207760
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: curb
49
- requirement: &18173840 !ruby/object:Gem::Requirement
49
+ requirement: &13206760 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *18173840
57
+ version_requirements: *13206760
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: ruby-debug19
60
- requirement: &18172520 !ruby/object:Gem::Requirement
60
+ requirement: &13205480 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *18172520
68
+ version_requirements: *13205480
69
69
  description: YAJI is a ruby wrapper to YAJL providing iterator interface to streaming
70
70
  JSON parser
71
71
  email: info@couchbase.com