7 static const char digit_values[256] = {
8 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
9 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
10 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
11 -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
12 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
13 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
14 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
15 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
16 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
17 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
18 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
19 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
20 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
21 -1, -1, -1, -1, -1, -1, -1
24 static UTF32 unescape_unicode(const unsigned char *p)
28 b = digit_values[p[0]];
29 if (b < 0) return UNI_REPLACEMENT_CHAR;
30 result = (result << 4) | b;
31 b = digit_values[p[1]];
32 result = (result << 4) | b;
33 if (b < 0) return UNI_REPLACEMENT_CHAR;
34 b = digit_values[p[2]];
35 result = (result << 4) | b;
36 if (b < 0) return UNI_REPLACEMENT_CHAR;
37 b = digit_values[p[3]];
38 result = (result << 4) | b;
39 if (b < 0) return UNI_REPLACEMENT_CHAR;
43 static int convert_UTF32_to_UTF8(char *buf, UTF32 ch)
48 } else if (ch <= 0x07FF) {
49 buf[0] = (char) ((ch >> 6) | 0xC0);
50 buf[1] = (char) ((ch & 0x3F) | 0x80);
52 } else if (ch <= 0xFFFF) {
53 buf[0] = (char) ((ch >> 12) | 0xE0);
54 buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
55 buf[2] = (char) ((ch & 0x3F) | 0x80);
57 } else if (ch <= 0x1fffff) {
58 buf[0] =(char) ((ch >> 18) | 0xF0);
59 buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
60 buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
61 buf[3] =(char) ((ch & 0x3F) | 0x80);
69 #ifdef HAVE_RUBY_ENCODING_H
70 static VALUE CEncoding_ASCII_8BIT, CEncoding_UTF_8, CEncoding_UTF_16BE,
71 CEncoding_UTF_16LE, CEncoding_UTF_32BE, CEncoding_UTF_32LE;
72 static ID i_encoding, i_encode;
77 static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
78 static VALUE CNaN, CInfinity, CMinusInfinity;
80 static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
81 i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_quirks_mode,
82 i_object_class, i_array_class, i_key_p, i_deep_const_get, i_match,
83 i_match_string, i_aset, i_leftshift;
91 static const int JSON_object_start = 1;
92 static const int JSON_object_first_final = 27;
93 static const int JSON_object_error = 0;
95 static const int JSON_object_en_main = 1;
101 static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result)
104 VALUE last_name = Qnil;
105 VALUE object_class = json->object_class;
107 if (json->max_nesting && json->current_nesting > json->max_nesting) {
108 rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
111 *result = NIL_P(object_class) ? rb_hash_new() : rb_class_new_instance(0, 0, object_class);
116 cs = JSON_object_start;
119 #line 165 "parser.rl"
145 if ( 9 <= (*p) && (*p) <= 10 )
149 #line 132 "parser.rl"
152 json->parsing_name = 1;
153 np = JSON_parse_string(json, p, pe, &last_name);
154 json->parsing_name = 0;
155 if (np == NULL) { p--; {p++; cs = 3; goto _out;} } else {p = (( np))-1;}
169 if ( 9 <= (*p) && (*p) <= 10 )
223 if ( 48 <= (*p) && (*p) <= 57 )
225 } else if ( (*p) >= 9 )
229 #line 117 "parser.rl"
232 char *np = JSON_parse_value(json, p, pe, &v);
234 p--; {p++; cs = 9; goto _out;}
236 if (NIL_P(json->object_class)) {
237 rb_hash_aset(*result, last_name, v);
239 rb_funcall(*result, i_aset, 2, last_name, v);
257 if ( 9 <= (*p) && (*p) <= 10 )
270 if ( 9 <= (*p) && (*p) <= 10 )
338 #line 140 "parser.rl"
339 { p--; {p++; cs = 27; goto _out;} }
412 _test_eof2: cs = 2; goto _test_eof;
413 _test_eof3: cs = 3; goto _test_eof;
414 _test_eof4: cs = 4; goto _test_eof;
415 _test_eof5: cs = 5; goto _test_eof;
416 _test_eof6: cs = 6; goto _test_eof;
417 _test_eof7: cs = 7; goto _test_eof;
418 _test_eof8: cs = 8; goto _test_eof;
419 _test_eof9: cs = 9; goto _test_eof;
420 _test_eof10: cs = 10; goto _test_eof;
421 _test_eof11: cs = 11; goto _test_eof;
422 _test_eof12: cs = 12; goto _test_eof;
423 _test_eof13: cs = 13; goto _test_eof;
424 _test_eof14: cs = 14; goto _test_eof;
425 _test_eof15: cs = 15; goto _test_eof;
426 _test_eof16: cs = 16; goto _test_eof;
427 _test_eof17: cs = 17; goto _test_eof;
428 _test_eof18: cs = 18; goto _test_eof;
429 _test_eof27: cs = 27; goto _test_eof;
430 _test_eof19: cs = 19; goto _test_eof;
431 _test_eof20: cs = 20; goto _test_eof;
432 _test_eof21: cs = 21; goto _test_eof;
433 _test_eof22: cs = 22; goto _test_eof;
434 _test_eof23: cs = 23; goto _test_eof;
435 _test_eof24: cs = 24; goto _test_eof;
436 _test_eof25: cs = 25; goto _test_eof;
437 _test_eof26: cs = 26; goto _test_eof;
443 #line 166 "parser.rl"
445 if (cs >= JSON_object_first_final) {
446 if (json->create_additions) {
447 VALUE klassname = rb_hash_aref(*result, json->create_id);
448 if (!NIL_P(klassname)) {
449 VALUE klass = rb_funcall(mJSON, i_deep_const_get, 1, klassname);
450 if (RTEST(rb_funcall(klass, i_json_creatable_p, 0))) {
451 *result = rb_funcall(klass, i_json_create, 1, *result);
464 static const int JSON_value_start = 1;
465 static const int JSON_value_first_final = 21;
466 static const int JSON_value_error = 0;
468 static const int JSON_value_en_main = 1;
471 #line 265 "parser.rl"
474 static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result)
481 cs = JSON_value_start;
484 #line 272 "parser.rl"
504 if ( 48 <= (*p) && (*p) <= 57 )
511 #line 213 "parser.rl"
513 char *np = JSON_parse_string(json, p, pe, result);
514 if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
518 #line 218 "parser.rl"
521 if(pe > p + 9 - json->quirks_mode && !strncmp(MinusInfinity, p, 9)) {
522 if (json->allow_nan) {
523 *result = CMinusInfinity;
525 p--; {p++; cs = 21; goto _out;}
527 rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
530 np = JSON_parse_float(json, p, pe, result);
531 if (np != NULL) {p = (( np))-1;}
532 np = JSON_parse_integer(json, p, pe, result);
533 if (np != NULL) {p = (( np))-1;}
534 p--; {p++; cs = 21; goto _out;}
538 #line 236 "parser.rl"
541 json->current_nesting++;
542 np = JSON_parse_array(json, p, pe, result);
543 json->current_nesting--;
544 if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
548 #line 244 "parser.rl"
551 json->current_nesting++;
552 np = JSON_parse_object(json, p, pe, result);
553 json->current_nesting--;
554 if (np == NULL) { p--; {p++; cs = 21; goto _out;} } else {p = (( np))-1;}
558 #line 206 "parser.rl"
560 if (json->allow_nan) {
563 rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
568 #line 199 "parser.rl"
570 if (json->allow_nan) {
573 rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
578 #line 193 "parser.rl"
584 #line 190 "parser.rl"
590 #line 196 "parser.rl"
599 #line 252 "parser.rl"
600 { p--; {p++; cs = 21; goto _out;} }
737 _test_eof21: cs = 21; goto _test_eof;
738 _test_eof2: cs = 2; goto _test_eof;
739 _test_eof3: cs = 3; goto _test_eof;
740 _test_eof4: cs = 4; goto _test_eof;
741 _test_eof5: cs = 5; goto _test_eof;
742 _test_eof6: cs = 6; goto _test_eof;
743 _test_eof7: cs = 7; goto _test_eof;
744 _test_eof8: cs = 8; goto _test_eof;
745 _test_eof9: cs = 9; goto _test_eof;
746 _test_eof10: cs = 10; goto _test_eof;
747 _test_eof11: cs = 11; goto _test_eof;
748 _test_eof12: cs = 12; goto _test_eof;
749 _test_eof13: cs = 13; goto _test_eof;
750 _test_eof14: cs = 14; goto _test_eof;
751 _test_eof15: cs = 15; goto _test_eof;
752 _test_eof16: cs = 16; goto _test_eof;
753 _test_eof17: cs = 17; goto _test_eof;
754 _test_eof18: cs = 18; goto _test_eof;
755 _test_eof19: cs = 19; goto _test_eof;
756 _test_eof20: cs = 20; goto _test_eof;
762 #line 273 "parser.rl"
764 if (cs >= JSON_value_first_final) {
773 static const int JSON_integer_start = 1;
774 static const int JSON_integer_first_final = 3;
775 static const int JSON_integer_error = 0;
777 static const int JSON_integer_en_main = 1;
780 #line 289 "parser.rl"
783 static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
790 cs = JSON_integer_start;
793 #line 296 "parser.rl"
807 if ( 49 <= (*p) && (*p) <= 57 )
819 if ( 49 <= (*p) && (*p) <= 57 )
826 if ( 48 <= (*p) && (*p) <= 57 )
830 #line 286 "parser.rl"
831 { p--; {p++; cs = 4; goto _out;} }
843 if ( 48 <= (*p) && (*p) <= 57 )
847 _test_eof2: cs = 2; goto _test_eof;
848 _test_eof3: cs = 3; goto _test_eof;
849 _test_eof4: cs = 4; goto _test_eof;
850 _test_eof5: cs = 5; goto _test_eof;
856 #line 298 "parser.rl"
858 if (cs >= JSON_integer_first_final) {
859 long len = p - json->memo;
860 *result = rb_Integer(rb_str_new(json->memo, len));
869 static const int JSON_float_start = 1;
870 static const int JSON_float_first_final = 8;
871 static const int JSON_float_error = 0;
873 static const int JSON_float_en_main = 1;
876 #line 320 "parser.rl"
879 static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *result)
886 cs = JSON_float_start;
889 #line 327 "parser.rl"
903 if ( 49 <= (*p) && (*p) <= 57 )
915 if ( 49 <= (*p) && (*p) <= 57 )
932 if ( 48 <= (*p) && (*p) <= 57 )
944 if ( 48 <= (*p) && (*p) <= 57 )
946 } else if ( (*p) >= 45 )
950 #line 314 "parser.rl"
951 { p--; {p++; cs = 9; goto _out;} }
967 if ( 48 <= (*p) && (*p) <= 57 )
974 if ( 48 <= (*p) && (*p) <= 57 )
986 if ( 48 <= (*p) && (*p) <= 57 )
988 } else if ( (*p) >= 45 )
1000 if ( 48 <= (*p) && (*p) <= 57 )
1004 _test_eof2: cs = 2; goto _test_eof;
1005 _test_eof3: cs = 3; goto _test_eof;
1006 _test_eof4: cs = 4; goto _test_eof;
1007 _test_eof8: cs = 8; goto _test_eof;
1008 _test_eof9: cs = 9; goto _test_eof;
1009 _test_eof5: cs = 5; goto _test_eof;
1010 _test_eof6: cs = 6; goto _test_eof;
1011 _test_eof10: cs = 10; goto _test_eof;
1012 _test_eof7: cs = 7; goto _test_eof;
1018 #line 329 "parser.rl"
1020 if (cs >= JSON_float_first_final) {
1021 long len = p - json->memo;
1022 *result = rb_Float(rb_str_new(json->memo, len));
1031 #line 1032 "parser.c"
1032 static const int JSON_array_start = 1;
1033 static const int JSON_array_first_final = 17;
1034 static const int JSON_array_error = 0;
1036 static const int JSON_array_en_main = 1;
1039 #line 369 "parser.rl"
1042 static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result)
1045 VALUE array_class = json->array_class;
1047 if (json->max_nesting && json->current_nesting > json->max_nesting) {
1048 rb_raise(eNestingError, "nesting of %d is too deep", json->current_nesting);
1050 *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
1053 #line 1054 "parser.c"
1055 cs = JSON_array_start;
1058 #line 382 "parser.rl"
1060 #line 1061 "parser.c"
1093 if ( 48 <= (*p) && (*p) <= 57 )
1095 } else if ( (*p) >= 9 )
1099 #line 346 "parser.rl"
1102 char *np = JSON_parse_value(json, p, pe, &v);
1104 p--; {p++; cs = 3; goto _out;}
1106 if (NIL_P(json->array_class)) {
1107 rb_ary_push(*result, v);
1109 rb_funcall(*result, i_leftshift, 1, v);
1119 #line 1120 "parser.c"
1127 if ( 9 <= (*p) && (*p) <= 10 )
1149 if ( 48 <= (*p) && (*p) <= 57 )
1151 } else if ( (*p) >= 9 )
1219 #line 361 "parser.rl"
1220 { p--; {p++; cs = 17; goto _out;} }
1226 #line 1227 "parser.c"
1261 _test_eof2: cs = 2; goto _test_eof;
1262 _test_eof3: cs = 3; goto _test_eof;
1263 _test_eof4: cs = 4; goto _test_eof;
1264 _test_eof5: cs = 5; goto _test_eof;
1265 _test_eof6: cs = 6; goto _test_eof;
1266 _test_eof7: cs = 7; goto _test_eof;
1267 _test_eof8: cs = 8; goto _test_eof;
1268 _test_eof9: cs = 9; goto _test_eof;
1269 _test_eof10: cs = 10; goto _test_eof;
1270 _test_eof11: cs = 11; goto _test_eof;
1271 _test_eof12: cs = 12; goto _test_eof;
1272 _test_eof17: cs = 17; goto _test_eof;
1273 _test_eof13: cs = 13; goto _test_eof;
1274 _test_eof14: cs = 14; goto _test_eof;
1275 _test_eof15: cs = 15; goto _test_eof;
1276 _test_eof16: cs = 16; goto _test_eof;
1282 #line 383 "parser.rl"
1284 if(cs >= JSON_array_first_final) {
1287 rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1292 static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
1294 char *p = string, *pe = string, *unescape;
1297 while (pe < stringEnd) {
1299 unescape = (char *) "?";
1301 if (pe > p) rb_str_buf_cat(result, p, pe - p);
1304 unescape = (char *) "\n";
1307 unescape = (char *) "\r";
1310 unescape = (char *) "\t";
1313 unescape = (char *) "\"";
1316 unescape = (char *) "\\";
1319 unescape = (char *) "\b";
1322 unescape = (char *) "\f";
1325 if (pe > stringEnd - 4) {
1329 UTF32 ch = unescape_unicode((unsigned char *) ++pe);
1331 if (UNI_SUR_HIGH_START == (ch & 0xFC00)) {
1333 if (pe > stringEnd - 6) return Qnil;
1334 if (pe[0] == '\\' && pe[1] == 'u') {
1335 UTF32 sur = unescape_unicode((unsigned char *) pe + 2);
1336 ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
1340 unescape = (char *) "?";
1344 unescape_len = convert_UTF32_to_UTF8(buf, ch);
1352 rb_str_buf_cat(result, unescape, unescape_len);
1358 rb_str_buf_cat(result, p, pe - p);
1363 #line 1364 "parser.c"
1364 static const int JSON_string_start = 1;
1365 static const int JSON_string_first_final = 8;
1366 static const int JSON_string_error = 0;
1368 static const int JSON_string_en_main = 1;
1371 #line 482 "parser.rl"
1375 match_i(VALUE regexp, VALUE klass, VALUE memo)
1377 if (regexp == Qundef) return ST_STOP;
1378 if (RTEST(rb_funcall(klass, i_json_creatable_p, 0)) &&
1379 RTEST(rb_funcall(regexp, i_match, 1, rb_ary_entry(memo, 0)))) {
1380 rb_ary_push(memo, klass);
1386 static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *result)
1391 *result = rb_str_buf_new(0);
1393 #line 1394 "parser.c"
1395 cs = JSON_string_start;
1398 #line 503 "parser.rl"
1401 #line 1402 "parser.c"
1422 if ( 0 <= (*p) && (*p) <= 31 )
1426 #line 468 "parser.rl"
1428 *result = json_string_unescape(*result, json->memo + 1, p);
1429 if (NIL_P(*result)) {
1431 {p++; cs = 8; goto _out;}
1433 FORCE_UTF8(*result);
1437 #line 479 "parser.rl"
1438 { p--; {p++; cs = 8; goto _out;} }
1444 #line 1445 "parser.c"
1452 if ( 0 <= (*p) && (*p) <= 31 )
1460 if ( 48 <= (*p) && (*p) <= 57 )
1462 } else if ( (*p) > 70 ) {
1463 if ( 97 <= (*p) && (*p) <= 102 )
1473 if ( 48 <= (*p) && (*p) <= 57 )
1475 } else if ( (*p) > 70 ) {
1476 if ( 97 <= (*p) && (*p) <= 102 )
1486 if ( 48 <= (*p) && (*p) <= 57 )
1488 } else if ( (*p) > 70 ) {
1489 if ( 97 <= (*p) && (*p) <= 102 )
1499 if ( 48 <= (*p) && (*p) <= 57 )
1501 } else if ( (*p) > 70 ) {
1502 if ( 97 <= (*p) && (*p) <= 102 )
1508 _test_eof2: cs = 2; goto _test_eof;
1509 _test_eof8: cs = 8; goto _test_eof;
1510 _test_eof3: cs = 3; goto _test_eof;
1511 _test_eof4: cs = 4; goto _test_eof;
1512 _test_eof5: cs = 5; goto _test_eof;
1513 _test_eof6: cs = 6; goto _test_eof;
1514 _test_eof7: cs = 7; goto _test_eof;
1520 #line 505 "parser.rl"
1522 if (json->create_additions && RTEST(match_string = json->match_string)) {
1524 VALUE memo = rb_ary_new2(2);
1525 rb_ary_push(memo, *result);
1526 rb_hash_foreach(match_string, match_i, memo);
1527 klass = rb_ary_entry(memo, 1);
1529 *result = rb_funcall(klass, i_json_create, 1, *result);
1533 if (json->symbolize_names && json->parsing_name) {
1534 *result = rb_str_intern(*result);
1536 if (cs >= JSON_string_first_final) {
1544 * Document-class: JSON::Ext::Parser
1546 * This is the JSON parser implemented as a C extension. It can be configured
1547 * to be used by setting
1549 * JSON.parser = JSON::Ext::Parser
1551 * with the method parser= in JSON.
1555 static VALUE convert_encoding(VALUE source)
1557 char *ptr = RSTRING_PTR(source);
1558 long len = RSTRING_LEN(source);
1560 rb_raise(eParserError, "A JSON text must at least contain two octets!");
1562 #ifdef HAVE_RUBY_ENCODING_H
1564 VALUE encoding = rb_funcall(source, i_encoding, 0);
1565 if (encoding == CEncoding_ASCII_8BIT) {
1566 if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1567 source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32BE);
1568 } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1569 source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16BE);
1570 } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1571 source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_32LE);
1572 } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1573 source = rb_funcall(source, i_encode, 2, CEncoding_UTF_8, CEncoding_UTF_16LE);
1575 source = rb_str_dup(source);
1579 source = rb_funcall(source, i_encode, 1, CEncoding_UTF_8);
1583 if (len >= 4 && ptr[0] == 0 && ptr[1] == 0 && ptr[2] == 0) {
1584 source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32be"), source);
1585 } else if (len >= 4 && ptr[0] == 0 && ptr[2] == 0) {
1586 source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16be"), source);
1587 } else if (len >= 4 && ptr[1] == 0 && ptr[2] == 0 && ptr[3] == 0) {
1588 source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-32le"), source);
1589 } else if (len >= 4 && ptr[1] == 0 && ptr[3] == 0) {
1590 source = rb_funcall(mJSON, i_iconv, 3, rb_str_new2("utf-8"), rb_str_new2("utf-16le"), source);
1597 * call-seq: new(source, opts => {})
1599 * Creates a new JSON::Ext::Parser instance for the string _source_.
1601 * Creates a new JSON::Ext::Parser instance for the string _source_.
1603 * It will be configured by the _opts_ hash. _opts_ can have the following
1606 * _opts_ can have the following keys:
1607 * * *max_nesting*: The maximum depth of nesting allowed in the parsed data
1608 * structures. Disable depth checking with :max_nesting => false|nil|0, it
1610 * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in
1611 * defiance of RFC 4627 to be parsed by the Parser. This option defaults to
1613 * * *symbolize_names*: If set to true, returns symbols for the names
1614 * (keys) in a JSON object. Otherwise strings are returned, which is also
1616 * * *create_additions*: If set to false, the Parser doesn't create
1617 * additions even if a matchin class and create_id was found. This option
1619 * * *object_class*: Defaults to Hash
1620 * * *array_class*: Defaults to Array
1621 * * *quirks_mode*: Enables quirks_mode for parser, that is for example
1622 * parsing single JSON values instead of documents is possible.
1625 static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
1630 if (json->Vsource) {
1631 rb_raise(rb_eTypeError, "already initialized instance");
1633 rb_scan_args(argc, argv, "11", &source, &opts);
1635 opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
1637 rb_raise(rb_eArgError, "opts needs to be like a hash");
1639 VALUE tmp = ID2SYM(i_max_nesting);
1640 if (option_given_p(opts, tmp)) {
1641 VALUE max_nesting = rb_hash_aref(opts, tmp);
1642 if (RTEST(max_nesting)) {
1643 Check_Type(max_nesting, T_FIXNUM);
1644 json->max_nesting = FIX2INT(max_nesting);
1646 json->max_nesting = 0;
1649 json->max_nesting = 19;
1651 tmp = ID2SYM(i_allow_nan);
1652 if (option_given_p(opts, tmp)) {
1653 json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1655 json->allow_nan = 0;
1657 tmp = ID2SYM(i_symbolize_names);
1658 if (option_given_p(opts, tmp)) {
1659 json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
1661 json->symbolize_names = 0;
1663 tmp = ID2SYM(i_quirks_mode);
1664 if (option_given_p(opts, tmp)) {
1665 VALUE quirks_mode = rb_hash_aref(opts, tmp);
1666 json->quirks_mode = RTEST(quirks_mode) ? 1 : 0;
1668 json->quirks_mode = 0;
1670 tmp = ID2SYM(i_create_additions);
1671 if (option_given_p(opts, tmp)) {
1672 json->create_additions = RTEST(rb_hash_aref(opts, tmp));
1674 json->create_additions = 0;
1676 tmp = ID2SYM(i_create_id);
1677 if (option_given_p(opts, tmp)) {
1678 json->create_id = rb_hash_aref(opts, tmp);
1680 json->create_id = rb_funcall(mJSON, i_create_id, 0);
1682 tmp = ID2SYM(i_object_class);
1683 if (option_given_p(opts, tmp)) {
1684 json->object_class = rb_hash_aref(opts, tmp);
1686 json->object_class = Qnil;
1688 tmp = ID2SYM(i_array_class);
1689 if (option_given_p(opts, tmp)) {
1690 json->array_class = rb_hash_aref(opts, tmp);
1692 json->array_class = Qnil;
1694 tmp = ID2SYM(i_match_string);
1695 if (option_given_p(opts, tmp)) {
1696 VALUE match_string = rb_hash_aref(opts, tmp);
1697 json->match_string = RTEST(match_string) ? match_string : Qnil;
1699 json->match_string = Qnil;
1703 json->max_nesting = 19;
1704 json->allow_nan = 0;
1705 json->create_additions = 1;
1706 json->create_id = rb_funcall(mJSON, i_create_id, 0);
1707 json->object_class = Qnil;
1708 json->array_class = Qnil;
1710 if (!json->quirks_mode) {
1711 source = convert_encoding(StringValue(source));
1713 json->current_nesting = 0;
1714 json->len = RSTRING_LEN(source);
1715 json->source = RSTRING_PTR(source);;
1716 json->Vsource = source;
1721 #line 1722 "parser.c"
1722 static const int JSON_start = 1;
1723 static const int JSON_first_final = 10;
1724 static const int JSON_error = 0;
1726 static const int JSON_en_main = 1;
1729 #line 729 "parser.rl"
1732 static VALUE cParser_parse_strict(VALUE self)
1736 VALUE result = Qnil;
1740 #line 1741 "parser.c"
1745 #line 739 "parser.rl"
1749 #line 1750 "parser.c"
1766 if ( 9 <= (*p) && (*p) <= 10 )
1805 #line 718 "parser.rl"
1808 json->current_nesting = 1;
1809 np = JSON_parse_array(json, p, pe, &result);
1810 if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1814 #line 711 "parser.rl"
1817 json->current_nesting = 1;
1818 np = JSON_parse_object(json, p, pe, &result);
1819 if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1826 #line 1827 "parser.c"
1832 if ( 9 <= (*p) && (*p) <= 10 )
1868 _test_eof1: cs = 1; goto _test_eof;
1869 _test_eof2: cs = 2; goto _test_eof;
1870 _test_eof3: cs = 3; goto _test_eof;
1871 _test_eof4: cs = 4; goto _test_eof;
1872 _test_eof5: cs = 5; goto _test_eof;
1873 _test_eof10: cs = 10; goto _test_eof;
1874 _test_eof6: cs = 6; goto _test_eof;
1875 _test_eof7: cs = 7; goto _test_eof;
1876 _test_eof8: cs = 8; goto _test_eof;
1877 _test_eof9: cs = 9; goto _test_eof;
1883 #line 742 "parser.rl"
1885 if (cs >= JSON_first_final && p == pe) {
1888 rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
1895 #line 1896 "parser.c"
1896 static const int JSON_quirks_mode_start = 1;
1897 static const int JSON_quirks_mode_first_final = 10;
1898 static const int JSON_quirks_mode_error = 0;
1900 static const int JSON_quirks_mode_en_main = 1;
1903 #line 767 "parser.rl"
1906 static VALUE cParser_parse_quirks_mode(VALUE self)
1910 VALUE result = Qnil;
1914 #line 1915 "parser.c"
1916 cs = JSON_quirks_mode_start;
1919 #line 777 "parser.rl"
1923 #line 1924 "parser.c"
1948 if ( 48 <= (*p) && (*p) <= 57 )
1950 } else if ( (*p) >= 9 )
1957 #line 759 "parser.rl"
1959 char *np = JSON_parse_value(json, p, pe, &result);
1960 if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
1967 #line 1968 "parser.c"
1973 if ( 9 <= (*p) && (*p) <= 10 )
2041 _test_eof1: cs = 1; goto _test_eof;
2042 _test_eof10: cs = 10; goto _test_eof;
2043 _test_eof2: cs = 2; goto _test_eof;
2044 _test_eof3: cs = 3; goto _test_eof;
2045 _test_eof4: cs = 4; goto _test_eof;
2046 _test_eof5: cs = 5; goto _test_eof;
2047 _test_eof6: cs = 6; goto _test_eof;
2048 _test_eof7: cs = 7; goto _test_eof;
2049 _test_eof8: cs = 8; goto _test_eof;
2050 _test_eof9: cs = 9; goto _test_eof;
2056 #line 780 "parser.rl"
2058 if (cs >= JSON_quirks_mode_first_final && p == pe) {
2061 rb_raise(eParserError, "%u: unexpected token at '%s'", __LINE__, p);
2069 * Parses the current JSON text _source_ and returns the complete data
2070 * structure as a result.
2072 static VALUE cParser_parse(VALUE self)
2076 if (json->quirks_mode) {
2077 return cParser_parse_quirks_mode(self);
2079 return cParser_parse_strict(self);
2084 static JSON_Parser *JSON_allocate()
2086 JSON_Parser *json = ALLOC(JSON_Parser);
2087 MEMZERO(json, JSON_Parser, 1);
2091 static void JSON_mark(JSON_Parser *json)
2093 rb_gc_mark_maybe(json->Vsource);
2094 rb_gc_mark_maybe(json->create_id);
2095 rb_gc_mark_maybe(json->object_class);
2096 rb_gc_mark_maybe(json->array_class);
2097 rb_gc_mark_maybe(json->match_string);
2100 static void JSON_free(JSON_Parser *json)
2105 static VALUE cJSON_parser_s_allocate(VALUE klass)
2107 JSON_Parser *json = JSON_allocate();
2108 return Data_Wrap_Struct(klass, JSON_mark, JSON_free, json);
2112 * call-seq: source()
2114 * Returns a copy of the current _source_ string, that was used to construct
2117 static VALUE cParser_source(VALUE self)
2120 return rb_str_dup(json->Vsource);
2124 * call-seq: quirks_mode?()
2126 * Returns a true, if this parser is in quirks_mode, false otherwise.
2128 static VALUE cParser_quirks_mode_p(VALUE self)
2131 return json->quirks_mode ? Qtrue : Qfalse;
2137 rb_require("json/common");
2138 mJSON = rb_define_module("JSON");
2139 mExt = rb_define_module_under(mJSON, "Ext");
2140 cParser = rb_define_class_under(mExt, "Parser", rb_cObject);
2141 eParserError = rb_path2class("JSON::ParserError");
2142 eNestingError = rb_path2class("JSON::NestingError");
2143 rb_define_alloc_func(cParser, cJSON_parser_s_allocate);
2144 rb_define_method(cParser, "initialize", cParser_initialize, -1);
2145 rb_define_method(cParser, "parse", cParser_parse, 0);
2146 rb_define_method(cParser, "source", cParser_source, 0);
2147 rb_define_method(cParser, "quirks_mode?", cParser_quirks_mode_p, 0);
2149 CNaN = rb_const_get(mJSON, rb_intern("NaN"));
2150 CInfinity = rb_const_get(mJSON, rb_intern("Infinity"));
2151 CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity"));
2153 i_json_creatable_p = rb_intern("json_creatable?");
2154 i_json_create = rb_intern("json_create");
2155 i_create_id = rb_intern("create_id");
2156 i_create_additions = rb_intern("create_additions");
2157 i_chr = rb_intern("chr");
2158 i_max_nesting = rb_intern("max_nesting");
2159 i_allow_nan = rb_intern("allow_nan");
2160 i_symbolize_names = rb_intern("symbolize_names");
2161 i_quirks_mode = rb_intern("quirks_mode");
2162 i_object_class = rb_intern("object_class");
2163 i_array_class = rb_intern("array_class");
2164 i_match = rb_intern("match");
2165 i_match_string = rb_intern("match_string");
2166 i_key_p = rb_intern("key?");
2167 i_deep_const_get = rb_intern("deep_const_get");
2168 i_aset = rb_intern("[]=");
2169 i_leftshift = rb_intern("<<");
2170 #ifdef HAVE_RUBY_ENCODING_H
2171 CEncoding_UTF_8 = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-8"));
2172 CEncoding_UTF_16BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16be"));
2173 CEncoding_UTF_16LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-16le"));
2174 CEncoding_UTF_32BE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32be"));
2175 CEncoding_UTF_32LE = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("utf-32le"));
2176 CEncoding_ASCII_8BIT = rb_funcall(rb_path2class("Encoding"), rb_intern("find"), 1, rb_str_new2("ascii-8bit"));
2177 i_encoding = rb_intern("encoding");
2178 i_encode = rb_intern("encode");
2180 i_iconv = rb_intern("iconv");
2187 * c-file-style: ruby
2188 * indent-tabs-mode: nil