json_common.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. //
  2. // json_common.h
  3. // json
  4. //
  5. // Created by Sam Jaffe on 4/22/16.
  6. //
  7. #pragma once
  8. #include <cstdint>
  9. #include <cstdlib>
  10. #include <stdexcept>
  11. #include <string>
  12. namespace json {
  13. using string_jt = std::string;
  14. using double_jt = double;
  15. using int_jt = int32_t;
  16. using uint_jt = uint32_t;
  17. using bool_jt = bool;
  18. class value;
  19. class malformed_json_exception :
  20. public std::domain_error {
  21. using std::domain_error::domain_error;
  22. };
  23. class unterminated_json_exception :
  24. public malformed_json_exception {
  25. using malformed_json_exception::malformed_json_exception;
  26. };
  27. namespace {
  28. const constexpr json::int_jt INT_JT_MAX = std::numeric_limits<json::int_jt>::max();
  29. const constexpr json::int_jt INT_JT_MAX_LAST_DIGIT = (INT_JT_MAX % 10);
  30. const constexpr json::int_jt INT_JT_MIN = std::numeric_limits<json::int_jt>::min();
  31. const constexpr json::uint_jt INT_JT_OVER = json::uint_jt(INT_JT_MAX) + 1;
  32. const constexpr json::uint_jt UINT_JT_MAX = json::uint_jt(0) - 1;
  33. // const constexpr json::uint_jt UINT_JT_MIN = 0;
  34. }
  35. }
  36. namespace json { namespace parser {
  37. enum options {
  38. allow_all = 0x00,
  39. disable_unknown_keys = 0x01,
  40. disable_concatenated_json_bodies = 0x02,
  41. disable_all = 0xFF,
  42. };
  43. } }
  44. namespace json { namespace helper {
  45. const char get_next_element(char const*& data);
  46. enum numeric_state {
  47. DOUBLE, INTEGER
  48. };
  49. struct numeric_token_info {
  50. numeric_token_info(char const * start);
  51. numeric_state parse_numeric();
  52. uint_jt val;
  53. char const * it;
  54. char const * end;
  55. bool is_double;
  56. bool is_negative;
  57. };
  58. numeric_token_info get_numeric_token_info(char const * it);
  59. /**
  60. * @throws json::malformed_json_exception
  61. */
  62. void advance_to_boundary(char const endtok, char const *& data);
  63. /**
  64. * @throws json::malformed_json_exception
  65. */
  66. std::string parse_string(char const * & data);
  67. template <typename T>
  68. void parse_string(T& json, char const * & data) {
  69. json = parse_string(data);
  70. }
  71. template <typename T>
  72. void parse_double(T& json, char const * & data) {
  73. json = atof(data);
  74. while (isdigit(*data)) { ++data; }
  75. if (*data == '.' || *data == 'e') { ++data; }
  76. while (isdigit(*data)) { ++data; }
  77. }
  78. // template <typename T>
  79. // void parse_integer(T& json, char const * & data) {
  80. // json = atoi(data);
  81. // while (isdigit(*data)) { ++data; }
  82. // }
  83. template <typename J>
  84. void parse_numeric(J & json, char const * & data) {
  85. numeric_token_info info = data;
  86. if ( info.is_double ) {
  87. helper::parse_double(json, data);
  88. } else if ( info.parse_numeric() == DOUBLE ) {
  89. helper::parse_double(json, data);
  90. } else {
  91. uint_jt const val = info.val;
  92. if (info.is_negative) {
  93. if (val == INT_JT_OVER) {
  94. json = INT_JT_MIN;
  95. } else {
  96. json = -int_jt(val);
  97. }
  98. } else if (val <= uint_jt(INT_JT_MAX)) {
  99. json = int_jt(val);
  100. } else {
  101. json = val;
  102. }
  103. data = info.it;
  104. }
  105. }
  106. }
  107. }