// // json_binder.cpp // json // // Created by Sam Jaffe on 4/23/16. // #include "json_common.hpp" namespace json { namespace helper { namespace { std::string get_no_end_error(char expected, char found) { char str[64] = { '\0' }; snprintf(str, sizeof(str), "Expected delimeter: ',' or '%c', got '%c' instead", expected, found); return str; } } numeric_token_info::numeric_token_info(char const * start) : val(0) , it(start) , end(start) , is_double(false) , is_negative(*start == '-') { if ( is_negative ) { ++it; ++end; } for (char c = *end; strchr(",]}", c) == NULL && !isspace(c); c = *++end) { is_double |= !isdigit(*end); } if (end == it) { throw unterminated_json_exception("Expected any token, got nothing"); } } numeric_state numeric_token_info::parse_numeric() { static uint_jt const threshold = (UINT_JT_MAX / 10); val = 0; for (char c = *it; it != end; c = *++it) { int_jt digit = static_cast(c - '0'); if (val > threshold || ( val == threshold && ((it + 1) < end || digit > INT_JT_MAX_LAST_DIGIT))) { return DOUBLE; } val = (10 * val) + digit; } return INTEGER; } const char get_next_element(char const*& data) { while (isspace(*data)) ++data; return *data; } void advance_to_boundary(char const endtok, char const*& data) { char const next = get_next_element(data); if (next == ',') { ++data; } else if (next != endtok) { throw json::unterminated_json_exception(get_no_end_error(endtok, *data)); } } int reverse_count(char const * data, char val) { int i = 0; while (*data-- == val) { ++i; } return i; } std::string replace_all(std::string && str, std::string const & from, std::string const & to) { std::string::size_type start_pos = 0; while((start_pos = str.find(from, start_pos)) != std::string::npos) { str.replace(start_pos, from.length(), to); start_pos += to.length(); // ... } return std::move(str); } std::string parse_string(char const * & data) { char const* start = data; while (*++data) { if (*data == '"' && (reverse_count(data-1, '\\') % 2) == 0) { return replace_all(std::string(start+1, data++), "\\\"", "\""); } } throw json::unterminated_json_exception("Could not locate end of string"); } } }