nlib
exi/serializer/serializer.cpp

Defines a simple XML serializer and serializes an object.

Much like the Boost serialization library, you can serialize a class object by creating a function template and using the & operator to specify which data member you want to serialize.

template<class Archive>
void Coordinate::serialize(Archive& ar) {
ar & latitude;
ar & longitude;
}

If binary XML was used, the serialized results are more compact than text-based XML. Although the results are in binary, it is still XML, so it has the advantage that it can be made readable by converting it to text-based XML.

The serializer in the sample has the following limitations.

The source code of the sample is shown below.

/*--------------------------------------------------------------------------------*
Project: CrossRoad
Copyright (C)Nintendo All rights reserved.
These coded instructions, statements, and computer programs contain proprietary
information of Nintendo and/or its licensed developers and are protected by
national and international copyright laws. They may not be disclosed to third
parties or copied or duplicated in any form, in whole or in part, without the
prior written consent of Nintendo.
The content herein is highly confidential and should be handled accordingly.
*--------------------------------------------------------------------------------*/
#include <map>
#include <string>
#include <vector>
#include "./def_serializer.h"
using nlib_ns::exi::ExiAllocator;
struct Coordinate {
float latitude;
float longitude;
template <class Archive>
void serialize(Archive& ar); // NOLINT
Coordinate(float arg_latitude, float arg_longitude) {
latitude = arg_latitude;
longitude = arg_longitude;
}
Coordinate() : latitude(0.f), longitude(0.f) {}
};
class CityInfo {
StdString name;
StdString url;
StdString governor;
int population;
Coordinate coordinate;
public:
template <class Archive>
void serialize(Archive& ar); // NOLINT
CityInfo(const ExiChar* arg_name, const ExiChar* arg_url, const ExiChar* arg_governor,
int arg_population, const Coordinate& arg_coordinate)
: name(arg_name),
url(arg_url),
governor(arg_governor),
population(arg_population),
coordinate(arg_coordinate) {}
CityInfo() : population(0) {}
void Print() {
ConsoleOutputStream out_;
TextWriter out;
out.Init();
out.Open(&out_);
out.WriteFormat("name: %s\n", M(name.c_str()));
out.WriteFormat("\turl: %s\n", M(url.c_str()));
out.WriteFormat("\tgovernor: %s\n", M(governor.c_str()));
out.WriteFormat("\tpopulation: %d\n", population);
out.WriteFormat("\tcoord: (%f, %f)\n\n", coordinate.latitude, coordinate.longitude);
}
};
template <class Archive>
void Coordinate::serialize(Archive& ar) { // NOLINT
ar& latitude;
ar& longitude;
}
template <class Archive>
void CityInfo::serialize(Archive& ar) { // NOLINT
// You can describe serialization and deserialization of the data by operator &().
// Archive is instantiated by SimpleSerializer in serialization,
// by SimpleDeserializer in deserialization.
ar& name;
ar& url;
ar& governor;
ar& population;
ar& coordinate;
}
typedef std::map<StdString, CityInfo> CityDB;
const int kBufSize = 1024 * 128;
unsigned char g_buf[kBufSize];
struct AllocFinalizer {
~AllocFinalizer() {
ExiAllocator::Finalize();
}
};
bool SampleExec() {
ReallocOutputStream os;
{
SimpleSerializer ser(&os);
CityDB sendData;
CityInfo tokyo(N("Tokyo"), N("http://www.metro.tokyo.jp/"), N("Shintaro Ishihara"),
13186835, Coordinate(35.6894875f, 139.6917064f));
CityInfo kyoto(N("Kyoto"), N("http://www.pref.kyoto.jp/"), N("Keiji Yamada"), 2633795,
Coordinate(35.0212466f, 135.7555968f));
sendData[N("Tokyo")] = tokyo;
sendData[N("Kyoto")] = kyoto;
// Serializes sendData into binary XML.
ser << sendData;
if (!ser.IsSuccess()) {
return false;
}
nlib_printf("%" PRIuS " bytes written\n\n", os.Pos());
}
// You have to reset the allocator after parsing.
ExiAllocator::Reset();
ReallocOutputStream::UniquePtrType data;
size_t data_size = os.Release(&data);
MemoryInputStream is(&data[0], data_size);
{
// Restore the CityDB object from the serialized data.
// You can also restore the object at a distant place.
SimpleDeserializer deser(&is);
CityDB receiveData;
// Restore receiveData by deserializing the binary XML for it.
deser >> receiveData;
if (!deser.IsSuccess()) {
return false;
}
CityDB::iterator it;
for (it = receiveData.begin(); it != receiveData.end(); ++it) {
it->second.Print();
}
}
return true;
}
bool SampleMain(int, char**) {
if (ExiAllocator::Init(g_buf, kBufSize) != 0) {
nlib_printf("ExiAllocator::Initialize failed\n");
return false;
}
bool rval = SampleExec();
ExiAllocator::Finalize();
return rval;
}
NLIB_MAINFUNC