ext/json/ext/parser/parser.c in json-1.1.1-mswin32 vs ext/json/ext/parser/parser.c in json-1.1.2

- old
+ new

@@ -9,12 +9,12 @@ #define EVIL 0x666 static VALUE mJSON, mExt, cParser, eParserError, eNestingError; static VALUE CNaN, CInfinity, CMinusInfinity; -static ID i_json_creatable_p, i_json_create, i_create_id, i_chr, i_max_nesting, - i_allow_nan; +static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, + i_chr, i_max_nesting, i_allow_nan; #define MinusInfinity "-Infinity" typedef struct JSON_ParserStruct { VALUE Vsource; @@ -384,46 +384,48 @@ _out: {} } #line 114 "parser.rl" if (cs >= JSON_object_first_final) { - VALUE klassname = rb_hash_aref(*result, json->create_id); - if (!NIL_P(klassname)) { - VALUE klass = rb_path2class(StringValueCStr(klassname)); - if RTEST(rb_funcall(klass, i_json_creatable_p, 0)) { - *result = rb_funcall(klass, i_json_create, 1, *result); + if (RTEST(json->create_id)) { + VALUE klassname = rb_hash_aref(*result, json->create_id); + if (!NIL_P(klassname)) { + VALUE klass = rb_path2class(StringValueCStr(klassname)); + if RTEST(rb_funcall(klass, i_json_creatable_p, 0)) { + *result = rb_funcall(klass, i_json_create, 1, *result); + } } } return p + 1; } else { return NULL; } } -#line 404 "parser.c" +#line 406 "parser.c" static const int JSON_value_start = 1; static const int JSON_value_first_final = 21; static const int JSON_value_error = 0; static const int JSON_value_en_main = 1; -#line 210 "parser.rl" +#line 212 "parser.rl" static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; -#line 419 "parser.c" +#line 421 "parser.c" { cs = JSON_value_start; } -#line 217 "parser.rl" +#line 219 "parser.rl" -#line 425 "parser.c" +#line 427 "parser.c" { if ( p == pe ) goto _out; switch ( cs ) { @@ -443,18 +445,18 @@ goto tr2; goto st0; st0: goto _out0; tr0: -#line 158 "parser.rl" +#line 160 "parser.rl" { char *np = JSON_parse_string(json, p, pe, result); if (np == NULL) goto _out21; else {p = (( np))-1;} } goto st21; tr2: -#line 163 "parser.rl" +#line 165 "parser.rl" { char *np; if(pe > p + 9 && !strncmp(MinusInfinity, p, 9)) { if (json->allow_nan) { *result = CMinusInfinity; @@ -470,74 +472,74 @@ if (np != NULL) {p = (( np))-1;} goto _out21; } goto st21; tr5: -#line 181 "parser.rl" +#line 183 "parser.rl" { char *np; json->current_nesting += 1; np = JSON_parse_array(json, p, pe, result); json->current_nesting -= 1; if (np == NULL) goto _out21; else {p = (( np))-1;} } goto st21; tr9: -#line 189 "parser.rl" +#line 191 "parser.rl" { char *np; json->current_nesting += 1; np = JSON_parse_object(json, p, pe, result); json->current_nesting -= 1; if (np == NULL) goto _out21; else {p = (( np))-1;} } goto st21; tr16: -#line 151 "parser.rl" +#line 153 "parser.rl" { if (json->allow_nan) { *result = CInfinity; } else { rb_raise(eParserError, "unexpected token at '%s'", p - 8); } } goto st21; tr18: -#line 144 "parser.rl" +#line 146 "parser.rl" { if (json->allow_nan) { *result = CNaN; } else { rb_raise(eParserError, "unexpected token at '%s'", p - 2); } } goto st21; tr22: -#line 138 "parser.rl" +#line 140 "parser.rl" { *result = Qfalse; } goto st21; tr25: -#line 135 "parser.rl" +#line 137 "parser.rl" { *result = Qnil; } goto st21; tr28: -#line 141 "parser.rl" +#line 143 "parser.rl" { *result = Qtrue; } goto st21; st21: if ( ++p == pe ) goto _out21; case 21: -#line 197 "parser.rl" +#line 199 "parser.rl" { goto _out21; } -#line 539 "parser.c" +#line 541 "parser.c" goto st0; st2: if ( ++p == pe ) goto _out2; case 2: @@ -693,43 +695,43 @@ _out19: cs = 19; goto _out; _out20: cs = 20; goto _out; _out: {} } -#line 218 "parser.rl" +#line 220 "parser.rl" if (cs >= JSON_value_first_final) { return p; } else { return NULL; } } -#line 709 "parser.c" +#line 711 "parser.c" static const int JSON_integer_start = 1; static const int JSON_integer_first_final = 5; static const int JSON_integer_error = 0; static const int JSON_integer_en_main = 1; -#line 234 "parser.rl" +#line 236 "parser.rl" static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; -#line 724 "parser.c" +#line 726 "parser.c" { cs = JSON_integer_start; } -#line 241 "parser.rl" +#line 243 "parser.rl" json->memo = p; -#line 731 "parser.c" +#line 733 "parser.c" { if ( p == pe ) goto _out; switch ( cs ) { @@ -758,18 +760,18 @@ case 3: if ( 48 <= (*p) && (*p) <= 57 ) goto st0; goto tr4; tr4: -#line 231 "parser.rl" +#line 233 "parser.rl" { goto _out5; } goto st5; st5: if ( ++p == pe ) goto _out5; case 5: -#line 771 "parser.c" +#line 773 "parser.c" goto st0; st4: if ( ++p == pe ) goto _out4; case 4: @@ -783,11 +785,11 @@ _out5: cs = 5; goto _out; _out4: cs = 4; goto _out; _out: {} } -#line 243 "parser.rl" +#line 245 "parser.rl" if (cs >= JSON_integer_first_final) { long len = p - json->memo; *result = rb_Integer(rb_str_new(json->memo, len)); return p + 1; @@ -795,33 +797,33 @@ return NULL; } } -#line 801 "parser.c" +#line 803 "parser.c" static const int JSON_float_start = 1; static const int JSON_float_first_final = 10; static const int JSON_float_error = 0; static const int JSON_float_en_main = 1; -#line 265 "parser.rl" +#line 267 "parser.rl" static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; -#line 816 "parser.c" +#line 818 "parser.c" { cs = JSON_float_start; } -#line 272 "parser.rl" +#line 274 "parser.rl" json->memo = p; -#line 823 "parser.c" +#line 825 "parser.c" { if ( p == pe ) goto _out; switch ( cs ) { @@ -874,18 +876,18 @@ goto st5; } else if ( (*p) >= 45 ) goto st0; goto tr7; tr7: -#line 259 "parser.rl" +#line 261 "parser.rl" { goto _out10; } goto st10; st10: if ( ++p == pe ) goto _out10; case 10: -#line 887 "parser.c" +#line 889 "parser.c" goto st0; st6: if ( ++p == pe ) goto _out6; case 6: @@ -941,11 +943,11 @@ _out8: cs = 8; goto _out; _out9: cs = 9; goto _out; _out: {} } -#line 274 "parser.rl" +#line 276 "parser.rl" if (cs >= JSON_float_first_final) { long len = p - json->memo; *result = rb_Float(rb_str_new(json->memo, len)); return p + 1; @@ -954,18 +956,18 @@ } } -#line 960 "parser.c" +#line 962 "parser.c" static const int JSON_array_start = 1; static const int JSON_array_first_final = 17; static const int JSON_array_error = 0; static const int JSON_array_en_main = 1; -#line 310 "parser.rl" +#line 312 "parser.rl" static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; @@ -974,17 +976,17 @@ rb_raise(eNestingError, "nesting of %d is to deep", json->current_nesting); } *result = rb_ary_new(); -#line 980 "parser.c" +#line 982 "parser.c" { cs = JSON_array_start; } -#line 322 "parser.rl" +#line 324 "parser.rl" -#line 986 "parser.c" +#line 988 "parser.c" { if ( p == pe ) goto _out; switch ( cs ) { @@ -1018,11 +1020,11 @@ goto tr2; } else if ( (*p) >= 9 ) goto st2; goto st0; tr2: -#line 291 "parser.rl" +#line 293 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v); if (np == NULL) { goto _out3; @@ -1034,11 +1036,11 @@ goto st3; st3: if ( ++p == pe ) goto _out3; case 3: -#line 1040 "parser.c" +#line 1042 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; case 44: goto st4; case 47: goto st9; @@ -1134,18 +1136,18 @@ case 12: if ( (*p) == 10 ) goto st3; goto st12; tr4: -#line 302 "parser.rl" +#line 304 "parser.rl" { goto _out17; } goto st17; st17: if ( ++p == pe ) goto _out17; case 17: -#line 1147 "parser.c" +#line 1149 "parser.c" goto st0; st13: if ( ++p == pe ) goto _out13; case 13: @@ -1196,11 +1198,11 @@ _out15: cs = 15; goto _out; _out16: cs = 16; goto _out; _out: {} } -#line 323 "parser.rl" +#line 325 "parser.rl" if(cs >= JSON_array_first_final) { return p + 1; } else { rb_raise(eParserError, "unexpected token at '%s'", p); @@ -1262,34 +1264,34 @@ } return result; } -#line 1268 "parser.c" +#line 1270 "parser.c" static const int JSON_string_start = 1; static const int JSON_string_first_final = 8; static const int JSON_string_error = 0; static const int JSON_string_en_main = 1; -#line 401 "parser.rl" +#line 403 "parser.rl" static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result) { int cs = EVIL; *result = rb_str_new("", 0); -#line 1284 "parser.c" +#line 1286 "parser.c" { cs = JSON_string_start; } -#line 409 "parser.rl" +#line 411 "parser.rl" json->memo = p; -#line 1291 "parser.c" +#line 1293 "parser.c" { if ( p == pe ) goto _out; switch ( cs ) { @@ -1309,23 +1311,23 @@ } if ( 0 <= (*p) && (*p) <= 31 ) goto st0; goto st2; tr2: -#line 393 "parser.rl" +#line 395 "parser.rl" { *result = json_string_unescape(json->memo + 1, p); if (NIL_P(*result)) goto _out8; else {p = (( p + 1))-1;} } -#line 398 "parser.rl" +#line 400 "parser.rl" { goto _out8; } goto st8; st8: if ( ++p == pe ) goto _out8; case 8: -#line 1327 "parser.c" +#line 1329 "parser.c" goto st0; st3: if ( ++p == pe ) goto _out3; case 3: @@ -1396,29 +1398,29 @@ _out6: cs = 6; goto _out; _out7: cs = 7; goto _out; _out: {} } -#line 411 "parser.rl" +#line 413 "parser.rl" if (cs >= JSON_string_first_final) { return p + 1; } else { return NULL; } } -#line 1413 "parser.c" +#line 1415 "parser.c" static const int JSON_start = 1; static const int JSON_first_final = 10; static const int JSON_error = 0; static const int JSON_en_main = 1; -#line 445 "parser.rl" +#line 447 "parser.rl" /* * Document-class: JSON::Ext::Parser * @@ -1446,10 +1448,13 @@ * 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. + * * *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. */ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) { char *ptr; long len; @@ -1460,12 +1465,10 @@ ptr = RSTRING_PTR(source); len = RSTRING_LEN(source); if (len < 2) { rb_raise(eParserError, "A JSON text must at least contain two octets!"); } - json->max_nesting = 19; - json->allow_nan = 0; 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 { @@ -1476,17 +1479,36 @@ 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 (st_lookup(RHASH(opts)->tbl, tmp, 0)) { VALUE allow_nan = rb_hash_aref(opts, tmp); - if (RTEST(allow_nan)) json->allow_nan = 1; + json->allow_nan = RTEST(allow_nan) ? 1 : 0; + } else { + json->allow_nan = 0; } + tmp = ID2SYM(i_create_additions); + if (st_lookup(RHASH(opts)->tbl, tmp, 0)) { + 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); + } } + } else { + json->max_nesting = 19; + json->allow_nan = 0; + json->create_id = rb_funcall(mJSON, i_create_id, 0); } json->current_nesting = 0; /* Convert these? if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) { @@ -1500,11 +1522,10 @@ } */ json->len = len; json->source = ptr; json->Vsource = source; - json->create_id = rb_funcall(mJSON, i_create_id, 0); return self; } /* * call-seq: parse() @@ -1518,19 +1539,19 @@ int cs = EVIL; VALUE result = Qnil; GET_STRUCT; -#line 1524 "parser.c" +#line 1545 "parser.c" { cs = JSON_start; } -#line 548 "parser.rl" +#line 569 "parser.rl" p = json->source; pe = p + json->len; -#line 1532 "parser.c" +#line 1553 "parser.c" { if ( p == pe ) goto _out; switch ( cs ) { @@ -1581,20 +1602,20 @@ case 5: if ( (*p) == 10 ) goto st1; goto st5; tr3: -#line 434 "parser.rl" +#line 436 "parser.rl" { char *np; json->current_nesting = 1; np = JSON_parse_array(json, p, pe, &result); if (np == NULL) goto _out10; else {p = (( np))-1;} } goto st10; tr4: -#line 427 "parser.rl" +#line 429 "parser.rl" { char *np; json->current_nesting = 1; np = JSON_parse_object(json, p, pe, &result); if (np == NULL) goto _out10; else {p = (( np))-1;} @@ -1602,11 +1623,11 @@ goto st10; st10: if ( ++p == pe ) goto _out10; case 10: -#line 1608 "parser.c" +#line 1629 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; case 47: goto st6; } @@ -1658,20 +1679,20 @@ _out8: cs = 8; goto _out; _out9: cs = 9; goto _out; _out: {} } -#line 551 "parser.rl" +#line 572 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; } else { rb_raise(eParserError, "unexpected token at '%s'", p); } } -static JSON_Parser *JSON_allocate() +inline static JSON_Parser *JSON_allocate() { JSON_Parser *json = ALLOC(JSON_Parser); MEMZERO(json, JSON_Parser, 1); return json; } @@ -1722,9 +1743,10 @@ CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity")); i_json_creatable_p = rb_intern("json_creatable?"); i_json_create = rb_intern("json_create"); i_create_id = rb_intern("create_id"); + i_create_additions = rb_intern("create_additions"); i_chr = rb_intern("chr"); i_max_nesting = rb_intern("max_nesting"); i_allow_nan = rb_intern("allow_nan"); }