json_common.h 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. //
  2. // json_common.h
  3. // json
  4. //
  5. // Created by Sam Jaffe on 4/22/16.
  6. //
  7. #pragma once
  8. #include <cstdlib>
  9. #include <stdexcept>
  10. #include <string>
  11. namespace json {
  12. class malformed_json_exception : public std::domain_error {
  13. using std::domain_error::domain_error;
  14. };
  15. }
  16. namespace json {
  17. namespace helper {
  18. const char get_next_element(char const*& data) {
  19. while (isspace(*data)) ++data;
  20. return *data;
  21. }
  22. template <char const E>
  23. void advance_to_boundary(char const*& data) {
  24. switch (get_next_element(data)) {
  25. case ',': // This is there 'more data remains' token for the compound value
  26. ++data;
  27. break;
  28. case E: // This is the end-token for the compound value
  29. break;
  30. default: // Error, malformed JSON
  31. throw json::malformed_json_exception(std::string("Expected to recieve container delimiter ',' or '") + E + "', got '" + *data + "' instead");
  32. break;
  33. }
  34. }
  35. template <typename T>
  36. void parse_string(T& json, char const*& data) {
  37. char const* start = data;
  38. while (*++data) {
  39. if (*data == '"' && *(data-1) != '\\') {
  40. json = std::string(start+1, data);
  41. ++data;
  42. return;
  43. }
  44. }
  45. throw json::malformed_json_exception("Could not locate end of string");
  46. }
  47. template <typename T>
  48. void parse_numeric(T& json, char const*& data) {
  49. // TODO: more sophisticated float detection?
  50. char const* start = data;
  51. while (*++data) {
  52. if (*data == '.') {
  53. while (isnumber(*++data));
  54. json = atof(start);
  55. break;
  56. } else if (!isnumber(*data)) {
  57. json = atoi(start);
  58. break;
  59. }
  60. }
  61. }
  62. }
  63. }