3#include "../fbuffer/fbuffer.h"
6#if defined HAVE_RUBY_ENCODING_H
7# define EXC_ENCODING rb_utf8_encoding(),
8# ifndef HAVE_RB_ENC_RAISE
21# define rb_enc_raise enc_raise
25# define rb_enc_raise rb_raise
30static const signed char digit_values[256] = {
31 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
32 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
33 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1,
34 -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1,
35 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
36 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
37 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
38 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
39 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
40 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
41 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
42 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
43 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
44 -1, -1, -1, -1, -1, -1, -1
47static UTF32 unescape_unicode(
const unsigned char *p)
51 b = digit_values[p[0]];
53 result = (result << 4) | (
unsigned char)b;
54 b = digit_values[p[1]];
56 result = (result << 4) | (
unsigned char)b;
57 b = digit_values[p[2]];
59 result = (result << 4) | (
unsigned char)b;
60 b = digit_values[p[3]];
62 result = (result << 4) | (
unsigned char)b;
66static int convert_UTF32_to_UTF8(
char *
buf,
UTF32 ch)
71 }
else if (ch <= 0x07FF) {
72 buf[0] = (char) ((ch >> 6) | 0xC0);
73 buf[1] = (char) ((ch & 0x3F) | 0x80);
75 }
else if (ch <= 0xFFFF) {
76 buf[0] = (char) ((ch >> 12) | 0xE0);
77 buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80);
78 buf[2] = (char) ((ch & 0x3F) | 0x80);
80 }
else if (ch <= 0x1fffff) {
81 buf[0] =(char) ((ch >> 18) | 0xF0);
82 buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80);
83 buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80);
84 buf[3] =(char) ((ch & 0x3F) | 0x80);
92static VALUE mJSON, mExt, cParser, eParserError, eNestingError;
93static VALUE CNaN, CInfinity, CMinusInfinity;
95static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
96 i_chr, i_max_nesting, i_allow_nan, i_symbolize_names,
97 i_object_class, i_array_class, i_decimal_class, i_key_p,
98 i_deep_const_get, i_match, i_match_string, i_aset, i_aref,
99 i_leftshift, i_new, i_try_convert, i_freeze, i_uminus;
117static char *JSON_parse_object(
JSON_Parser *json,
char *p,
char *pe,
VALUE *result,
int current_nesting)
124 rb_raise(eNestingError,
"nesting of %d is too deep", current_nesting);
161 if ( 9 <= (*p) && (*p) <= 10 )
169 np = JSON_parse_string(json, p, pe, &last_name);
171 if (np ==
NULL) { p--; {p++; cs = 3;
goto _out;} }
else {p = (( np))-1;}
185 if ( 9 <= (*p) && (*p) <= 10 )
239 if ( 48 <= (*p) && (*p) <= 57 )
241 }
else if ( (*p) >= 9 )
248 char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
250 p--; {p++; cs = 9;
goto _out;}
274 if ( 9 <= (*p) && (*p) <= 10 )
287 if ( 9 <= (*p) && (*p) <= 10 )
356 { p--; {p++; cs = 27;
goto _out;} }
429 _test_eof2: cs = 2;
goto _test_eof;
430 _test_eof3: cs = 3;
goto _test_eof;
431 _test_eof4: cs = 4;
goto _test_eof;
432 _test_eof5: cs = 5;
goto _test_eof;
433 _test_eof6: cs = 6;
goto _test_eof;
434 _test_eof7: cs = 7;
goto _test_eof;
435 _test_eof8: cs = 8;
goto _test_eof;
436 _test_eof9: cs = 9;
goto _test_eof;
437 _test_eof10: cs = 10;
goto _test_eof;
438 _test_eof11: cs = 11;
goto _test_eof;
439 _test_eof12: cs = 12;
goto _test_eof;
440 _test_eof13: cs = 13;
goto _test_eof;
441 _test_eof14: cs = 14;
goto _test_eof;
442 _test_eof15: cs = 15;
goto _test_eof;
443 _test_eof16: cs = 16;
goto _test_eof;
444 _test_eof17: cs = 17;
goto _test_eof;
445 _test_eof18: cs = 18;
goto _test_eof;
446 _test_eof27: cs = 27;
goto _test_eof;
447 _test_eof19: cs = 19;
goto _test_eof;
448 _test_eof20: cs = 20;
goto _test_eof;
449 _test_eof21: cs = 21;
goto _test_eof;
450 _test_eof22: cs = 22;
goto _test_eof;
451 _test_eof23: cs = 23;
goto _test_eof;
452 _test_eof24: cs = 24;
goto _test_eof;
453 _test_eof25: cs = 25;
goto _test_eof;
454 _test_eof26: cs = 26;
goto _test_eof;
470 if (!
NIL_P(klassname)) {
473 *result =
rb_funcall(klass, i_json_create, 1, *result);
496static char *JSON_parse_value(
JSON_Parser *json,
char *p,
char *pe,
VALUE *result,
int current_nesting)
533 if ( 48 <= (*p) && (*p) <= 57 )
535 }
else if ( (*p) >= 9 )
544 char *np = JSON_parse_string(json, p, pe, result);
545 if (np ==
NULL) { p--; {p++; cs = 29;
goto _out;} }
else {p = (( np))-1;}
554 *result = CMinusInfinity;
556 p--; {p++; cs = 29;
goto _out;}
561 np = JSON_parse_float(json, p, pe, result);
562 if (np !=
NULL) {p = (( np))-1;}
563 np = JSON_parse_integer(json, p, pe, result);
564 if (np !=
NULL) {p = (( np))-1;}
565 p--; {p++; cs = 29;
goto _out;}
572 np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
573 if (np ==
NULL) { p--; {p++; cs = 29;
goto _out;} }
else {p = (( np))-1;}
580 np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
581 if (np ==
NULL) { p--; {p++; cs = 29;
goto _out;} }
else {p = (( np))-1;}
627 { p--; {p++; cs = 29;
goto _out;} }
634 if ( 9 <= (*p) && (*p) <= 10 )
835 _test_eof1: cs = 1;
goto _test_eof;
836 _test_eof29: cs = 29;
goto _test_eof;
837 _test_eof2: cs = 2;
goto _test_eof;
838 _test_eof3: cs = 3;
goto _test_eof;
839 _test_eof4: cs = 4;
goto _test_eof;
840 _test_eof5: cs = 5;
goto _test_eof;
841 _test_eof6: cs = 6;
goto _test_eof;
842 _test_eof7: cs = 7;
goto _test_eof;
843 _test_eof8: cs = 8;
goto _test_eof;
844 _test_eof9: cs = 9;
goto _test_eof;
845 _test_eof10: cs = 10;
goto _test_eof;
846 _test_eof11: cs = 11;
goto _test_eof;
847 _test_eof12: cs = 12;
goto _test_eof;
848 _test_eof13: cs = 13;
goto _test_eof;
849 _test_eof14: cs = 14;
goto _test_eof;
850 _test_eof15: cs = 15;
goto _test_eof;
851 _test_eof16: cs = 16;
goto _test_eof;
852 _test_eof17: cs = 17;
goto _test_eof;
853 _test_eof18: cs = 18;
goto _test_eof;
854 _test_eof19: cs = 19;
goto _test_eof;
855 _test_eof20: cs = 20;
goto _test_eof;
856 _test_eof21: cs = 21;
goto _test_eof;
857 _test_eof22: cs = 22;
goto _test_eof;
858 _test_eof23: cs = 23;
goto _test_eof;
859 _test_eof24: cs = 24;
goto _test_eof;
860 _test_eof25: cs = 25;
goto _test_eof;
861 _test_eof26: cs = 26;
goto _test_eof;
862 _test_eof27: cs = 27;
goto _test_eof;
863 _test_eof28: cs = 28;
goto _test_eof;
894static char *JSON_parse_integer(
JSON_Parser *json,
char *p,
char *pe,
VALUE *result)
918 if ( 49 <= (*p) && (*p) <= 57 )
930 if ( 49 <= (*p) && (*p) <= 57 )
937 if ( 48 <= (*p) && (*p) <= 57 )
942 { p--; {p++; cs = 4;
goto _out;} }
954 if ( 48 <= (*p) && (*p) <= 57 )
958 _test_eof2: cs = 2;
goto _test_eof;
959 _test_eof3: cs = 3;
goto _test_eof;
960 _test_eof4: cs = 4;
goto _test_eof;
961 _test_eof5: cs = 5;
goto _test_eof;
973 fbuffer_append_char(json->
fbuffer,
'\0');
993static char *JSON_parse_float(
JSON_Parser *json,
char *p,
char *pe,
VALUE *result)
1003#line 366 "parser.rl"
1006#line 1021 "parser.c"
1017 if ( 49 <= (*p) && (*p) <= 57 )
1029 if ( 49 <= (*p) && (*p) <= 57 )
1046 if ( 48 <= (*p) && (*p) <= 57 )
1058 if ( 48 <= (*p) && (*p) <= 57 )
1060 }
else if ( (*p) >= 45 )
1064#line 340 "parser.rl"
1065 { p--; {p++; cs = 9;
goto _out;} }
1071#line 1086 "parser.c"
1081 if ( 48 <= (*p) && (*p) <= 57 )
1088 if ( 48 <= (*p) && (*p) <= 57 )
1100 if ( 48 <= (*p) && (*p) <= 57 )
1102 }
else if ( (*p) >= 45 )
1114 if ( 48 <= (*p) && (*p) <= 57 )
1118 _test_eof2: cs = 2;
goto _test_eof;
1119 _test_eof3: cs = 3;
goto _test_eof;
1120 _test_eof4: cs = 4;
goto _test_eof;
1121 _test_eof8: cs = 8;
goto _test_eof;
1122 _test_eof9: cs = 9;
goto _test_eof;
1123 _test_eof5: cs = 5;
goto _test_eof;
1124 _test_eof6: cs = 6;
goto _test_eof;
1125 _test_eof10: cs = 10;
goto _test_eof;
1126 _test_eof7: cs = 7;
goto _test_eof;
1132#line 368 "parser.rl"
1139 method_id = i_try_convert;
1146 const char *last_colon =
strrchr(name_cstr,
':');
1148 const char *mod_path_end = last_colon - 1;
1152 const char *method_name_beg = last_colon + 1;
1153 long before_len = method_name_beg - name_cstr;
1166 fbuffer_append_char(json->
fbuffer,
'\0');
1183#line 1173 "parser.c"
1191#line 421 "parser.rl"
1194static char *JSON_parse_array(
JSON_Parser *json,
char *p,
char *pe,
VALUE *result,
int current_nesting)
1200 rb_raise(eNestingError,
"nesting of %d is too deep", current_nesting);
1205#line 1195 "parser.c"
1210#line 434 "parser.rl"
1212#line 1202 "parser.c"
1245 if ( 48 <= (*p) && (*p) <= 57 )
1247 }
else if ( (*p) >= 9 )
1251#line 398 "parser.rl"
1254 char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
1256 p--; {p++; cs = 3;
goto _out;}
1271#line 1261 "parser.c"
1279 if ( 9 <= (*p) && (*p) <= 10 )
1301 if ( 48 <= (*p) && (*p) <= 57 )
1303 }
else if ( (*p) >= 9 )
1371#line 413 "parser.rl"
1372 { p--; {p++; cs = 17;
goto _out;} }
1378#line 1368 "parser.c"
1413 _test_eof2: cs = 2;
goto _test_eof;
1414 _test_eof3: cs = 3;
goto _test_eof;
1415 _test_eof4: cs = 4;
goto _test_eof;
1416 _test_eof5: cs = 5;
goto _test_eof;
1417 _test_eof6: cs = 6;
goto _test_eof;
1418 _test_eof7: cs = 7;
goto _test_eof;
1419 _test_eof8: cs = 8;
goto _test_eof;
1420 _test_eof9: cs = 9;
goto _test_eof;
1421 _test_eof10: cs = 10;
goto _test_eof;
1422 _test_eof11: cs = 11;
goto _test_eof;
1423 _test_eof12: cs = 12;
goto _test_eof;
1424 _test_eof17: cs = 17;
goto _test_eof;
1425 _test_eof13: cs = 13;
goto _test_eof;
1426 _test_eof14: cs = 14;
goto _test_eof;
1427 _test_eof15: cs = 15;
goto _test_eof;
1428 _test_eof16: cs = 16;
goto _test_eof;
1434#line 435 "parser.rl"
1444static VALUE json_string_unescape(
VALUE result,
char *
string,
char *stringEnd)
1446 char *p = string, *pe = string, *unescape;
1450 while (pe < stringEnd) {
1452 unescape = (
char *)
"?";
1457 unescape = (
char *)
"\n";
1460 unescape = (
char *)
"\r";
1463 unescape = (
char *)
"\t";
1466 unescape = (
char *)
"\"";
1469 unescape = (
char *)
"\\";
1472 unescape = (
char *)
"\b";
1475 unescape = (
char *)
"\f";
1478 if (pe > stringEnd - 4) {
1481 "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
1484 UTF32 ch = unescape_unicode((
unsigned char *) ++pe);
1488 if (pe > stringEnd - 6) {
1491 "%u: incomplete surrogate pair at '%s'", __LINE__, p
1494 if (pe[0] ==
'\\' && pe[1] ==
'u') {
1495 UTF32 sur = unescape_unicode((
unsigned char *) pe + 2);
1496 ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16)
1500 unescape = (
char *)
"?";
1504 unescape_len = convert_UTF32_to_UTF8(
buf, ch);
1523#line 1513 "parser.c"
1531#line 542 "parser.rl"
1546static char *JSON_parse_string(
JSON_Parser *json,
char *p,
char *pe,
VALUE *result)
1553#line 1543 "parser.c"
1558#line 563 "parser.rl"
1561#line 1551 "parser.c"
1582 if ( 0 <= (
signed char)(*p) && (*p) <= 31 )
1586#line 528 "parser.rl"
1588 *result = json_string_unescape(*result, json->
memo + 1, p);
1589 if (
NIL_P(*result)) {
1591 {p++; cs = 8;
goto _out;}
1597#line 539 "parser.rl"
1598 { p--; {p++; cs = 8;
goto _out;} }
1604#line 1594 "parser.c"
1612 if ( 0 <= (
signed char)(*p) && (*p) <= 31 )
1620 if ( 48 <= (*p) && (*p) <= 57 )
1622 }
else if ( (*p) > 70 ) {
1623 if ( 97 <= (*p) && (*p) <= 102 )
1633 if ( 48 <= (*p) && (*p) <= 57 )
1635 }
else if ( (*p) > 70 ) {
1636 if ( 97 <= (*p) && (*p) <= 102 )
1646 if ( 48 <= (*p) && (*p) <= 57 )
1648 }
else if ( (*p) > 70 ) {
1649 if ( 97 <= (*p) && (*p) <= 102 )
1659 if ( 48 <= (*p) && (*p) <= 57 )
1661 }
else if ( (*p) > 70 ) {
1662 if ( 97 <= (*p) && (*p) <= 102 )
1668 _test_eof2: cs = 2;
goto _test_eof;
1669 _test_eof8: cs = 8;
goto _test_eof;
1670 _test_eof3: cs = 3;
goto _test_eof;
1671 _test_eof4: cs = 4;
goto _test_eof;
1672 _test_eof5: cs = 5;
goto _test_eof;
1673 _test_eof6: cs = 6;
goto _test_eof;
1674 _test_eof7: cs = 7;
goto _test_eof;
1680#line 565 "parser.rl"
1689 *result =
rb_funcall(klass, i_json_create, 1, *result);
1695 }
else if (RB_TYPE_P(*result,
T_STRING)) {
1696# if STR_UMINUS_DEDUPE_FROZEN
1703# elif STR_UMINUS_DEDUPE
1734#ifdef HAVE_RUBY_ENCODING_H
1783#ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1789#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1798 if (
RTEST(max_nesting)) {
1807 tmp =
ID2SYM(i_allow_nan);
1813 tmp =
ID2SYM(i_symbolize_names);
1825 tmp =
ID2SYM(i_create_additions);
1833 "options :symbolize_names and :create_additions cannot be "
1834 " used in conjunction");
1836 tmp =
ID2SYM(i_create_id);
1842 tmp =
ID2SYM(i_object_class);
1848 tmp =
ID2SYM(i_array_class);
1854 tmp =
ID2SYM(i_decimal_class);
1860 tmp =
ID2SYM(i_match_string);
1867#ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
1888#line 1878 "parser.c"
1896#line 786 "parser.rl"
1913#line 1903 "parser.c"
1918#line 802 "parser.rl"
1922#line 1912 "parser.c"
1947 if ( 48 <= (*p) && (*p) <= 57 )
1949 }
else if ( (*p) >= 9 )
1956#line 778 "parser.rl"
1958 char *np = JSON_parse_value(json, p, pe, &result, 0);
1959 if (np ==
NULL) { p--; {p++; cs = 10;
goto _out;} }
else {p = (( np))-1;}
1966#line 1956 "parser.c"
1972 if ( 9 <= (*p) && (*p) <= 10 )
2040 _test_eof1: cs = 1;
goto _test_eof;
2041 _test_eof10: cs = 10;
goto _test_eof;
2042 _test_eof2: cs = 2;
goto _test_eof;
2043 _test_eof3: cs = 3;
goto _test_eof;
2044 _test_eof4: cs = 4;
goto _test_eof;
2045 _test_eof5: cs = 5;
goto _test_eof;
2046 _test_eof6: cs = 6;
goto _test_eof;
2047 _test_eof7: cs = 7;
goto _test_eof;
2048 _test_eof8: cs = 8;
goto _test_eof;
2049 _test_eof9: cs = 9;
goto _test_eof;
2055#line 805 "parser.rl"
2065static void JSON_mark(
void *
ptr)
2076static void JSON_free(
void *
ptr)
2083static size_t JSON_memsize(
const void *
ptr)
2089#ifdef NEW_TYPEDDATA_WRAPPER
2092 {JSON_mark, JSON_free, JSON_memsize,},
2093#ifdef RUBY_TYPED_FREE_IMMEDIATELY
2100static VALUE cJSON_parser_s_allocate(
VALUE klass)
2104 json->
fbuffer = fbuffer_alloc(0);
2122#ifdef HAVE_RB_EXT_RACTOR_SAFE
2149 i_json_creatable_p =
rb_intern(
"json_creatable?");
2150 i_json_create =
rb_intern(
"json_create");
2152 i_create_additions =
rb_intern(
"create_additions");
2154 i_max_nesting =
rb_intern(
"max_nesting");
2156 i_symbolize_names =
rb_intern(
"symbolize_names");
2157 i_object_class =
rb_intern(
"object_class");
2158 i_array_class =
rb_intern(
"array_class");
2159 i_decimal_class =
rb_intern(
"decimal_class");
2161 i_match_string =
rb_intern(
"match_string");
2163 i_deep_const_get =
rb_intern(
"deep_const_get");
2168 i_try_convert =
rb_intern(
"try_convert");
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_ary_entry(VALUE ary, long offset)
VALUE rb_cstr2inum(const char *str, int base)
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
rb_encoding * rb_utf8_encoding(void)
rb_encoding * rb_ascii8bit_encoding(void)
rb_encoding * rb_enc_get(VALUE obj)
char * strrchr(const char *, const char)
#define RSTRING_LEN(string)
#define RSTRING_PTR(string)
void ruby_xfree(void *x)
Deallocates a storage instance.
void rb_gc_mark_maybe(VALUE obj)
void rb_gc_register_mark_object(VALUE obj)
Inform the garbage collector that object is a live Ruby object that should not be moved.
#define UNI_REPLACEMENT_CHAR
#define UNI_SUR_HIGH_START
#define option_given_p(opts, key)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_define_module(const char *name)
VALUE rb_define_module_under(VALUE outer, const char *name)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
void rb_raise(VALUE exc, const char *fmt,...)
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
VALUE rb_convert_type(VALUE, int, const char *, const char *)
Converts an object into another type.
VALUE rb_mKernel
Kernel module.
VALUE rb_cObject
Object class.
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
double rb_cstr_to_dbl(const char *, int)
Parses a string representation of a floating point number.
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
VALUE rb_hash_aref(VALUE hash, VALUE key)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
VALUE rb_enc_vsprintf(rb_encoding *, const char *, va_list)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
void rb_ext_ractor_safe(bool flag)
VALUE rb_str_freeze(VALUE)
VALUE rb_str_resize(VALUE, long)
VALUE rb_str_substr(VALUE, long, long)
VALUE rb_str_buf_new(long)
VALUE rb_str_intern(VALUE)
VALUE rb_class_name(VALUE)
VALUE rb_const_get(VALUE, ID)
VALUE rb_path2class(const char *)
VALUE rb_path_to_class(VALUE)
int rb_respond_to(VALUE, ID)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
ID rb_intern(const char *)
@ JSON_integer_first_final
@ JSON_object_first_final
@ JSON_string_first_final
@ RUBY_TYPED_FREE_IMMEDIATELY
#define TypedData_Make_Struct(klass, type, data_type, sval)
VALUE rb_require(const char *)