Warning: session_start(): open(/var/lib/php/sessions/sess_h7kbitc6pfdfl91e0a8jv09vak, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
scope jsonDecode
sO jsonDecode(S text) {
ret new Y(text).parse();
}
// the miraculous class Y
sclass #Y {
S text;
LS tok;
bool useOrderedMaps;
int i = 1;
*(S *text) {
tok = jsonTok(text);
}
swappable RuntimeException fail(S msg) { ret main fail(msg); }
O parse() {
if (l(tok) == 1) null;
ret parseExpr();
}
O parseExpr() {
String t = tok.get(i);
if (t.startsWith("\"") || t.startsWith("'")) {
String s = unquote(tok.get(i));
i += 2;
return s;
}
if (t.equals("{"))
return parseMap();
if (t.equals("["))
return this.parseList(); // avoid loading standard function "parseList"
if (t.equals("null")) {
i += 2; return null;
}
if (t.equals("false")) {
i += 2; return false;
}
if (t.equals("true")) {
i += 2; return true;
}
bool minus = false;
if (t.equals("-")) {
minus = true;
i += 2;
t = get(tok, i);
}
if (isInteger(t)) {
int j = i;
i += 2;
if (eqOneOf(get(tok, i), ".", "e", "E")) {
// rough parsing for doubles
while (isInteger(get(tok, i))
|| eqOneOf(get(tok, i), ".", "e", "E", "-"))
i += 2;
double d = parseDouble(joinSubList(tok, j, i-1));
if (minus) d = -d;
ret d;
} else {
long l = parseLong(t);
ret boxedIntOrLong(minus ? -l : l);
}
}
fail("Unknown token " + (i+1) + ": " + t + ": " + text);
}
Object parseList() {
consume("[");
List list = new ArrayList;
while (!tok.get(i).equals("]")) {
list.add(parseExpr());
if (tok.get(i).equals(",")) i += 2;
}
consume("]");
return list;
}
Object parseMap() {
consume("{");
Map map = useOrderedMaps ? new LinkedHashMap : new TreeMap;
while (!tok.get(i).equals("}")) {
String key = unquote(tok.get(i));
i += 2;
consume(":");
Object value = parseExpr();
map.put(key, value);
if (tok.get(i).equals(",")) i += 2;
}
consume("}");
return map;
}
void consume(String s) {
if (!tok.get(i).equals(s)) {
S prevToken = i-2 >= 0 ? tok.get(i-2) : "";
S nextTokens = join(tok.subList(i, Math.min(i+4, tok.size())));
fail(quote(s) + " expected: " + prevToken + " " + nextTokens + " (" + i + "/" + tok.size() + ")");
}
i += 2;
}
}