How to serialize a vector to an XML file using C++ Boost serialization

The Boost library provides a serialization library to serialize objects to XML or text stream. It is very simple to use. Here is my two class, one that contains a vector of shapes and the class of shapes.

//
// CShapeCollection
//
class CShapeCollection
{
public:
	CShapeCollection() {}
	~CShapeCollection() {}

private:
	friend class boost::serialization::access;

	template<class Archive>
	void save(Archive & ar, const unsigned int version) const
	{
		ar & BOOST_SERIALIZATION_NVP(m_shapes);
	}

	template<class Archive>
	void load(Archive & ar, const unsigned int version)
	{
		ar & BOOST_SERIALIZATION_NVP(m_shapes);
	}

    BOOST_SERIALIZATION_SPLIT_MEMBER()

public:
	vector<boost::shared_ptr<CSimpleShape> > m_shapes;
};

BOOST_CLASS_VERSION(CShapeCollection, 1)

//
// CSimpleShape
//
class CSimpleShape
{
public:
	CSimpleShape() {}
	~CSimpleShape() {}

private:
	friend class boost::serialization::access;
	template<class Archive>
	void save(Archive & ar, const unsigned int version) const
	{
		// ar & name;
		// ar & id;
		ar & BOOST_SERIALIZATION_NVP(m_name);
		ar & BOOST_SERIALIZATION_NVP(m_id);
		ar & BOOST_SERIALIZATION_NVP(m_rect);
		ar & BOOST_SERIALIZATION_NVP(m_type);
		ar & BOOST_SERIALIZATION_NVP(m_shapeType);
		ar & BOOST_SERIALIZATION_NVP(m_caption);
		ar & BOOST_SERIALIZATION_NVP(m_text);
		ar & BOOST_SERIALIZATION_NVP(m_x1);
		ar & BOOST_SERIALIZATION_NVP(m_y1);
		ar & BOOST_SERIALIZATION_NVP(m_x2);
		ar & BOOST_SERIALIZATION_NVP(m_y2);
		ar & BOOST_SERIALIZATION_NVP(m_colorFillR);
		ar & BOOST_SERIALIZATION_NVP(m_colorFillG);
		ar & BOOST_SERIALIZATION_NVP(m_colorFillB);
		ar & BOOST_SERIALIZATION_NVP(m_colorLineR);
		ar & BOOST_SERIALIZATION_NVP(m_colorLineG);
		ar & BOOST_SERIALIZATION_NVP(m_colorLineB);
		ar & BOOST_SERIALIZATION_NVP(m_bSolidColorFill);
		ar & BOOST_SERIALIZATION_NVP(m_bColorLine);
		ar & BOOST_SERIALIZATION_NVP(m_bColorFill);
	}

	template<class Archive>
	void load(Archive & ar, const unsigned int version)
	{
		// ar & name;
		// ar & id;
		ar & BOOST_SERIALIZATION_NVP(m_name);
		ar & BOOST_SERIALIZATION_NVP(m_id);
		ar & BOOST_SERIALIZATION_NVP(m_rect);
		ar & BOOST_SERIALIZATION_NVP(m_type);
		ar & BOOST_SERIALIZATION_NVP(m_shapeType);
		ar & BOOST_SERIALIZATION_NVP(m_caption);
		ar & BOOST_SERIALIZATION_NVP(m_text);
		ar & BOOST_SERIALIZATION_NVP(m_x1);
		ar & BOOST_SERIALIZATION_NVP(m_y1);
		ar & BOOST_SERIALIZATION_NVP(m_x2);
		ar & BOOST_SERIALIZATION_NVP(m_y2);
		ar & BOOST_SERIALIZATION_NVP(m_colorFillR);
		ar & BOOST_SERIALIZATION_NVP(m_colorFillG);
		ar & BOOST_SERIALIZATION_NVP(m_colorFillB);
		ar & BOOST_SERIALIZATION_NVP(m_colorLineR);
		ar & BOOST_SERIALIZATION_NVP(m_colorLineG);
		ar & BOOST_SERIALIZATION_NVP(m_colorLineB);
		ar & BOOST_SERIALIZATION_NVP(m_bSolidColorFill);
		ar & BOOST_SERIALIZATION_NVP(m_bColorLine);
		ar & BOOST_SERIALIZATION_NVP(m_bColorFill);
	}
    BOOST_SERIALIZATION_SPLIT_MEMBER()

public:
	string m_name;
	string m_id;
	string m_rect;
	long m_type;
	long m_shapeType;
	string m_caption;
	string m_text;
	long m_x1;
	long m_y1;
	long m_x2;
	long m_y2;
	int m_colorFillR;
	int m_colorFillG;
	int m_colorFillB;
	int m_colorLineR;
	int m_colorLineG;
	int m_colorLineB;
	bool m_bSolidColorFill;
	bool m_bColorLine;
	bool m_bColorFill;
};

BOOST_CLASS_VERSION(CSimpleShape, 1)

Now you have the data, you need to fill it and call the serialize to XML method… In my code, the real data of the application is the CElement. I have a vector of CElement but I need to transfer each element from CElement to SimpleShape witch is the XML container. It is a matter of separation. Then I call boost::archive::xml_oarchive… It is simple.

void CElementManager::Serialize_SaveAsXML(CModeler1View * pView)
{
	CFileDialog dlg(FALSE);
	if( dlg.DoModal() == IDCANCEL )
		return;

	CString strFileName = dlg.GetFileName();
	CString strPath = dlg.GetFolderPath();
	CString strFile;
	strFile.Format("%s\\%s", strPath, strFileName);
	std::string filename = (LPCTSTR)strFile;

	boost::shared_ptr<CShapeCollection> data(new CShapeCollection());

	for( vector<std::shared_ptr<CElement>>::iterator i = m_objects.m_objects.begin() ; i!=m_objects.m_objects.end() ; i++ )
	{
		std::shared_ptr<CElement> pElement = *i;
		boost::shared_ptr<CSimpleShape> pNewElement(new CSimpleShape());
		pNewElement->m_name = pElement->m_name;
		pNewElement->m_id = pElement->m_objectId;
		pNewElement->m_type = pElement->m_type;
		pNewElement->m_shapeType = pElement->m_shapeType;
		pNewElement->m_caption = pElement->m_caption;
		pNewElement->m_text = pElement->m_text;

		CPoint p1 = pElement->m_rect.TopLeft();
		CPoint p2 = pElement->m_rect.BottomRight();
		pNewElement->m_x1 = p1.x;
		pNewElement->m_y1 = p1.y;
		pNewElement->m_x2 = p2.x;
		pNewElement->m_y2 = p2.y;

		pNewElement->m_colorFillR = GetRValue(pElement->m_colorFill);
		pNewElement->m_colorFillG = GetGValue(pElement->m_colorFill);
		pNewElement->m_colorFillB = GetBValue(pElement->m_colorFill);
		pNewElement->m_colorLineR = GetRValue(pElement->m_colorLine);
		pNewElement->m_colorLineG = GetGValue(pElement->m_colorLine);
		pNewElement->m_colorLineB = GetBValue(pElement->m_colorLine);

		pNewElement->m_bSolidColorFill = pElement->m_bSolidColorFill;
		pNewElement->m_bColorLine = pElement->m_bColorLine;
		pNewElement->m_bColorFill = pElement->m_bColorFill;

		data->m_shapes.push_back(pNewElement);
	}

	// load an archive
	std::ofstream xofs(filename.c_str());
	boost::archive::xml_oarchive xoa(xofs);
	xoa << BOOST_SERIALIZATION_NVP(data);

}
Advertisements

Tagged: ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: