Elm  1.0
ELM is a library providing generic data structures, OS-independent interface, plugins and XML.
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Serialization / unserialization

Classes

class  elm::serial2::AbstractType
 
class  elm::serial2::TextSerializer
 
class  elm::serial2::XOMSerializer
 
class  elm::serial2::XOMUnserializer
 

Detailed Description

ELM provides support for pseudo-automatic serialization / unserialization of objects.

The following C++ features are supported in serialization:

In addition, the user can provides its own custom serialization code in a serializer / unserializer independent format.

A simple example

The serialization or the unserialization is a very simple to perform using the same interface as usual C++ input/output.

#include <elm/serial2/serial.h>
#include <elm/serial2/TextSerializer.h>
#include <elm/serial2/collections.h>
using namespace elm;
int main(void) {
serializer << "Hello, World !\n" << 666 << true;
MyClass my_object;
serializer << my_object;
Vector<MyClass> objects;
for(int i = 0; i < 10; i++)
objects.add(my_object);
serializer << objects;
}

In the example above, we show how serializable objects (scalar values, string, MyClass and Vector) are easily serialized by a serializer providing a text output. As a default, the output is performed to the standard output. Notice that the unserialization of data from the bytes produced by this example must be performed in the same order.

#include <elm/serial2/serial.h>
#include <elm/serial2/XOMUnserializer.h>
#include <elm/serial2/collections.h>
using namespace elm;
int main(void) {
serial2::XOMUnserializer unser("unser.xml");
string str;
int x;
bool boolean;
serializer >> str >> x >> boolean;
MyClass my_object;
serializer >> my_object;
Vector<MyClass> objects;
serializer >> objects;
}
}

The unserialization above looks much like the previous serialization example. It works in the same way as the input stream of C++ standard library. The read values must be put in variable. Notice that in the case of the Vector, the unserializer automatically allocate enough space to store the serialized collection of objects. This examples illustrates also the use of an XML unserializer taking its input from the file "unser.xml". This file is usual XML text that may be modified by hand and that contains very few serialization-systems items.

ELM provides serializer / unserializer for usual types (like scalars, strings or data collections). Yet, to serializer custom classes, the user has to add some information about the fields to work with. In our example, we use the following declaration for MyClass in MyClass.h:

#include <elm/serial2/macros.h>
#include <elm/serial2/collections.h>
class MyClass {
SERIALIZABLE(MyClass, FIELD(name) & FIELD(value) & FIELD(attrs));
string name;
int value;
Vector<string> attrs;
public:
...
};

The macro SERIALIZABLE is used to add to the class some RTTI information that is used by the serialization system. After the name of the class, this macro takes the list of fields to serialize separated by the '&' operator and embedded in the FIELD macro. The field macro is not mandatory, it allows only to provide better reading on textual output by providing the name of the field. This macro is used both by serialization and unserialization.

Making a class serializable

In ELM, making a class serializable is very easy. One has to add some RTTI information in the class declaration and add a macro in the class definition file.

The declaration ".h" file must includes serialization headers:

#include <elm/serial2/macros.h>
#include <elm/serial2/collections.h>

Then, we have to add the macro SERIALIZE in the class declaration including the name of the class and the list of the field to serialize separated by '&'.

class ClassName {
SERIALIZABLE(ClassName, field1 & field2 & field3 & ...);
...
};

In the definition ".cpp" file, we have just to put the following macro that provides the implementation of the RTTI information of the class:

SERIALIZE(ClassName)

The passed class name must be the same between the SERIALIZABLE and the SERIALIZE macro and fully qualified to avoid ambiguities.

Declaring a field serializable is as easy as passing its name in the SERIALIZABLE list. Actually, a reference to the field is taken and used to read or write the serialized values. In human readable formats (like XML or text), it may be useful to provide also the identifier of the field to the serialization system. This is easily done using the FIELD macro in place of the field name:

SERIALIZE(MyClass, FIELD(field1) & field2 & FIELD(field3) & ...);

Some serialization formats supports optional field definition. In this case, a default value may be provided with the DFIELD macro:

SERIALIZE(MyClass, DFIELD(field1, default_value) & field2 & FIELD(field3) & ...);

Finally, if the serialized class inherit from a serializable class, the base class must be added to the list of field with the BASE macro:

class MyBaseClass {
SERIALIZABLE(MyBaseClass, ...);
...
};
class MyClass: public MyBaseClass {
SERIALIZABLE(MyClass, BASE(MyBaseClass) & field1 & ...);
...
};
Collection serialization
Customizing the serialization
Available serializers / unserializers
Writing a serialiazer