yaji 0.3.1 → 0.3.2

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