| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- //
- // 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<int_jt>(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");
- }
- }
- }
|