json_parser.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. //
  2. // json_parser.cpp
  3. // json
  4. //
  5. // Created by Sam Jaffe on 4/24/16.
  6. //
  7. #include <iostream>
  8. #include "json.hpp"
  9. #include "json_common.hpp"
  10. namespace json { namespace {
  11. void parse_object(value& json, char const*& data);
  12. void parse_array(value& json, char const*& data);
  13. void parse_one_token(value& json, char const*& data);
  14. void parse_one_token(value& json, char const*& data) {
  15. const char ch = helper::get_next_element(data);
  16. if (ch == '{') {
  17. parse_object(json, ++data);
  18. } else if (ch == '[') {
  19. parse_array(json, ++data);
  20. } else if (ch == '"') {
  21. helper::parse_string(json, ++data);
  22. } else if (!strncmp(data, "true", 4)) {
  23. json = true;
  24. } else if (!strncmp(data, "false", 5)) {
  25. json = false;
  26. } else {
  27. helper::parse_numeric(json, data);
  28. }
  29. }
  30. void parse_object(value& json, char const*& data) {
  31. std::string key;
  32. while (*data && *data != '}') {
  33. helper::parse_string(key, data);
  34. if (helper::get_next_element(data) != ':') {
  35. throw malformed_json_exception(std::string("Expected key:value pair delimited by ':', got '") + *data + "' instead");
  36. }
  37. parse_one_token(json[key], ++data);
  38. helper::advance_to_boundary('}', data);
  39. }
  40. if (*data) ++data;
  41. else throw malformed_json_exception("Reached end of parse string without finding object end");
  42. }
  43. void parse_array(value& json, char const*& data) {
  44. size_t current_idx = 0;
  45. while (*data && *data != ']') {
  46. parse_one_token(json[current_idx++], data);
  47. helper::advance_to_boundary(']', data);
  48. }
  49. if (*data) ++data;
  50. else throw malformed_json_exception("Reached end of parse string without finding array end");
  51. }
  52. } }
  53. namespace json {
  54. namespace parser {
  55. void parse(json::value& json, char const* data) {
  56. parse_one_token(json, data);
  57. if (*data) throw malformed_json_exception("Expected a single json token in top-level parse");
  58. }
  59. void parse(json::value& json, std::istream & in) {
  60. in.seekg(0, std::ios_base::end);
  61. size_t end = in.tellg();
  62. std::unique_ptr<char[]> data{new char[end]};
  63. in.seekg(0);
  64. in.read(data.get(), end);
  65. parse(json, data.get());
  66. }
  67. }
  68. }
  69. void json::value::parse(char const* data) {
  70. json::parser::parse(*this, data);
  71. }
  72. void json::value::parse(std::string const& str) {
  73. json::parser::parse(*this, str.c_str());
  74. }
  75. void json::value::parse(std::istream & in) {
  76. json::parser::parse(*this, in);
  77. }