Main  /  Edit version 1  /  Edit version 2  /   /  Users Area

Difference "Serialization" ver. 1 versus ver. 2

Content:

<!--toc-->
## Introduction
It is frequently required to save some C++ objects in some type of storage like user session or cache and retrieve
them back.
It is not a trivial task for C++ - non-reflective language. So CppCMS provide simple serialization library that helps
us to complete such tasks.
## CppCMS Serialization Tools
### Preparing Objects
Lets assume we have a class `person` that holds some information and a list of his children - `child` classes.
Person:
struct person {
std::string name;
std::string family;
std::string occupation;
std::string martial_state;
double salary;
physical parameters;
std::list<child> children;
std::vector<std::string> friends;
};
Child:
struct child {
std::string name;
physical parameters;
}
Physical data about them:
struct physical {
int age;
double height;
};
Now, in order to serialize our object we would derive
them from `cppcms::serializable` class.
Include `<cppcms/serialization.h>` header, and update
the object such that:
struct child {
...
};
struct person {
...
};
Become
struct child : public cppcms::serializable {
...
};
struct person : public cppcms::serializable {
...
};
Note, because "physical" object is POD we would handle
it in a better way.
Now we add a new member function the to two
classes abive that describes how to serialize them:
Child:
void serialize(cppcms::archive &a)
{
a & name & cppcms::as_pod(parameters);
}
It receives as parameter `cppcms::archive` - an object
that is capable to save/restore that data
and we mark each one of the members: `name`
and `parameters`.
Note, because we know that `parameters` is POD object
we use special marker that describes how to copy it.
Next we do the same for person:
void serialize(cppcms::archive &a)
{
a & name & family & occupation & martial_state
& salary & cppcms::as_pod(parameters) & children & friends;
}
**Note:**
The `archive` object knows how to deal with standard C++ containers like `std::vector` or `std::string`. It know
to save primitive types like `double` as plain binary data.
So for example because `children` is `std::list<child>`
and `child` is derived from `cppcms::serializable` it
knows how to handle this situation automatically.
If you use your own containers or non-standard containers
you may want to specialize: [`cppcms::archive_traits`](/cppcms_ref_v0_99/structcppcms_1_1archive__traits.html)
class for your specific class.
### Saving and Restoring Objects
Let's assume that `std::string buffer` us our data container
So we can save the data to the buffer using these
steps:
person john;
... // setup its data
cppcms::archive a;
john.save(a); // save it to archvive
buffer = a.str(); // get the buffer
We can load it as following:
person john;
cppcms::archive a;
a.str(buffer);
john.load(a);
This is very simple way to store and load data but we
recommend to use little bit complicated API that
would give us more power as we would see later:
Save:
person john;
... // setup its data
cppcms::serialization_traits<person>::save(john,buffer);
Load:
person john;
cppcms::serialization_traits<person>::load(buffer,john);
### Using with Cache and Sessions
Now lets see how we can use CppCMS serialization
tools with Cache and Session interfaces:
We can easily cache person objects like this:
person john;
if(!cache().fetch_data("john",john)) {
init_person(john);
cache().store_data("john",john);
}
This would allow use for example reduce complex
queries to database for some common data that is
not updated
We can store the objects withing the session:
person me;
if(session().is_set("me")) {
session().fetch_data("me",me);
me.salary += 1;
session().store_data("me",me);
}
## Using 3rd Party Serialization API
### Approach
CppCMS API is simple fast and powerful, but it is strictly
platform dependent - it does not allow to pass same
object between hosts with different architecture
or endianess, it does not support versioning etc.
So sometimes you want to use some 3rd party API with
CppCMS.
It is quite simple, all you need to do is to provide
specialization for `serialization_traits`
class - that was the reason we recommended to use
`serialization_traits` class rather then `cppcms::archive`
directly.
### Boost.Serialization
Lets show how we use for example Boost.Serialization
with CppCMS.
This is our very simple class that supports Boost.Serialization:
struct person {
std::string name;
std::string family;
template<typename Archive>
void serialize(Archive &a,unsigned /*version*/)
{
a & name & family;
}
};
Let's define two small helper functions to save
and load the object to the string:
template<typename T>
void load_from_boost(std::string const &src,T &obj)
{
std::stringbuf ss(src);
{
boost::archive::binary_iarchive oa(ss);
oa >> obj;
}
}
template<typename T>
void save_with_boost(T const &obj,std::string &tgt)
{
std::stringbuf ss;
{
boost::archive::binary_oarchive oa(ss);
oa << obj;
}
tgt=ss.str();
}
Now all we need is to specialize our `serialization_traits`
to handle `person` properly:
namespace cppcms {
template<>
struct serialization_traits<person> {
static void save(person const &obj,std::string &tgt)
{
save_with_boost(obj,tgt);
}
static void load(std::string const &src,person &obj)
{
load_from_boost(src,obj);
}
};
}
Then you can freely save and load object using CppCMS
session interface:
session or cache interface:
person john;
if(!cache().fetch_data("john",john)) {
init_person(john);
cache().store_data("john",john);
}

About

CppCMS is a web development framework for performance demanding applications.

Support This Project

SourceForge.net Logo

Поддержать проект

CppCMS needs You


Navigation

Main Page


Valid CSS | Valid XHTML 1.0