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