module FFI_Yajl::Ext::Parser

Public Instance Methods

do_yajl_parse(p1, p2) click to toggle source
static VALUE mParser_do_yajl_parse(VALUE self, VALUE str, VALUE yajl_opts) {
  yajl_handle hand;
  yajl_status stat;
  unsigned char *err;
  volatile CTX ctx;

  rb_ivar_set(self, rb_intern("stack"), rb_ary_new());
  rb_ivar_set(self, rb_intern("key_stack"), rb_ary_new());

  ctx.self = self;
  ctx.symbolizeKeys = get_opts_key(self, "symbolize_keys");

  hand = yajl_alloc(&callbacks, NULL, (void *)&ctx);

  if (rb_hash_aref(yajl_opts, ID2SYM(rb_intern("yajl_allow_comments"))) == Qtrue) {
    yajl_config(hand, yajl_allow_comments, 1);
  }
  if (rb_hash_aref(yajl_opts, ID2SYM(rb_intern("yajl_dont_validate_strings"))) == Qtrue) {
    yajl_config(hand, yajl_dont_validate_strings, 1);
  }
  if (rb_hash_aref(yajl_opts, ID2SYM(rb_intern("yajl_allow_trailing_garbage"))) == Qtrue) {
    yajl_config(hand, yajl_allow_trailing_garbage, 1);
  }
  if (rb_hash_aref(yajl_opts, ID2SYM(rb_intern("yajl_allow_multiple_values"))) == Qtrue) {
    yajl_config(hand, yajl_allow_multiple_values, 1);
  }
  if (rb_hash_aref(yajl_opts, ID2SYM(rb_intern("yajl_allow_partial_values"))) == Qtrue) {
    yajl_config(hand, yajl_allow_partial_values, 1);
  }

  if ((stat = yajl_parse(hand, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str))) != yajl_status_ok) {
    err = yajl_get_error(hand, 1, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str));
    goto raise;
  }
  if ((stat = yajl_complete_parse(hand)) != yajl_status_ok) {
    err = yajl_get_error(hand, 1, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str));
    goto raise;
  }
  yajl_free(hand);
  return rb_ivar_get(self, rb_intern("finished"));

raise:
  if (hand) {
    yajl_free(hand);
  }
  rb_raise(cParseError, "%s", err);
}