json_binder.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. //
  2. // json_binder.h
  3. // json
  4. //
  5. // Created by Sam Jaffe on 1/31/16.
  6. // Copyright © 2016 Sam Jaffe. All rights reserved.
  7. //
  8. #ifndef json_binder_h
  9. #define json_binder_h
  10. #pragma once
  11. #include "json_common.h"
  12. #include <map>
  13. #include <string>
  14. #include <vector>
  15. namespace json {
  16. namespace binder {
  17. template <typename T>
  18. class binder_impl {
  19. public:
  20. virtual binder_impl<T>* clone() const = 0;
  21. virtual ~binder_impl() {}
  22. virtual void parse(T&, char const*&) const = 0;
  23. virtual void write(T const&, std::string &) const = 0;
  24. };
  25. template <typename T>
  26. class binder {
  27. public:
  28. binder() : impl(nullptr), owned(false) {}
  29. binder(binder const& other) : impl(other.impl->clone()), owned(true) {}
  30. binder(binder_impl<T> const* p) : impl(p), owned(true) {}
  31. binder(binder_impl<T> const& r) : impl(&r), owned(false) {}
  32. ~binder() { if (impl && owned) delete impl; }
  33. void parse(T& object, char const*& data) const {
  34. if (!impl) return;
  35. impl->parse(object, data);
  36. }
  37. void write(T const& object, std::string & data) const {
  38. if (!impl) return;
  39. impl->write(object, data);
  40. }
  41. private:
  42. binder_impl<T> const* impl;
  43. bool owned;
  44. };
  45. template <typename T, typename E>
  46. class direct_binder : public binder_impl<T> {
  47. public:
  48. direct_binder(E T::*p, binder<E> const& i) : ptr(p), impl(i) {}
  49. virtual binder_impl<T>* clone() const override { return new direct_binder(*this); }
  50. virtual void parse(T& val, char const*& data) const override {
  51. impl.parse(val.*ptr, data);
  52. }
  53. virtual void write(T const& val, std::string & data) const override {
  54. impl.write(val.*ptr, data);
  55. }
  56. private:
  57. E T::*ptr;
  58. binder<E> impl;
  59. };
  60. template <typename T>
  61. class direct_binder<T, bool> : public binder_impl<T> {
  62. public:
  63. direct_binder(bool T::*p) : ptr(p) {}
  64. virtual binder_impl<T>* clone() const override { return new direct_binder(*this); }
  65. virtual void parse(T& val, char const*& data) const override {
  66. if (!strncmp(data, "true", 4)) {
  67. val.*ptr = true;
  68. } else if (!strncmp(data, "false", 5)) {
  69. val.*ptr = false;
  70. } else {
  71. throw json::malformed_json_exception("Expected a boolean type here");
  72. }
  73. }
  74. virtual void write(T const& val, std::string & data) const override {
  75. data += (val.*ptr ? "true" : "false");
  76. }
  77. private:
  78. bool T::*ptr;
  79. };
  80. template <typename T>
  81. class direct_binder<T, int> : public binder_impl<T> {
  82. public:
  83. direct_binder(int T::*p) : ptr(p) {}
  84. virtual binder_impl<T>* clone() const override { return new direct_binder(*this); }
  85. virtual void parse(T& val, char const*& data) const override {
  86. // if (false) {
  87. json::helper::parse_numeric(val.*ptr, data);
  88. // } else {
  89. // throw json::malformed_json_exception("Expected an integral type here");
  90. // }
  91. }
  92. virtual void write(T const& val, std::string & data) const override {
  93. char buffer[16] = { '\0' };
  94. snprintf(buffer, sizeof(buffer), "%d", val.*ptr);
  95. data += buffer;
  96. }
  97. private:
  98. int T::*ptr;
  99. };
  100. template <typename T>
  101. class direct_binder<T, double> : public binder_impl<T> {
  102. public:
  103. direct_binder(double T::*p) : ptr(p) {}
  104. virtual binder_impl<T>* clone() const override { return new direct_binder(*this); }
  105. virtual void parse(T& val, char const*& data) const override {
  106. // if (false) {
  107. json::helper::parse_numeric(val.*ptr, data);
  108. // } else {
  109. // throw json::malformed_json_exception("Expected a floating point type here");
  110. // }
  111. }
  112. virtual void write(T const& val, std::string & data) const override {
  113. char buffer[32] = { '\0' };
  114. snprintf(buffer, sizeof(buffer), "%lf", val.*ptr);
  115. data += buffer;
  116. }
  117. private:
  118. double T::*ptr;
  119. };
  120. template <typename T>
  121. class direct_binder<T, std::string> : public binder_impl<T> {
  122. public:
  123. direct_binder(std::string T::*p) : ptr(p) {}
  124. virtual binder_impl<T>* clone() const override { return new direct_binder(*this); }
  125. virtual void parse(T& val, char const*& data) const override {
  126. json::helper::parse_string(val.*ptr, data);
  127. }
  128. virtual void write(T const& val, std::string & data) const override {
  129. data += "\"" + val.*ptr + "\"";
  130. }
  131. private:
  132. std::string T::*ptr;
  133. };
  134. template <typename T, typename V>
  135. class direct_binder<T, std::vector<V> > : public binder_impl<T> {
  136. public:
  137. direct_binder(std::vector<V> T::*p, binder<V> const&i);
  138. virtual binder_impl<T>* clone() const override { return new direct_binder(*this); }
  139. virtual void parse(T& val, char const*& data) const override {
  140. const char ch = json::helper::get_next_element(data);
  141. if (ch != '[') {
  142. throw json::malformed_json_exception("Expected an array type");
  143. }
  144. ++data;
  145. V to_make;
  146. std::vector<V>& vec = val.*ptr;
  147. while (*data && *data != ']') {
  148. impl.parse(to_make, data);
  149. vec.emplace_back(to_make);
  150. json::helper::advance_to_boundary<']'>(data);
  151. }
  152. if (*data) ++data;
  153. else throw json::malformed_json_exception("Reached end of parse string without finding array end");
  154. }
  155. virtual void write(T const& val, std::string & data) const override {
  156. data += "[";
  157. std::vector<V> const & vec = val.*ptr;
  158. for (typename std::vector<V>::const_iterator it = vec.begin(),
  159. end = vec.end(); it != end; ++it) {
  160. impl.write(*it, data);
  161. data += ",";
  162. }
  163. data.back() = ']';
  164. }
  165. private:
  166. std::vector<V> T::*ptr;
  167. binder<V> impl;
  168. };
  169. template <typename T, typename V>
  170. class direct_binder<T, std::map<std::string, V> > : public binder_impl<T> {
  171. public:
  172. direct_binder(std::vector<V> T::*p, binder<V> const&i);
  173. virtual binder_impl<T>* clone() const override { return new direct_binder(*this); }
  174. virtual void parse(T& val, char const*& data) const override {
  175. const char ch = json::helper::get_next_element(data);
  176. if (ch != '{') {
  177. throw json::malformed_json_exception("Expected an array type");
  178. }
  179. ++data;
  180. V to_make;
  181. std::map<std::string, V>& vec = val.*ptr;
  182. std::string key;
  183. while (*data && *data != '}') {
  184. json::helper::parse_string(key, data);
  185. if (json::helper::get_next_element(data) != ':') {
  186. throw json::malformed_json_exception(std::string("Expected key:value pair delimited by ':', got '") + *data + "' instead");
  187. }
  188. impl.parse(to_make, ++data);
  189. vec.emplace(key, to_make);
  190. json::helper::advance_to_boundary<'}'>(data);
  191. }
  192. if (*data) ++data;
  193. else throw json::malformed_json_exception("Reached end of parse string without finding object end");
  194. }
  195. virtual void write(T const& val, std::string & data) const override {
  196. data += "{";
  197. std::map<std::string, V> const & map = val.*ptr;
  198. for (typename std::map<std::string, V>::const_iterator it = map.begin(),
  199. end = map.end(); it != end; ++it) {
  200. data += "\"" + it->first + "\":";
  201. impl.write(it->second, data);
  202. data += ",";
  203. }
  204. data.back() = '}';
  205. }
  206. private:
  207. std::map<std::string, V> T::*ptr;
  208. binder<V> impl;
  209. };
  210. template <typename T>
  211. class object_binder : public binder_impl<T> {
  212. public:
  213. object_binder() {}
  214. virtual binder_impl<T>* clone() const override { return new object_binder(*this); }
  215. template <typename V>
  216. object_binder& operator()(std::string const&k, V T::*ptr, binder_impl<V> const&v) {
  217. return (*this)(k, binder<T>(new direct_binder<T, V>(ptr, binder<V>(v) )));
  218. }
  219. object_binder& operator()(std::string const&k, binder<T> const&v) {
  220. mapping.emplace(k, v);
  221. return *this;
  222. }
  223. virtual void parse(T& object, char const*& data) const override {
  224. const char ch = json::helper::get_next_element(data);
  225. if (ch == '{') {
  226. parse_object(object, ++data);
  227. } else {
  228. throw json::malformed_json_exception(std::string("Expected an object type for binding to ") + typeid(T).name());
  229. }
  230. }
  231. virtual void write(T const& val, std::string & data) const override {
  232. data += "{";
  233. for (typename std::map<std::string, binder<T>>::const_iterator it = mapping.begin(),
  234. end = mapping.end(); it != end; ++it) {
  235. data += "\"" + it->first + "\":";
  236. it->second.write(val, data);
  237. data += ",";
  238. }
  239. data.back() = '}';
  240. }
  241. void parse_object(T& object, char const*& data) const {
  242. std::string key;
  243. while (*data && *data != '}') {
  244. json::helper::parse_string(key, data);
  245. if (json::helper::get_next_element(data) != ':') {
  246. throw json::malformed_json_exception(std::string("Expected key:value pair delimited by ':', got '") + *data + "' instead");
  247. }
  248. auto it = mapping.find(key);
  249. if (it != mapping.end()) {
  250. it->second.parse(object, ++data);
  251. } else {
  252. throw json::malformed_json_exception("Unexpected key " + key);
  253. }
  254. json::helper::advance_to_boundary<'}'>(data);
  255. }
  256. if (*data) ++data;
  257. else throw json::malformed_json_exception("Reached end of parse string without finding object end");
  258. }
  259. template <typename E>
  260. object_binder& operator()(std::string const& s, E T::*p) {
  261. return operator()(s, binder<T>(new direct_binder<T, E>(p)));
  262. }
  263. private:
  264. std::map<std::string, binder<T>> mapping;
  265. };
  266. template <typename T>
  267. class tuple_binder : public binder_impl<T> {
  268. public:
  269. virtual binder_impl<T>* clone() const override { return new tuple_binder(*this); }
  270. tuple_binder& operator()(binder<T> const&b) {
  271. members.push_back(b);
  272. return *this;
  273. }
  274. virtual void parse(T& object, char const*& data) const override {
  275. const char ch = json::helper::get_next_element(data);
  276. if (ch == '[') {
  277. parse_tuple(object, ++data);
  278. } else {
  279. throw json::malformed_json_exception(std::string("Expected an object type for binding to ") + typeid(T).name());
  280. }
  281. }
  282. virtual void write(T const& val, std::string & data) const override {
  283. data += "[";
  284. for (typename std::vector<binder<T>>::const_iterator it = members.begin(),
  285. end = members.end(); it != end; ++it) {
  286. it->write(val, data);
  287. data += ",";
  288. }
  289. data.back() = ']';
  290. }
  291. void parse_tuple(T& object, char const*& data) const {
  292. auto it = members.begin();
  293. while (*data && *data != ']' && it != members.end()) {
  294. it->parse(object, data);
  295. json::helper::advance_to_boundary<']'>(data);
  296. ++it;
  297. }
  298. if (it != members.end()) {
  299. throw json::malformed_json_exception("Failed to parse every member of tuple");
  300. }
  301. if (*data) ++data;
  302. else throw json::malformed_json_exception("Reached end of parse string without finding array end");
  303. }
  304. template <typename E>
  305. tuple_binder& operator()(E T::*p) {
  306. return operator()(binder<T>(new direct_binder<T, E>(p)));
  307. }
  308. private:
  309. std::vector<binder<T>> members;
  310. };
  311. template <typename T, typename S = T>
  312. class visitor {
  313. public:
  314. visitor(S& o, binder_impl<T>& b) : obj(o), b(b) {}
  315. void parse(char const* data) {
  316. b.parse(obj, data);
  317. }
  318. void write(std::string & data) const {
  319. b.write(obj, data);
  320. }
  321. private:
  322. S& obj;
  323. binder_impl<T>& b;
  324. };
  325. template <typename T>
  326. visitor<T> bind(T& object, binder_impl<T>& b) {
  327. return visitor<T>{object, b};
  328. }
  329. }
  330. namespace parser {
  331. template <typename T>
  332. void parse(binder::visitor<T>& visitor, char const* data) {
  333. visitor.parse(data);
  334. }
  335. template <typename T, typename S>
  336. void write(binder::visitor<T, S> const & visitor, std::string & data) {
  337. visitor.write(data);
  338. }
  339. }
  340. }
  341. #endif /* json_binder_h */