This is the JSON parser implemented as a C extension. It can be configured to be used by setting
JSON.parser = JSON::Ext::Parser
with the method parser= in JSON.
Creates a new JSON::Ext::Parser instance for the string source.
Creates a new JSON::Ext::Parser instance for the string source.
It will be configured by the opts hash. opts can have the following keys:
opts can have the following keys:
max_nesting: The maximum depth of nesting allowed in the parsed data structures. Disable depth checking with :max_nesting => false|nil|0, it defaults to 19.
allow_nan: If set to true, allow NaN, Infinity and -Infinity in defiance of RFC 4627 to be parsed by the Parser. This option defaults to false.
symbolize_names: If set to true, returns symbols for the names (keys) in a JSON object. Otherwise strings are returned, which is also the default.
create_additions: If set to false, the Parser doesn't create additions even if a matchin class and create_id was found. This option defaults to true.
object_class: Defaults to Hash
array_class: Defaults to Array
static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) { char *ptr; long len; VALUE source, opts; GET_PARSER; rb_scan_args(argc, argv, "11", &source, &opts); source = convert_encoding(StringValue(source)); ptr = RSTRING_PTR(source); len = RSTRING_LEN(source); if (!NIL_P(opts)) { opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash"); if (NIL_P(opts)) { rb_raise(rb_eArgError, "opts needs to be like a hash"); } else { VALUE tmp = ID2SYM(i_max_nesting); if (option_given_p(opts, tmp)) { VALUE max_nesting = rb_hash_aref(opts, tmp); if (RTEST(max_nesting)) { Check_Type(max_nesting, T_FIXNUM); json->max_nesting = FIX2INT(max_nesting); } else { json->max_nesting = 0; } } else { json->max_nesting = 19; } tmp = ID2SYM(i_allow_nan); if (option_given_p(opts, tmp)) { VALUE allow_nan = rb_hash_aref(opts, tmp); json->allow_nan = RTEST(allow_nan) ? 1 : 0; } else { json->allow_nan = 0; } tmp = ID2SYM(i_symbolize_names); if (option_given_p(opts, tmp)) { VALUE symbolize_names = rb_hash_aref(opts, tmp); json->symbolize_names = RTEST(symbolize_names) ? 1 : 0; } else { json->symbolize_names = 0; } tmp = ID2SYM(i_create_additions); if (option_given_p(opts, tmp)) { VALUE create_additions = rb_hash_aref(opts, tmp); if (RTEST(create_additions)) { json->create_id = rb_funcall(mJSON, i_create_id, 0); } else { json->create_id = Qnil; } } else { json->create_id = rb_funcall(mJSON, i_create_id, 0); } tmp = ID2SYM(i_object_class); if (option_given_p(opts, tmp)) { json->object_class = rb_hash_aref(opts, tmp); } else { json->object_class = Qnil; } tmp = ID2SYM(i_array_class); if (option_given_p(opts, tmp)) { json->array_class = rb_hash_aref(opts, tmp); } else { json->array_class = Qnil; } } } else { json->max_nesting = 19; json->allow_nan = 0; json->create_id = rb_funcall(mJSON, i_create_id, 0); json->object_class = Qnil; json->array_class = Qnil; } json->current_nesting = 0; json->len = len; json->source = ptr; json->Vsource = source; return self; }
Parses the current JSON text source and returns the complete data structure as a result.
static VALUE cParser_parse(VALUE self) { char *p, *pe; int cs = EVIL; VALUE result = Qnil; GET_PARSER; #line 1701 "parser.c" { cs = JSON_start; } #line 698 "parser.rl" p = json->source; pe = p + json->len; #line 1710 "parser.c" { if ( p == pe ) goto _test_eof; switch ( cs ) { st1: if ( ++p == pe ) goto _test_eof1; case 1: switch( (*p) ) { case 13: goto st1; case 32: goto st1; case 47: goto st2; case 91: goto tr3; case 123: goto tr4; } if ( 9 <= (*p) && (*p) <= 10 ) goto st1; goto st0; st0: cs = 0; goto _out; st2: if ( ++p == pe ) goto _test_eof2; case 2: switch( (*p) ) { case 42: goto st3; case 47: goto st5; } goto st0; st3: if ( ++p == pe ) goto _test_eof3; case 3: if ( (*p) == 42 ) goto st4; goto st3; st4: if ( ++p == pe ) goto _test_eof4; case 4: switch( (*p) ) { case 42: goto st4; case 47: goto st1; } goto st3; st5: if ( ++p == pe ) goto _test_eof5; case 5: if ( (*p) == 10 ) goto st1; goto st5; tr3: #line 506 "parser.rl" { char *np; json->current_nesting = 1; np = JSON_parse_array(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} } goto st10; tr4: #line 499 "parser.rl" { char *np; json->current_nesting = 1; np = JSON_parse_object(json, p, pe, &result); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} } goto st10; st10: if ( ++p == pe ) goto _test_eof10; case 10: #line 1787 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; case 47: goto st6; } if ( 9 <= (*p) && (*p) <= 10 ) goto st10; goto st0; st6: if ( ++p == pe ) goto _test_eof6; case 6: switch( (*p) ) { case 42: goto st7; case 47: goto st9; } goto st0; st7: if ( ++p == pe ) goto _test_eof7; case 7: if ( (*p) == 42 ) goto st8; goto st7; st8: if ( ++p == pe ) goto _test_eof8; case 8: switch( (*p) ) { case 42: goto st8; case 47: goto st10; } goto st7; st9: if ( ++p == pe ) goto _test_eof9; case 9: if ( (*p) == 10 ) goto st10; goto st9; } _test_eof1: cs = 1; goto _test_eof; _test_eof2: cs = 2; goto _test_eof; _test_eof3: cs = 3; goto _test_eof; _test_eof4: cs = 4; goto _test_eof; _test_eof5: cs = 5; goto _test_eof; _test_eof10: cs = 10; goto _test_eof; _test_eof6: cs = 6; goto _test_eof; _test_eof7: cs = 7; goto _test_eof; _test_eof8: cs = 8; goto _test_eof; _test_eof9: cs = 9; goto _test_eof; _test_eof: {} _out: {} } #line 701 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; } else { rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p); return Qnil; } }
Returns a copy of the current source string, that was used to construct this Parser.
static VALUE cParser_source(VALUE self) { GET_PARSER; return rb_str_dup(json->Vsource); }
Generated with the Darkfish Rdoc Generator 2.