void JSONValue::FromBinary(Stream& source) { JSONType newType = (JSONType)source.Read<unsigned char>(); switch (newType) { case JSON_NULL: Clear(); break; case JSON_BOOL: *this = source.Read<bool>(); break; case JSON_NUMBER: *this = source.Read<double>(); break; case JSON_STRING: *this = source.Read<String>(); break; case JSON_ARRAY: { SetEmptyArray(); size_t num = source.ReadVLE(); for (size_t i = 0; i < num && !source.IsEof(); ++i) Push(source.Read<JSONValue>()); } break; case JSON_OBJECT: { SetEmptyObject(); size_t num = source.ReadVLE(); for (size_t i = 0; i < num && !source.IsEof(); ++i) { String key = source.Read<String>(); (*this)[key] = source.Read<JSONValue>(); } } break; default: break; } }
bool JSONValue::Parse(const char*& pos, const char*& end) { char c; // Handle comments for (;;) { if (!NextChar(c, pos, end, true)) return false; if (c == '/') { if (!NextChar(c, pos, end, false)) return false; if (c == '/') { // Skip until end of line if (!MatchChar('\n', pos, end)) return false; } else if (c == '*') { // Skip until end of comment if (!MatchChar('*', pos, end)) return false; if (!MatchChar('/', pos, end)) return false; } else return false; } else break; } if (c == '}' || c == ']') return false; else if (c == 'n') { SetNull(); return MatchString("ull", pos, end); } else if (c == 'f') { *this = false; return MatchString("alse", pos, end); } else if (c == 't') { *this = true; return MatchString("rue", pos, end); } else if (IsDigit(c) || c == '-') { --pos; *this = strtod(pos, const_cast<char**>(&pos)); return true; } else if (c == '\"') { SetType(JSON_STRING); return ReadJSONString(*(reinterpret_cast<String*>(&data)), pos, end, true); } else if (c == '[') { SetEmptyArray(); // Check for empty first if (!NextChar(c, pos, end, true)) return false; if (c == ']') return true; else --pos; for (;;) { JSONValue arrayValue; if (!arrayValue.Parse(pos, end)) return false; Push(arrayValue); if (!NextChar(c, pos, end, true)) return false; if (c == ']') break; else if (c != ',') return false; } return true; } else if (c == '{') { SetEmptyObject(); if (!NextChar(c, pos, end, true)) return false; if (c == '}') return true; else --pos; for (;;) { String key; if (!ReadJSONString(key, pos, end, false)) return false; if (!NextChar(c, pos, end, true)) return false; if (c != ':') return false; JSONValue objectValue; if (!objectValue.Parse(pos, end)) return false; (*this)[key] = objectValue; if (!NextChar(c, pos, end, true)) return false; if (c == '}') break; else if (c != ',') return false; } return true; } return false; }