// // json_binder_discard.cpp // json // // Created by Sam Jaffe on 7/29/16. // #include "json/json_common.hpp" #include "json/binder/json_binder_discard.hpp" #include namespace json { namespace { struct discard_t { template discard_t & operator=(T const &) { return *this; } template discard_t & operator[](T const &) { return *this; } }; }} namespace json { namespace helper { template <> void parse_numeric(json::discard_t &, char const *& data); template <> json::discard_t parse_double_impl(const char * begin, const char *& end); }} namespace json { namespace { void parse_object(discard_t & json, char const *& data); void parse_array(discard_t & json, char const *& data); void parse_one_token(discard_t & json, char const *& data); void parse_one_token(discard_t & 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; data += 4; } else if (!strncmp(data, "false", 5)) { json = false; data += 5; } else if (!strncmp(data, "null", 4)) { data += 4; } else { helper::parse_numeric(json, data); } } void parse_object(discard_t & json, char const *& data) { std::string key; while (*data && *data != '}') { helper::parse_string(key, data); if (helper::get_next_element(data) != ':') { throw malformed_object_association(*data); } parse_one_token(json[key], ++data); helper::advance_to_boundary('}', data); } if (*data) { ++data; } else { throw unterminated_json_object(); } } void parse_array(discard_t & 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 unterminated_json_array(); } } }} namespace json { namespace helper { template <> discard_t parse_double_impl(const char * begin, const char *& end) { std::strtod(begin, const_cast(&end)); errno = 0; return {}; } template <> void parse_numeric(discard_t & d, char const *& data) { numeric_token_info info = data; if (info.is_double || info.parse_numeric() == DOUBLE) { helper::parse_double(d, data); } else { data = info.it; } } }} namespace json { void parse_discard_token(char const *& data) { json::discard_t tmp; parse_one_token(tmp, data); } }