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");
}