json_common.cpp 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. //
  2. // json_binder.cpp
  3. // json
  4. //
  5. // Created by Sam Jaffe on 4/23/16.
  6. //
  7. #include "json_common.hpp"
  8. namespace json {
  9. namespace helper {
  10. namespace {
  11. std::string get_no_end_error(char expected, char found) {
  12. char str[64] = { '\0' };
  13. snprintf(str, sizeof(str),
  14. "Expected delimeter: ',' or '%c', got '%c' instead",
  15. expected, found);
  16. return str;
  17. }
  18. }
  19. numeric_token_info::numeric_token_info(char const * start)
  20. : val(0)
  21. , it(start)
  22. , end(start)
  23. , is_double(false)
  24. , is_negative(*start == '-') {
  25. if ( is_negative ) { ++it; ++end; }
  26. for (char c = *end;
  27. strchr(",]}", c) == NULL && !isspace(c);
  28. c = *++end) {
  29. is_double |= !isdigit(*end);
  30. }
  31. if (end == it) {
  32. throw malformed_json_exception("Expected any token, got nothing");
  33. }
  34. }
  35. numeric_state numeric_token_info::parse_numeric() {
  36. static uint_jt const threshold = (UINT_JT_MAX / 10);
  37. val = 0;
  38. for (char c = *it; it != end; c = *++it) {
  39. int_jt digit = static_cast<int_jt>(c - '0');
  40. if (val > threshold ||
  41. ( val == threshold && ((it + 1) < end ||
  42. digit > INT_JT_MAX_LAST_DIGIT))) {
  43. return DOUBLE;
  44. }
  45. val = (10 * val) + digit;
  46. }
  47. return INTEGER;
  48. }
  49. const char get_next_element(char const*& data) {
  50. while (isspace(*data)) ++data;
  51. return *data;
  52. }
  53. void advance_to_boundary(char const endtok, char const*& data) {
  54. char const next = get_next_element(data);
  55. if (next == ',') {
  56. ++data;
  57. } else if (next != endtok) {
  58. throw json::malformed_json_exception(get_no_end_error(endtok, *data));
  59. }
  60. }
  61. std::string parse_string(char const * & data) {
  62. char const* start = data;
  63. while (*++data) {
  64. if (*data == '"' && *(data-1) != '\\') {
  65. return std::string(start+1, data++);
  66. }
  67. }
  68. throw json::malformed_json_exception("Could not locate end of string");
  69. }
  70. }
  71. }