json_binder_discard.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. //
  2. // json_binder_discard.cpp
  3. // json
  4. //
  5. // Created by Sam Jaffe on 7/29/16.
  6. //
  7. #include "json/json_common.hpp"
  8. #include "json/binder/json_binder_discard.hpp"
  9. #include <cstring>
  10. namespace json { namespace {
  11. struct discard_t {
  12. template <typename T> discard_t & operator=(T const &) { return *this; }
  13. template <typename T> discard_t & operator[](T const &) { return *this; }
  14. };
  15. }}
  16. namespace json { namespace helper {
  17. template <>
  18. void parse_numeric<json::discard_t>(json::discard_t &, char const *& data);
  19. template <>
  20. json::discard_t parse_double_impl<json::discard_t>(const char * begin,
  21. const char *& end);
  22. }}
  23. namespace json { namespace {
  24. void parse_object(discard_t & json, char const *& data);
  25. void parse_array(discard_t & json, char const *& data);
  26. void parse_one_token(discard_t & json, char const *& data);
  27. void parse_one_token(discard_t & json, char const *& data) {
  28. const char ch = helper::get_next_element(data);
  29. if (ch == '{') {
  30. parse_object(json, ++data);
  31. } else if (ch == '[') {
  32. parse_array(json, ++data);
  33. } else if (ch == '"') {
  34. helper::parse_string(json, ++data);
  35. } else if (!strncmp(data, "true", 4)) {
  36. json = true;
  37. data += 4;
  38. } else if (!strncmp(data, "false", 5)) {
  39. json = false;
  40. data += 5;
  41. } else if (!strncmp(data, "null", 4)) {
  42. data += 4;
  43. } else {
  44. helper::parse_numeric(json, data);
  45. }
  46. }
  47. void parse_object(discard_t & json, char const *& data) {
  48. std::string key;
  49. while (*data && *data != '}') {
  50. helper::parse_string(key, data);
  51. if (helper::get_next_element(data) != ':') {
  52. throw malformed_object_association(*data);
  53. }
  54. parse_one_token(json[key], ++data);
  55. helper::advance_to_boundary('}', data);
  56. }
  57. if (*data) {
  58. ++data;
  59. } else {
  60. throw unterminated_json_object();
  61. }
  62. }
  63. void parse_array(discard_t & json, char const *& data) {
  64. size_t current_idx = 0;
  65. while (*data && *data != ']') {
  66. parse_one_token(json[current_idx++], data);
  67. helper::advance_to_boundary(']', data);
  68. }
  69. if (*data) {
  70. ++data;
  71. } else {
  72. throw unterminated_json_array();
  73. }
  74. }
  75. }}
  76. namespace json { namespace helper {
  77. template <>
  78. discard_t parse_double_impl<discard_t>(const char * begin,
  79. const char *& end) {
  80. std::strtod(begin, const_cast<char **>(&end));
  81. errno = 0;
  82. return {};
  83. }
  84. template <> void parse_numeric<discard_t>(discard_t & d, char const *& data) {
  85. numeric_token_info info = data;
  86. if (info.is_double || info.parse_numeric() == DOUBLE) {
  87. helper::parse_double(d, data);
  88. } else {
  89. data = info.it;
  90. }
  91. }
  92. }}
  93. namespace json {
  94. void parse_discard_token(char const *& data) {
  95. json::discard_t tmp;
  96. parse_one_token(tmp, data);
  97. }
  98. }