3 STRING_ITERATOR(_json, string_null, 0);
4 // Store interleaved keys/values in a string buffer
9 /** parse a json object */
10 bool _json_parse_object();
11 bool _json_parse_members();
12 bool _json_parse_pair();
13 bool _json_parse_array();
14 bool _json_parse_value();
15 bool _json_parse_true();
16 bool _json_parse_false();
17 bool _json_parse_null();
18 bool _json_parse_string(bool add);
19 bool _json_parse_number();
20 bool _json_parse_float();
21 bool _json_parse_int();
23 #define JSON_BEGIN() int __i = STRING_ITERATOR_SAVE(_json)
24 #define JSON_FAIL(reason) goto fail
28 STRING_ITERATOR_LOAD(_json, __i); \
35 bool _json_parse_object() {
37 if (STRING_ITERATOR_GET(_json) != '{') JSON_FAIL("expected '{'");
38 WITH(int, _json_keys, bufstr_add(_json_buffer, "", 0), _json_parse_members());
39 if (STRING_ITERATOR_GET(_json) != '}') JSON_FAIL("expected '}'");
43 bool _json_parse_members() {
46 if (!_json_parse_pair()) JSON_FAIL("expected pair");
47 if (STRING_ITERATOR_PEEK(_json) == ',') {
48 STRING_ITERATOR_NEXT(_json);
56 bool _json_parse_pair() {
58 if (!_json_parse_string(false)) JSON_FAIL("expected string");
59 string key = _json_temp;
60 bufstr_set(_json_buffer, _json_keys, cons(bufstr_get(_json_buffer, _json_keys), key));
61 key = _json_ns ? strcat(_json_ns, ".", key) : key;
62 bufstr_add(_json_buffer, key, 0);
63 if (STRING_ITERATOR_GET(_json) != ':') JSON_FAIL("expected ':'");
64 bool ret = false; WITH(string, _json_ns, key, ret = _json_parse_value());
65 if (!ret) JSON_FAIL("expected value");
69 bool _json_parse_array() {
71 if (STRING_ITERATOR_GET(_json) != '[') JSON_FAIL("expected '['");
72 int len = bufstr_add(_json_buffer, "0", 0);
73 if (len) bufstr_set(_json_buffer, len - 1, strcat(bufstr_get(_json_buffer, len - 1), ".length"));
74 bool required = false;
75 for (int n = 0; ; n++) {
77 key = _json_ns ? strcat(_json_ns, ".", key) : key;
78 int it = bufstr_add(_json_buffer, key, 0);
79 bool ret = false; WITH(string, _json_ns, key, ret = _json_parse_value());
81 bufstr_free(_json_buffer, it);
82 if (required) JSON_FAIL("expected value"); else break;
84 bufstr_set(_json_buffer, len, ftos(n + 1));
85 if (STRING_ITERATOR_PEEK(_json) == ',') {
86 STRING_ITERATOR_NEXT(_json);
92 if (STRING_ITERATOR_GET(_json) != ']') JSON_FAIL("expected ']'");
96 bool _json_parse_value() {
98 if (!(_json_parse_string(true)
99 || _json_parse_number()
100 || _json_parse_object()
101 || _json_parse_array()
102 || _json_parse_true()
103 || _json_parse_false()
104 || _json_parse_null())) JSON_FAIL("expected value");
108 bool _json_parse_true() {
110 if (!(STRING_ITERATOR_GET(_json) == 't'
111 && STRING_ITERATOR_GET(_json) == 'r'
112 && STRING_ITERATOR_GET(_json) == 'u'
113 && STRING_ITERATOR_GET(_json) == 'e'))
114 JSON_FAIL("expected 'true'");
115 bufstr_add(_json_buffer, "1", 0);
119 bool _json_parse_false() {
121 if (!(STRING_ITERATOR_GET(_json) == 'f'
122 && STRING_ITERATOR_GET(_json) == 'a'
123 && STRING_ITERATOR_GET(_json) == 'l'
124 && STRING_ITERATOR_GET(_json) == 's'
125 && STRING_ITERATOR_GET(_json) == 'e'))
126 JSON_FAIL("expected 'false'");
127 bufstr_add(_json_buffer, "0", 0);
131 bool _json_parse_null() {
133 if (!(STRING_ITERATOR_GET(_json) == 'n'
134 && STRING_ITERATOR_GET(_json) == 'u'
135 && STRING_ITERATOR_GET(_json) == 'l'
136 && STRING_ITERATOR_GET(_json) == 'l'))
137 JSON_FAIL("expected 'null'");
138 bufstr_add(_json_buffer, "", 0);
142 bool _json_parse_string(bool add) {
144 if (STRING_ITERATOR_GET(_json) != '"') JSON_FAIL("expected opening '\"'");
146 for (int c; (c = STRING_ITERATOR_GET(_json)); ) {
148 STRING_ITERATOR_UNGET(_json);
150 } else if (c == '\\') {
152 switch (STRING_ITERATOR_GET(_json)) {
154 JSON_FAIL("expected ( '\"' | '\\' | 'n' | 't' )");
155 case '"': esc = "\""; break;
156 case '\\': esc = "\\"; break;
157 case 'n': esc = "\n"; break;
158 case 't': esc = "\t"; break;
159 case 'u': esc = "\\u"; break; // TODO
160 case '/': esc = "/"; break;
164 s = strcat(s, chr2str(c));
167 if (STRING_ITERATOR_GET(_json) != '"') JSON_FAIL("expected closing '\"'");
168 if (add) bufstr_add(_json_buffer, s, 0);
173 bool _json_parse_number() {
175 if (!(_json_parse_float() || _json_parse_int())) JSON_FAIL("expected number");
179 bool _json_parse_float() {
183 for (int c; (c = STRING_ITERATOR_GET(_json)); ) {
184 if (!(c >= '0' && c <= '9')) {
185 if (c == '.' && needdot) {
189 STRING_ITERATOR_UNGET(_json);
193 s = strcat(s, chr2str(c));
195 if (s == "") JSON_FAIL("expected float");
196 bufstr_add(_json_buffer, s, 0);
200 bool _json_parse_int() {
203 for (int c; (c = STRING_ITERATOR_GET(_json)); ) {
204 if (!(c >= '0' && c <= '9')) {
205 STRING_ITERATOR_UNGET(_json);
208 if (s == "" && c == '0') JSON_FAIL("expected [1-9]");
209 s = strcat(s, chr2str(c));
211 if (s == "") JSON_FAIL("expected int");
212 if (ftos(stof(s)) != s) JSON_FAIL("expected int");
213 bufstr_add(_json_buffer, s, 0);
217 int json_parse(string in, bool() func) {
220 int o = strstrofs(in, "\"", 0);
222 string part = substring(in, 0, o + 1); in = substring(in, o + 1, -1);
223 part = strreplace(" ", "", part);
224 part = strreplace("\n", "", part);
225 trimmed = strcat(trimmed, part);
229 part = strreplace(" ", "", part);
230 part = strreplace("\n", "", part);
231 trimmed = strcat(trimmed, part);
236 int o = strstrofs(in, "\"", 0);
237 int esc = strstrofs(in, "\\\"", 0);
238 if (o < esc || esc < 0) {
240 string part = substring(in, 0, o + 1); in = substring(in, o + 1, -1);
241 trimmed = strcat(trimmed, part);
245 string part = substring(in, 0, esc + 2); in = substring(in, esc + 2, -1);
246 trimmed = strcat(trimmed, part);
252 STRING_ITERATOR_SET(_json, trimmed, 0);
253 _json_buffer = buf_create();
256 buf_del(_json_buffer);
262 string json_get(int buf, string key)
264 for (int i = 1, n = buf_getsize(buf); i < n; i += 2) {
265 if (bufstr_get(buf, i) == key) return bufstr_get(buf, i + 1);
270 void json_del(int buf)
275 void json_dump(int buf)
277 for (int i = 0, n = buf_getsize(buf); i < n; ++i) {
278 print(bufstr_get(buf, i), "\n");
289 \"m_string\": \"\\\"string\\\"\",\n\
294 \"m_arr\": [ ]\n}"; // "
296 int buf = json_parse(s, _json_parse_object);