cppcms::serializable
Role
This class used for simple, fast and robust serialization of C++ object.
Header: #include <cppcms/archive.hpp>
Rationale
Serialization of object is important task, there are many good libraries that do this job, like boost::serialization.
However, most of them are too general and give too much overhead for simple task. This may significantly hurt performance in many simple cases we use.
So, good enough is good for our case --- keep serialization as simple as possible.
If you anyway want use any other serialization library, you can if it supports serialization to std::string
.
Base serializable class
This class has two pure virtual methods that should be implemented by it's users -- load() and save().
It provides simple interface to efficient conversion to string object and from string object in order to be useful with session and cache API.
class serializable { public: virtual void load(archive &a) = 0; virtual void save(archive &a) const = 0; operator std::string() const; serializable const &operator=(std::string const &s); void str(std::string const &s); std::string str() const; };
For example:
struct person : public serializable { int user_id; string name; double age; ... }; ... person per(id,"roy",35); session["user_data"].swap(per.str()); ... person per; per.str(session["user_data"]);
All save and load operations are performed through "archive" class.
cppcms::archive
Storage methods
cppcms::archive
know to store and restore two types of data:
- std::string
- Old Plain Data -- or general "memcpy"-able structures.
These operations are available using following operators of cppcms::archive
template<typename T> archive &operator<<(T const &val); template<typename T> archive &operator>>(T &val)
Save and restore old-plain-data to archive.
archive &operator<<(string const &val); archive &operator>>(string &val);
Save and restore C++ strings.
Simple objects
So, how should we serialize more complex objects? Let's see a simple example:
struct person : public serializable { int id; string name; double age; virtual void load(archive &a) { a>>id>>name>>age; } virtual void save(archive &a) const { a<<id<<name<<age; } };
That's it!
Managing more complex data
What should we do with STL collections or other more complex data?
struct person : public serializable { int id; string name; double age; set<string> colors; virtual void load(archive &a) { size_t n; string color; a>>id>>name>>age>>n; for(size_t i=0;i<n;i++) { a>>color; colors.insert(color); } } virtual void save(archive &a) const { a<<id<<name<<age<<colors.size(); set<string>::const_iterator p; for(p=colors.begin();p!=colors.end();++p) a<<*p; } };
That's it.