diff options
Diffstat (limited to 'src/s3select/rapidjson/example/archiver/archivertest.cpp')
-rw-r--r-- | src/s3select/rapidjson/example/archiver/archivertest.cpp | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/src/s3select/rapidjson/example/archiver/archivertest.cpp b/src/s3select/rapidjson/example/archiver/archivertest.cpp new file mode 100644 index 000000000..417a421a3 --- /dev/null +++ b/src/s3select/rapidjson/example/archiver/archivertest.cpp @@ -0,0 +1,287 @@ +#include "archiver.h" +#include <iostream> +#include <vector> + +////////////////////////////////////////////////////////////////////////////// +// Test1: simple object + +struct Student { + Student() : name(), age(), height(), canSwim() {} + Student(const std::string name, unsigned age, double height, bool canSwim) : + name(name), age(age), height(height), canSwim(canSwim) + {} + + std::string name; + unsigned age; + double height; + bool canSwim; +}; + +template <typename Archiver> +Archiver& operator&(Archiver& ar, Student& s) { + ar.StartObject(); + ar.Member("name") & s.name; + ar.Member("age") & s.age; + ar.Member("height") & s.height; + ar.Member("canSwim") & s.canSwim; + return ar.EndObject(); +} + +std::ostream& operator<<(std::ostream& os, const Student& s) { + return os << s.name << " " << s.age << " " << s.height << " " << s.canSwim; +} + +void test1() { + std::string json; + + // Serialize + { + Student s("Lua", 9, 150.5, true); + + JsonWriter writer; + writer & s; + json = writer.GetString(); + std::cout << json << std::endl; + } + + // Deserialize + { + Student s; + JsonReader reader(json.c_str()); + reader & s; + std::cout << s << std::endl; + } +} + +////////////////////////////////////////////////////////////////////////////// +// Test2: std::vector <=> JSON array +// +// You can map a JSON array to other data structures as well + +struct Group { + Group() : groupName(), students() {} + std::string groupName; + std::vector<Student> students; +}; + +template <typename Archiver> +Archiver& operator&(Archiver& ar, Group& g) { + ar.StartObject(); + + ar.Member("groupName"); + ar & g.groupName; + + ar.Member("students"); + size_t studentCount = g.students.size(); + ar.StartArray(&studentCount); + if (ar.IsReader) + g.students.resize(studentCount); + for (size_t i = 0; i < studentCount; i++) + ar & g.students[i]; + ar.EndArray(); + + return ar.EndObject(); +} + +std::ostream& operator<<(std::ostream& os, const Group& g) { + os << g.groupName << std::endl; + for (std::vector<Student>::const_iterator itr = g.students.begin(); itr != g.students.end(); ++itr) + os << *itr << std::endl; + return os; +} + +void test2() { + std::string json; + + // Serialize + { + Group g; + g.groupName = "Rainbow"; + + Student s1("Lua", 9, 150.5, true); + Student s2("Mio", 7, 120.0, false); + g.students.push_back(s1); + g.students.push_back(s2); + + JsonWriter writer; + writer & g; + json = writer.GetString(); + std::cout << json << std::endl; + } + + // Deserialize + { + Group g; + JsonReader reader(json.c_str()); + reader & g; + std::cout << g << std::endl; + } +} + +////////////////////////////////////////////////////////////////////////////// +// Test3: polymorphism & friend +// +// Note that friendship is not necessary but make things simpler. + +class Shape { +public: + virtual ~Shape() {} + virtual const char* GetType() const = 0; + virtual void Print(std::ostream& os) const = 0; + +protected: + Shape() : x_(), y_() {} + Shape(double x, double y) : x_(x), y_(y) {} + + template <typename Archiver> + friend Archiver& operator&(Archiver& ar, Shape& s); + + double x_, y_; +}; + +template <typename Archiver> +Archiver& operator&(Archiver& ar, Shape& s) { + ar.Member("x") & s.x_; + ar.Member("y") & s.y_; + return ar; +} + +class Circle : public Shape { +public: + Circle() : radius_() {} + Circle(double x, double y, double radius) : Shape(x, y), radius_(radius) {} + ~Circle() {} + + const char* GetType() const { return "Circle"; } + + void Print(std::ostream& os) const { + os << "Circle (" << x_ << ", " << y_ << ")" << " radius = " << radius_; + } + +private: + template <typename Archiver> + friend Archiver& operator&(Archiver& ar, Circle& c); + + double radius_; +}; + +template <typename Archiver> +Archiver& operator&(Archiver& ar, Circle& c) { + ar & static_cast<Shape&>(c); + ar.Member("radius") & c.radius_; + return ar; +} + +class Box : public Shape { +public: + Box() : width_(), height_() {} + Box(double x, double y, double width, double height) : Shape(x, y), width_(width), height_(height) {} + ~Box() {} + + const char* GetType() const { return "Box"; } + + void Print(std::ostream& os) const { + os << "Box (" << x_ << ", " << y_ << ")" << " width = " << width_ << " height = " << height_; + } + +private: + template <typename Archiver> + friend Archiver& operator&(Archiver& ar, Box& b); + + double width_, height_; +}; + +template <typename Archiver> +Archiver& operator&(Archiver& ar, Box& b) { + ar & static_cast<Shape&>(b); + ar.Member("width") & b.width_; + ar.Member("height") & b.height_; + return ar; +} + +class Canvas { +public: + Canvas() : shapes_() {} + ~Canvas() { Clear(); } + + void Clear() { + for (std::vector<Shape*>::iterator itr = shapes_.begin(); itr != shapes_.end(); ++itr) + delete *itr; + } + + void AddShape(Shape* shape) { shapes_.push_back(shape); } + + void Print(std::ostream& os) { + for (std::vector<Shape*>::iterator itr = shapes_.begin(); itr != shapes_.end(); ++itr) { + (*itr)->Print(os); + std::cout << std::endl; + } + } + +private: + template <typename Archiver> + friend Archiver& operator&(Archiver& ar, Canvas& c); + + std::vector<Shape*> shapes_; +}; + +template <typename Archiver> +Archiver& operator&(Archiver& ar, Shape*& shape) { + std::string type = ar.IsReader ? "" : shape->GetType(); + ar.StartObject(); + ar.Member("type") & type; + if (type == "Circle") { + if (ar.IsReader) shape = new Circle; + ar & static_cast<Circle&>(*shape); + } + else if (type == "Box") { + if (ar.IsReader) shape = new Box; + ar & static_cast<Box&>(*shape); + } + return ar.EndObject(); +} + +template <typename Archiver> +Archiver& operator&(Archiver& ar, Canvas& c) { + size_t shapeCount = c.shapes_.size(); + ar.StartArray(&shapeCount); + if (ar.IsReader) { + c.Clear(); + c.shapes_.resize(shapeCount); + } + for (size_t i = 0; i < shapeCount; i++) + ar & c.shapes_[i]; + return ar.EndArray(); +} + +void test3() { + std::string json; + + // Serialize + { + Canvas c; + c.AddShape(new Circle(1.0, 2.0, 3.0)); + c.AddShape(new Box(4.0, 5.0, 6.0, 7.0)); + + JsonWriter writer; + writer & c; + json = writer.GetString(); + std::cout << json << std::endl; + } + + // Deserialize + { + Canvas c; + JsonReader reader(json.c_str()); + reader & c; + c.Print(std::cout); + } +} + +////////////////////////////////////////////////////////////////////////////// + +int main() { + test1(); + test2(); + test3(); +} |