archivertest.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #include <rtthread.h>
  2. #include "archiver.h"
  3. #include <iostream>
  4. #include <vector>
  5. //////////////////////////////////////////////////////////////////////////////
  6. // Test1: simple object
  7. struct Student {
  8. Student() : name(), age(), height(), canSwim() {}
  9. Student(const std::string name, unsigned age, double height, bool canSwim) :
  10. name(name), age(age), height(height), canSwim(canSwim)
  11. {}
  12. std::string name;
  13. unsigned age;
  14. double height;
  15. bool canSwim;
  16. };
  17. template <typename Archiver>
  18. Archiver& operator&(Archiver& ar, Student& s) {
  19. ar.StartObject();
  20. ar.Member("name") & s.name;
  21. ar.Member("age") & s.age;
  22. ar.Member("height") & s.height;
  23. ar.Member("canSwim") & s.canSwim;
  24. return ar.EndObject();
  25. }
  26. std::ostream& operator<<(std::ostream& os, const Student& s) {
  27. return os << s.name << " " << s.age << " " << s.height << " " << s.canSwim;
  28. }
  29. void test1() {
  30. std::string json;
  31. // Serialize
  32. {
  33. Student s("Lua", 9, 150.5, true);
  34. JsonWriter writer;
  35. writer & s;
  36. json = writer.GetString();
  37. std::cout << json << std::endl;
  38. }
  39. // Deserialize
  40. {
  41. Student s;
  42. JsonReader reader(json.c_str());
  43. reader & s;
  44. std::cout << s << std::endl;
  45. }
  46. }
  47. //////////////////////////////////////////////////////////////////////////////
  48. // Test2: std::vector <=> JSON array
  49. //
  50. // You can map a JSON array to other data structures as well
  51. struct Group {
  52. Group() : groupName(), students() {}
  53. std::string groupName;
  54. std::vector<Student> students;
  55. };
  56. template <typename Archiver>
  57. Archiver& operator&(Archiver& ar, Group& g) {
  58. ar.StartObject();
  59. ar.Member("groupName");
  60. ar & g.groupName;
  61. ar.Member("students");
  62. size_t studentCount = g.students.size();
  63. ar.StartArray(&studentCount);
  64. if (ar.IsReader)
  65. g.students.resize(studentCount);
  66. for (size_t i = 0; i < studentCount; i++)
  67. ar & g.students[i];
  68. ar.EndArray();
  69. return ar.EndObject();
  70. }
  71. std::ostream& operator<<(std::ostream& os, const Group& g) {
  72. os << g.groupName << std::endl;
  73. for (std::vector<Student>::const_iterator itr = g.students.begin(); itr != g.students.end(); ++itr)
  74. os << *itr << std::endl;
  75. return os;
  76. }
  77. void test2() {
  78. std::string json;
  79. // Serialize
  80. {
  81. Group g;
  82. g.groupName = "Rainbow";
  83. Student s1("Lua", 9, 150.5, true);
  84. Student s2("Mio", 7, 120.0, false);
  85. g.students.push_back(s1);
  86. g.students.push_back(s2);
  87. JsonWriter writer;
  88. writer & g;
  89. json = writer.GetString();
  90. std::cout << json << std::endl;
  91. }
  92. // Deserialize
  93. {
  94. Group g;
  95. JsonReader reader(json.c_str());
  96. reader & g;
  97. std::cout << g << std::endl;
  98. }
  99. }
  100. //////////////////////////////////////////////////////////////////////////////
  101. // Test3: polymorphism & friend
  102. //
  103. // Note that friendship is not necessary but make things simpler.
  104. class Shape {
  105. public:
  106. virtual ~Shape() {}
  107. virtual const char* GetType() const = 0;
  108. virtual void Print(std::ostream& os) const = 0;
  109. protected:
  110. Shape() : x_(), y_() {}
  111. Shape(double x, double y) : x_(x), y_(y) {}
  112. template <typename Archiver>
  113. friend Archiver& operator&(Archiver& ar, Shape& s);
  114. double x_, y_;
  115. };
  116. template <typename Archiver>
  117. Archiver& operator&(Archiver& ar, Shape& s) {
  118. ar.Member("x") & s.x_;
  119. ar.Member("y") & s.y_;
  120. return ar;
  121. }
  122. class Circle : public Shape {
  123. public:
  124. Circle() : radius_() {}
  125. Circle(double x, double y, double radius) : Shape(x, y), radius_(radius) {}
  126. ~Circle() {}
  127. const char* GetType() const { return "Circle"; }
  128. void Print(std::ostream& os) const {
  129. os << "Circle (" << x_ << ", " << y_ << ")" << " radius = " << radius_;
  130. }
  131. private:
  132. template <typename Archiver>
  133. friend Archiver& operator&(Archiver& ar, Circle& c);
  134. double radius_;
  135. };
  136. template <typename Archiver>
  137. Archiver& operator&(Archiver& ar, Circle& c) {
  138. ar & static_cast<Shape&>(c);
  139. ar.Member("radius") & c.radius_;
  140. return ar;
  141. }
  142. class Box : public Shape {
  143. public:
  144. Box() : width_(), height_() {}
  145. Box(double x, double y, double width, double height) : Shape(x, y), width_(width), height_(height) {}
  146. ~Box() {}
  147. const char* GetType() const { return "Box"; }
  148. void Print(std::ostream& os) const {
  149. os << "Box (" << x_ << ", " << y_ << ")" << " width = " << width_ << " height = " << height_;
  150. }
  151. private:
  152. template <typename Archiver>
  153. friend Archiver& operator&(Archiver& ar, Box& b);
  154. double width_, height_;
  155. };
  156. template <typename Archiver>
  157. Archiver& operator&(Archiver& ar, Box& b) {
  158. ar & static_cast<Shape&>(b);
  159. ar.Member("width") & b.width_;
  160. ar.Member("height") & b.height_;
  161. return ar;
  162. }
  163. class Canvas {
  164. public:
  165. Canvas() : shapes_() {}
  166. ~Canvas() { Clear(); }
  167. void Clear() {
  168. for (std::vector<Shape*>::iterator itr = shapes_.begin(); itr != shapes_.end(); ++itr)
  169. delete *itr;
  170. }
  171. void AddShape(Shape* shape) { shapes_.push_back(shape); }
  172. void Print(std::ostream& os) {
  173. for (std::vector<Shape*>::iterator itr = shapes_.begin(); itr != shapes_.end(); ++itr) {
  174. (*itr)->Print(os);
  175. std::cout << std::endl;
  176. }
  177. }
  178. private:
  179. template <typename Archiver>
  180. friend Archiver& operator&(Archiver& ar, Canvas& c);
  181. std::vector<Shape*> shapes_;
  182. };
  183. template <typename Archiver>
  184. Archiver& operator&(Archiver& ar, Shape*& shape) {
  185. std::string type = ar.IsReader ? "" : shape->GetType();
  186. ar.StartObject();
  187. ar.Member("type") & type;
  188. if (type == "Circle") {
  189. if (ar.IsReader) shape = new Circle;
  190. ar & static_cast<Circle&>(*shape);
  191. }
  192. else if (type == "Box") {
  193. if (ar.IsReader) shape = new Box;
  194. ar & static_cast<Box&>(*shape);
  195. }
  196. return ar.EndObject();
  197. }
  198. template <typename Archiver>
  199. Archiver& operator&(Archiver& ar, Canvas& c) {
  200. size_t shapeCount = c.shapes_.size();
  201. ar.StartArray(&shapeCount);
  202. if (ar.IsReader) {
  203. c.Clear();
  204. c.shapes_.resize(shapeCount);
  205. }
  206. for (size_t i = 0; i < shapeCount; i++)
  207. ar & c.shapes_[i];
  208. return ar.EndArray();
  209. }
  210. void test3() {
  211. std::string json;
  212. // Serialize
  213. {
  214. Canvas c;
  215. c.AddShape(new Circle(1.0, 2.0, 3.0));
  216. c.AddShape(new Box(4.0, 5.0, 6.0, 7.0));
  217. JsonWriter writer;
  218. writer & c;
  219. json = writer.GetString();
  220. std::cout << json << std::endl;
  221. }
  222. // Deserialize
  223. {
  224. Canvas c;
  225. JsonReader reader(json.c_str());
  226. reader & c;
  227. c.Print(std::cout);
  228. }
  229. }
  230. //////////////////////////////////////////////////////////////////////////////
  231. int archiver_test() {
  232. test1();
  233. // test2();
  234. test3();
  235. }
  236. MSH_CMD_EXPORT(archiver_test, rapid json archiver_test example);