// // json_parser.cpp // json // // Created by Sam Jaffe on 4/24/16. // #include #include "json.hpp" #include "json_common.hpp" namespace json { namespace { void parse_object(value& json, char const*& data); void parse_array(value& json, char const*& data); void parse_one_token(value& json, char const*& data); void parse_one_token(value& json, char const*& data) { const char ch = helper::get_next_element(data); if (ch == '{') { parse_object(json, ++data); } else if (ch == '[') { parse_array(json, ++data); } else if (ch == '"') { helper::parse_string(json, ++data); } else if (!strncmp(data, "true", 4)) { json = true; } else if (!strncmp(data, "false", 5)) { json = false; } else { helper::parse_numeric(json, data); } } void parse_object(value& json, char const*& data) { std::string key; while (*data && *data != '}') { helper::parse_string(key, data); if (helper::get_next_element(data) != ':') { throw malformed_json_exception(std::string("Expected key:value pair delimited by ':', got '") + *data + "' instead"); } parse_one_token(json[key], ++data); helper::advance_to_boundary('}', data); } if (*data) ++data; else throw malformed_json_exception("Reached end of parse string without finding object end"); } void parse_array(value& json, char const*& data) { size_t current_idx = 0; while (*data && *data != ']') { parse_one_token(json[current_idx++], data); helper::advance_to_boundary(']', data); } if (*data) ++data; else throw malformed_json_exception("Reached end of parse string without finding array end"); } } } namespace json { namespace parser { void parse(json::value& json, char const* data) { parse_one_token(json, data); if (*data) throw malformed_json_exception("Expected a single json token in top-level parse"); } void parse(json::value& json, std::istream & in) { in.seekg(0, std::ios_base::end); size_t end = in.tellg(); std::unique_ptr data{new char[end]}; in.seekg(0); in.read(data.get(), end); parse(json, data.get()); } } } void json::value::parse(char const* data) { json::parser::parse(*this, data); } void json::value::parse(std::string const& str) { json::parser::parse(*this, str.c_str()); } void json::value::parse(std::istream & in) { json::parser::parse(*this, in); }