json_direct_map_binder.hpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. //
  2. // json_direct_map_binder.hpp
  3. // json
  4. //
  5. // Created by Sam Jaffe on 4/23/16.
  6. //
  7. #pragma once
  8. namespace json { namespace binder {
  9. template <typename T, typename V>
  10. class direct_binder<T, std::map<std::string, V> > : public binder_impl<T> {
  11. public:
  12. direct_binder(std::vector<V> T::*p, binder<V> const&i);
  13. virtual binder_impl<T>* clone() const override { return new direct_binder(*this); }
  14. virtual void parse(T& val, char const*& data) const override {
  15. const char ch = json::helper::get_next_element(data);
  16. if (ch != '{') {
  17. throw json::malformed_json_exception("Expected an array type");
  18. }
  19. ++data;
  20. V to_make;
  21. std::map<std::string, V>& vec = val.*ptr;
  22. std::string key;
  23. while (*data && *data != '}') {
  24. json::helper::parse_string(key, data);
  25. if (json::helper::get_next_element(data) != ':') {
  26. throw json::malformed_json_exception(std::string("Expected key:value pair delimited by ':', got '") + *data + "' instead");
  27. }
  28. impl.parse(to_make, ++data);
  29. vec.emplace(key, to_make);
  30. json::helper::advance_to_boundary('}', data);
  31. }
  32. if (*data) ++data;
  33. else throw json::unterminated_json_exception("Reached end of parse string without finding object end");
  34. }
  35. virtual void write(T const& val, std::ostream & data) const override {
  36. data << '{';
  37. std::map<std::string, V> const & map = val.*ptr;
  38. typename std::map<std::string, V>::const_iterator it = map.begin(), end = map.end();
  39. if (it != end) {
  40. data << '"' << it->first << '"' << ':';
  41. impl.write(it->second, data);
  42. for (++it; it != end; ++it) {
  43. data << ',';
  44. data << '"' << it->first << '"' << ':';
  45. impl.write(it->second, data);
  46. }
  47. }
  48. data << '}';
  49. }
  50. private:
  51. std::map<std::string, V> T::*ptr;
  52. binder<V> impl;
  53. };
  54. } }