void ParsedJson::_parse(const string& str) { _json = str; _values.clear(); auto v = _add_value(); int end = _rec_parse(0,v); if(end != _json.size()) _parse_error(end,"_json not closed"); }
static void _add_value(void *tbl[], uint16_t a, int lvl, void *data) { int a3 = SUB_TABLE(a, lvl); if (lvl == 0) { tbl[a3] = data; } else { if (tbl[a3] == NULL) { tbl[a3] = _rtr_alloc_table(tbl); } _add_value(tbl[a3], a, lvl - 1, data); } }
void rtr_add_value(void *tbl[], uint16_t a, void *data) { gb_debug("%s(%p, 0x%04x, %p)\n", __func__, tbl, a, data); _add_value(tbl, a, LEVELS - 1, data); }
int ParsedJson::_rec_parse(int v, int cur) { cur = _skipws(cur); if(cur >= _json.length()) return cur; _values[v].start = cur; if(_json[cur] == '{') { cur++; cur = _skipws(cur); while(_json[cur] != '}') { cur = _skipws(cur); if(_json[cur] != '\"') _parse_error(cur, "string expected"); auto n = _add_value(); _add_child(v, n); cur = _rec_parse(n,cur); cur = _skipws(cur); if(_json[cur] != ':') _parse_error(cur, ": expected"); cur++; cur = _skipws(cur); auto m = _add_value(); _add_child(v, m); cur = _rec_parse(m,cur); cur = _skipws(cur); if(_json[cur] != '}' and _json[cur] != ',') _parse_error(cur,"} or , expected"); if(_json[cur] == ',') cur++; cur = _skipws(cur); } _values[v].end = cur; } else if(_json[cur] == '[') { cur++; cur = _skipws(cur); while(_json[cur] != ']') { cur = _skipws(cur); auto m = _add_value(); _add_child(v, m); cur = _rec_parse(m,cur); cur = _skipws(cur); if(_json[cur] != ']' and _json[cur] != ',') _parse_error(cur,"] or , expected"); if(_json[cur] == ',') cur++; cur = _skipws(cur); } cur = _skipws(cur); } else if(_json[cur] == 't') { _check(cur,"true",4); cur += 3; } else if(_json[cur] == 'f') { _check(cur,"false",5); cur += 4; } else if(_json[cur] == 'n') { _check(cur,"null",4); cur += 3; } else if(_json[cur] == '"') { cur++; while(_json[cur] != '"') { if(_json[cur] == '\\') { cur++; if(_json[cur] == 'u') { _parse_error(cur, "unsupported unicode strings"); } else if(_json[cur] != '"' and _json[cur] != '\\' and _json[cur] != '/' and _json[cur] != 't' and _json[cur] != 'n' and _json[cur] != 'r' and _json[cur] != 'b' and _json[cur] != 'f') { _parse_error(cur, "unsupported string escapes"); } else { _parse_error(cur, "unknown string escape"); } } cur++; } } else if(_json[cur] == '+' or _json[cur] == '-' or isdigit(_json[cur])) { if(_json[cur] == '+' or _json[cur] == '-') cur++; while(isdigit(_json[cur])) cur++; if(_json[cur] == '.') { cur++; while(isdigit(_json[cur])) cur++; } if(_json[cur] == 'e' or _json[cur] == 'E') { cur++; if(_json[cur] == '+' or _json[cur] == '-') cur++; while(isdigit(_json[cur])) cur++; } cur--; } else _parse_error(cur, "unknown token type"); _values[v].end = cur; cur++; cur = _skipws(cur); return cur; }