// // json_binder_discard.cpp // json // // Created by Sam Jaffe on 7/29/16. // #include "json_common.hpp" #include "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 { 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_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(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 malformed_json_exception("Reached end of parse string without finding array end"); } } } 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 ); } }