/* --------------------------------------------------------------------------- // XMLSerializer.h // Author: Christian Schüller on 08/05/13. ------------------------------------------------------------------------------ This class allows to save and load a serialization of basic c++ data types like char, char*, std::string, bool, uint, int, float, double to and from a xml file. Containers like std::vector, std::std::pair, Eigen dense and sparse matrices are supported as well as combination of them (like vector> or vector>). To serialize an arbitary object use the XMLSerializable interface. The serialized objects are organised in groups in the xml file and have their own names which must be unique within one group. You can find examples how to use it in the test case class XMLSerializerTest. ----------------------------------------------------------------------------*/ #ifndef XML_SERIALIZER_H #define XML_SERIALIZER_H #include #include //#include #include #include #include #include #include namespace igl { namespace { void EncodeXMLElementName(std::string& name); void DecodeXMLElementName(std::string& name); void ReplaceSubString(std::string& str, const std::string& search, const std::string& replace); // Forward declaration class XMLSerializer; /** * interface XMLSerializable * Inherit from this interface to have full control over the serialization of you user defined class. */ class XMLSerializable { public: std::string Name; /** * This function gets called if the objects were not found during deserialization. * Initialize your objects as you like. */ virtual void Init() = 0; /** * Serialize your stuff within this function. * It contains the current serialization xml file. You can use SaveToXMLDoc or SaveGroupToXMLElement to add your objects. */ virtual bool Serialize(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element) = 0; /** * Deserialize your stuff within this function. * It contains the current serialization xml file. You can use LoadFromXMLDoc or LoadGroupFromXMLElement to read out your objects. */ virtual bool Deserialize(tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element) = 0; }; /** * class XMLSerialization * Inherit from this class to have the easiest way to serialize your user defined class. */ class XMLSerialization : public XMLSerializable { public: XMLSerializer* xmlSerializer; /** * Default implementation of XMLSerializable interface */ virtual void Init(); virtual bool Serialize(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element); virtual bool Deserialize(tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element); XMLSerialization(const std::string& name); ~XMLSerialization(); /** * Following functions can be overwritten to handle the specific events. * Return false to prevent serialization of object. */ virtual bool BeforeSerialization(); virtual void AfterSerialization(); virtual bool BeforeDeserialization(); virtual void AfterDeserialization(); }; /** * class XMLSerializableObject * internal usage */ class XMLSerializableObject : public XMLSerializable { public: XMLSerializableObject(const std::string& name, const std::string& group); virtual ~XMLSerializableObject(); // set attribute conversion functions void SetAttribute(tinyxml2::XMLElement* element, const char* name, char& dest); void SetAttribute(tinyxml2::XMLElement* element, const char* name, char*& dest); void SetAttribute(tinyxml2::XMLElement* element, const char* name, std::string& dest); void SetAttribute(tinyxml2::XMLElement* element, const char* name, bool& dest); void SetAttribute(tinyxml2::XMLElement* element, const char* name, unsigned int& dest); void SetAttribute(tinyxml2::XMLElement* element, const char* name, int& dest); void SetAttribute(tinyxml2::XMLElement* element, const char* name, float& dest); void SetAttribute(tinyxml2::XMLElement* element, const char* name, double& dest); // get attribute conversion functions void GetAttribute(const char* src, char& dest); void GetAttribute(const char* src, char*& dest); void GetAttribute(const char* src, std::string& dest); void GetAttribute(const char* src, bool& dest); void GetAttribute(const char* src, unsigned int& dest); void GetAttribute(const char* src, int& dest); void GetAttribute(const char* src, float& dest); void GetAttribute(const char* src, double& dest); // Initialization // Basic data types using XMLSerializable::Init; void Init(char& val); void Init(char*& val); void Init(std::string& val); void Init(bool& val); void Init(unsigned int& val); void Init(int& val); void Init(float& val); void Init(double& val); // XMLSerializable* template void Init(T& obj); template void Init(T*& obj); // STL containers /*template void Init(std::array& obj);*/ template void Init(std::pair& obj); template void Init(std::vector& obj); // Eigen types template void Init(Eigen::Matrix& obj); template void Init(Eigen::SparseMatrix& obj); // Serialization // Basic data types using XMLSerializable::Serialize; bool Serialize(char& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(char*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(std::string& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(std::string*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(bool obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(bool*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(unsigned int& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(unsigned int*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(int& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(int*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(float& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(float*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(double& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(double*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); // XMLSerializable* template bool Serialize(T& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); template bool Serialize(T*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); // STL containers /*template bool Serialize(std::array& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); template bool Serialize(std::array*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name);*/ template bool Serialize(std::pair& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); template bool Serialize(std::pair*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); template bool Serialize(std::vector& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); template bool Serialize(std::vector*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(std::vector& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool Serialize(std::vector*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); // Eigen types template bool Serialize(Eigen::Matrix& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); template bool Serialize(Eigen::Matrix*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); template bool Serialize(Eigen::SparseMatrix& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); template bool Serialize(Eigen::SparseMatrix*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); // Serialization // Basic data types using XMLSerializable::Deserialize; bool Deserialize(char& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(char*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(std::string& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(std::string*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(bool& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(bool*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(unsigned int& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(unsigned int*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(int& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(int*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(float& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(float*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(double& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(double*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); // XMLSerializable* template bool Deserialize(T& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); template bool Deserialize(T*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); // STL containers /*template bool Deserialize(std::array& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); template bool Deserialize(std::array*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name);*/ template bool Deserialize(std::pair& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); template bool Deserialize(std::pair*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); template bool Deserialize(std::vector& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); template bool Deserialize(std::vector*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(std::vector& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); bool Deserialize(std::vector*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); // Eigen types template bool Deserialize(Eigen::Matrix& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); template bool Deserialize(Eigen::Matrix*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); template bool Deserialize(Eigen::SparseMatrix& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); template bool Deserialize(Eigen::SparseMatrix*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); private: template bool setElementAttribute(T& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); template bool getElementAttribute(T& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name); }; /** * class XMLSerializableInstance * internal usage */ template class XMLSerializableInstance : public XMLSerializableObject { public: T& Object; T DefaultValue; XMLSerializableInstance(T& obj, const std::string& name, const std::string group); XMLSerializableInstance(T& obj, const std::string& name, const std::string group, T defaultValue); ~XMLSerializableInstance(); // XMLSerializable interface implementation void Init(); bool Serialize(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element); bool Deserialize(tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element); }; /** * struct XMLSerializerGroup * internal usage */ struct XMLSerializerGroup { std::string Name; std::vector* Objects; }; /** * class XMLSerializer * This is the core class which takes care of saving and loading of serialization of object structures. */ class XMLSerializer { public: /** * Serializes an object to a file */ template static bool SaveObject(T& object, const char* filename); template static bool SaveObject(T& object, const std::string& objectName, const std::string& groupName, const char* filename, bool overwrite); /** * Loads the serialization of an object from a file. */ template static bool LoadObject(T& object, const char* filename); template static bool LoadObject(T& object, const std::string& objectName, const std::string& groupName, const char* filename); /** * Constructor which sets the default group */ XMLSerializer(const std::string& defaultGroup); ~XMLSerializer(); /** * Save the serialization of all groups to file. * Parameter overwrite specifies if file gets overwritten or updated */ bool Save(const char* filename, bool overwrite); bool Save(const std::string& groupName, const char* filename, bool overwrite); bool Save(const std::string& objectName, const std::string& groupName, const char* filename, bool overwrite); /** * Save the serialization of all groups to a XMLDocument instance. */ bool SaveToXMLDoc(tinyxml2::XMLDocument* doc); bool SaveToXMLDoc(const std::string& groupName, tinyxml2::XMLDocument* doc); bool SaveToXMLDoc(const std::string& objectName, const std::string& groupName, tinyxml2::XMLDocument* doc); /** * Save the serialization of a group with a new provided name to given XMLElement instance. */ bool SaveGroupToXMLElement(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); bool SaveGroupToXMLElement(const std::string& groupName, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name); /** * Load the serialization from a file. */ bool Load(const char* filename); bool Load(const std::string& groupName, const char* filename); bool Load(const std::string& objectName, const std::string& groupName, const char* filename); /** * Load the serialization from an XMLDocument instance. */ bool LoadFromXMLDoc(tinyxml2::XMLDocument* doc); bool LoadFromXMLDoc(const std::string& groupName, tinyxml2::XMLDocument* doc); bool LoadFromXMLDoc(const std::string& objectName, const std::string& groupName, tinyxml2::XMLDocument* doc); /** * Load the serialization from a XMLElement instance to given group. */ bool LoadGroupFromXMLElement(const std::string& groupName, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element); /** * Set/Get current group. Every object which is added afterwards will be in this group, except it specifies another group. */ void SetCurrentGroup(const std::string& group); std::string GetCurrentGroup(); /** * Add an object to the serializer. Can be simple types like char, char*, string, unsigned int, int, float, double or containers like std::array, std::pair, std::vector. * Also Eigen dense or sparse matrices are supported and all objects of type Serializable* and combinations of thoses types like vector, vector or even vector>>. * Also pointers to those objects can be used (for instance like vector*>*>). * char* is also possible as base type and represents a array of chars, but be carefull that the pointer is not just a copy but a valid instance in the current programm scope. */ // Basic types bool Add(char& obj, const std::string& name); bool Add(char*& obj, const std::string& name); bool Add(std::string& obj, const std::string& name); bool Add(bool& obj, const std::string& name); bool Add(unsigned int& obj, const std::string& name); bool Add(int& obj, const std::string& name); bool Add(float& obj, const std::string& name); bool Add(double& obj, const std::string& name); bool Add(char& obj, const std::string& name, char defaultValue); bool Add(char*& obj, const std::string& name, char* defaultValue); bool Add(std::string& obj, const std::string& name, std::string defaultValue); bool Add(bool& obj, const std::string& name, bool defaultValue); bool Add(unsigned int& obj, const std::string& name, unsigned int defaultValue); bool Add(int& obj, const std::string& name, int defaultValue); bool Add(float& obj, const std::string& name, float defaultValue); bool Add(double& obj, const std::string& name, double defaultValue); // XMLSerializable* template bool Add(T& object, const std::string& name); template bool Add(T& object, const std::string& name, T defaultValue); // STL containers /*template bool Add(std::array& obj, const std::string& name);*/ template bool Add(std::pair& obj, const std::string& name); template bool Add(std::vector& obj, const std::string& name); // Eigen types template bool Add(Eigen::Matrix& obj, const std::string& name); template bool Add(Eigen::SparseMatrix& obj, const std::string& name); private: std::map::iterator currentGroup; std::map groups; template bool add(T& object, const std::string& name); template bool add(T& object, const std::string& name, T defaultValue); bool addObjectToGroup(XMLSerializable* object, const std::string& group); bool addObjectToGroup(XMLSerializable* object, std::map::iterator it); std::map::iterator setGetGroup(const std::string& group); tinyxml2::XMLDocument* openDoc(const char* filename); tinyxml2::XMLElement* findAddGroup(tinyxml2::XMLDocument* doc, const char* groupName); }; /** * class XMLSerializerTest * Used to test the functionality of the library and also shows howto use it. */ class XMLSerializerTest : public XMLSerialization { public: int testInt; std::vector testVector; XMLSerializerTest(); bool Test(); }; int numForbiddenChars = 8; char forbiddenChars[] = {' ','/','~','#','&','>','<','='}; void ReplaceSubString(std::string& str, const std::string& search, const std::string& replace) { size_t pos = 0; while ((pos = str.find(search, pos)) != std::string::npos) { str.replace(pos, search.length(), replace); pos += replace.length(); } } void EncodeXMLElementName(std::string& name) { // must not start with a digit if(isdigit(*name.begin())) { name = ":::" + name; } std::stringstream stream; for(int i=0;iSaveGroupToXMLElement(doc,element,Name); AfterSerialization(); } return serialized; } bool XMLSerialization::Deserialize(tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element) { bool serialized = false; if(BeforeDeserialization()) { serialized = xmlSerializer->LoadGroupFromXMLElement(Name,doc,element); AfterDeserialization(); } return serialized; } XMLSerialization::XMLSerialization(const std::string& name) { Name = name; xmlSerializer = new XMLSerializer(name); } XMLSerialization::~XMLSerialization() { delete xmlSerializer; } bool XMLSerialization::BeforeSerialization() { return true; } void XMLSerialization::AfterSerialization() { } bool XMLSerialization::BeforeDeserialization() { return true; } void XMLSerialization::AfterDeserialization() { } XMLSerializableObject::XMLSerializableObject(const std::string& name, const std::string& group) { std::string groupName = group; std::string objectName = name; EncodeXMLElementName(groupName); EncodeXMLElementName(objectName); Name = objectName; } XMLSerializableObject::~XMLSerializableObject() { } // set attribute conversion functions void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, char& dest) { element->SetAttribute(name,dest); } void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, char*& dest) { element->SetAttribute(name,const_cast(dest)); } void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, std::string& dest) { element->SetAttribute(name,dest.c_str()); } void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, bool& dest) { element->SetAttribute(name,dest); } void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, unsigned int& dest) { element->SetAttribute(name,dest); } void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, int& dest) { element->SetAttribute(name,dest); } void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, float& dest) { element->SetAttribute(name,dest); } void XMLSerializableObject::SetAttribute(tinyxml2::XMLElement* element, const char* name, double& dest) { element->SetAttribute(name,dest); } // get attribute conversion functions void XMLSerializableObject::GetAttribute(const char* src, char& dest) { dest = (char)atoi(src); } void XMLSerializableObject::GetAttribute(const char* src, char*& dest) { unsigned int length = strlen(src)+1; dest = new char[length]; strcpy(dest, src); } void XMLSerializableObject::GetAttribute(const char* src, std::string& dest) { dest = src; } void XMLSerializableObject::GetAttribute(const char* src, bool& dest) { tinyxml2::XMLUtil::ToBool(src,&dest); } void XMLSerializableObject::GetAttribute(const char* src, unsigned int& dest) { tinyxml2::XMLUtil::ToUnsigned(src,&dest); } void XMLSerializableObject::GetAttribute(const char* src, int& dest) { tinyxml2::XMLUtil::ToInt(src,&dest); } void XMLSerializableObject::GetAttribute(const char* src, float& dest) { tinyxml2::XMLUtil::ToFloat(src,&dest); } void XMLSerializableObject::GetAttribute(const char* src, double& dest) { tinyxml2::XMLUtil::ToDouble(src,&dest); } // specify default value of types void XMLSerializableObject::Init(char& val) { val = '0'; } void XMLSerializableObject::Init(char*& val) { val = NULL; } void XMLSerializableObject::Init(std::string& val) { val = ""; } void XMLSerializableObject::Init(bool& val) { val = false; } void XMLSerializableObject::Init(unsigned int& val) { val = 0; } void XMLSerializableObject::Init(int& val) { val = 0; } void XMLSerializableObject::Init(float& val) { val = 0.0f; } void XMLSerializableObject::Init(double& val) { val = 0.000000000000000; } template void XMLSerializableObject::Init(T*& obj) { XMLSerializable* object = static_cast(obj); object->Init(); } /*template void XMLSerializableObject::Init(std::array& obj) { for(unsigned int i=0;i void XMLSerializableObject::Init(std::pair& obj) { Init(obj.first); Init(obj.second); } template void XMLSerializableObject::Init(std::vector& obj) { obj.clear(); } template void XMLSerializableObject::Init(Eigen::Matrix& obj) { obj.setZero(obj.rows(),obj.cols()); } template void XMLSerializableObject::Init(Eigen::SparseMatrix& obj) { obj.setZero(); } bool XMLSerializableObject::Serialize(char& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return setElementAttribute(obj,doc,element,name); } // overload function for char*, it interpreted as char array and can be used to handle strings bool XMLSerializableObject::Serialize(char*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return setElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Serialize(std::string& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return setElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Serialize(std::string*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return Serialize(*obj,doc,element,name); } bool XMLSerializableObject::Serialize(bool obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return setElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Serialize(bool*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return Serialize(*obj,doc,element,name); } bool XMLSerializableObject::Serialize(unsigned int& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return setElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Serialize(unsigned int*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return Serialize(*obj,doc,element,name); } bool XMLSerializableObject::Serialize(int& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return setElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Serialize(int*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return Serialize(*obj,doc,element,name); } bool XMLSerializableObject::Serialize(float& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return setElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Serialize(float*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return Serialize(*obj,doc,element,name); } bool XMLSerializableObject::Serialize(double& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return setElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Serialize(double*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return Serialize(*obj,doc,element,name); } template bool XMLSerializableObject::Serialize(T& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return false; } template bool XMLSerializableObject::Serialize(T*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { // Serialize object implementing XMLSerializable interface XMLSerializable* object = static_cast(obj); tinyxml2::XMLElement* child = doc->NewElement(name.c_str()); element->InsertEndChild(child); return object->Serialize(doc,child); } bool XMLSerializableObject::Deserialize(char& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return getElementAttribute(obj,doc,element,name); } // template specialisation for char*, it interpreted as char array and can be used to handle strings bool XMLSerializableObject::Deserialize(char*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return getElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Deserialize(std::string& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return getElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Deserialize(std::string*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return Deserialize(*obj,doc,element,name); } bool XMLSerializableObject::Deserialize(bool& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return getElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Deserialize(bool*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return Deserialize(*obj,doc,element,name); } bool XMLSerializableObject::Deserialize(unsigned int& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return getElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Deserialize(unsigned int*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return Deserialize(*obj,doc,element,name); } bool XMLSerializableObject::Deserialize(int& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return getElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Deserialize(int*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return Deserialize(*obj,doc,element,name); } bool XMLSerializableObject::Deserialize(float& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return getElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Deserialize(float*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return Deserialize(*obj,doc,element,name); } bool XMLSerializableObject::Deserialize(double& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return getElementAttribute(obj,doc,element,name); } bool XMLSerializableObject::Deserialize(double*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return Deserialize(*obj,doc,element,name); } template bool XMLSerializableObject::Deserialize(T& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { return false; } template bool XMLSerializableObject::Deserialize(T*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { obj = new T(); XMLSerializable* object = static_cast(obj); const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str()); object->Name = child->FirstChild()->Value(); if(child != NULL) { obj->Deserialize(doc,child); } else { obj->Init(); return false; } return true; } /* template bool XMLSerializableObject::Serialize(std::array& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { tinyxml2::XMLElement* ar = doc->NewElement(name.c_str()); element->InsertEndChild(ar); ar->SetAttribute("size",(unsigned int)obj.size()); std::stringstream num; for(unsigned int i=0;i bool XMLSerializableObject::Serialize(std::array*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return Serialize(*obj,doc,element,name); } template bool XMLSerializableObject::Deserialize(std::array& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { bool res = true; const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str()); if(child != NULL) { int size = child->UnsignedAttribute("size"); size = S < size ? S : size; std::stringstream num; const tinyxml2::XMLAttribute* attribute = NULL; for(unsigned int i=0;i bool XMLSerializableObject::Deserialize(std::array*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { obj = new std::array(); return Deserialize(*obj,doc,element,name); } */ template bool XMLSerializableObject::Serialize(std::pair& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { bool res = true; tinyxml2::XMLElement* pair = doc->NewElement(name.c_str()); element->InsertEndChild(pair); res &= Serialize(obj.first,doc,pair,"first"); res &= Serialize(obj.second,doc,pair,"second"); return res; } template bool XMLSerializableObject::Serialize(std::pair*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return Serialize(*obj,doc,element,name); } template bool XMLSerializableObject::Deserialize(std::pair& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { bool res = true; const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str()); if(child != NULL) { res &= Deserialize(obj.first,doc,child,"first"); res &= Deserialize(obj.second,doc,child,"second"); } else { Init(obj.first); Init(obj.second); return false; } return res; } template bool XMLSerializableObject::Deserialize(std::pair*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { obj = new std::pair(); return Deserialize(*obj,doc,element,name); } template bool XMLSerializableObject::Serialize(std::vector& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { tinyxml2::XMLElement* vector = doc->NewElement(name.c_str()); element->InsertEndChild(vector); vector->SetAttribute("size",(unsigned int)obj.size()); std::stringstream num; for(unsigned int i=0;i bool XMLSerializableObject::Deserialize(std::vector& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { bool res = true; obj.clear(); const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str()); if(child != NULL) { unsigned int size = child->UnsignedAttribute("size"); obj.resize(size); std::stringstream num; for(unsigned int i=0;i& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { tinyxml2::XMLElement* vector = doc->NewElement(name.c_str()); element->InsertEndChild(vector); vector->SetAttribute("size",(unsigned int)obj.size()); std::stringstream num; for(unsigned int i=0;i& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { bool res = true; obj.clear(); const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str()); if(child != NULL) { unsigned int size = child->UnsignedAttribute("size"); obj.resize(size); std::stringstream num; for(unsigned int i=0;i bool XMLSerializableObject::Serialize(std::vector*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return Serialize(*obj,doc,element,name); } bool XMLSerializableObject::Serialize(std::vector*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return Serialize(*obj,doc,element,name); } template bool XMLSerializableObject::Deserialize(std::vector*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { obj = new std::vector(); return Deserialize(*obj,doc,element,name); } bool XMLSerializableObject::Deserialize(std::vector*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { obj = new std::vector(); return Deserialize(*obj,doc,element,name); } template bool XMLSerializableObject::Serialize(Eigen::Matrix& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { tinyxml2::XMLElement* matrix = doc->NewElement(name.c_str()); element->InsertEndChild(matrix); const unsigned int rows = obj.rows(); const unsigned int cols = obj.cols(); matrix->SetAttribute("rows",rows); matrix->SetAttribute("cols",cols); std::stringstream ms; ms << "\n"; for(unsigned int r=0;r 1) mString[mString.size()-2] = '\0'; matrix->SetAttribute("matrix",mString.c_str()); return true; } template bool XMLSerializableObject::Serialize(Eigen::Matrix*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return Serialize(*obj,doc,element,name); } template bool XMLSerializableObject::Deserialize(Eigen::Matrix& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str()); if(child != NULL) { const unsigned int rows = child->UnsignedAttribute("rows"); const unsigned int cols = child->UnsignedAttribute("cols"); obj.resize(rows,cols); const tinyxml2::XMLAttribute* attribute = child->FindAttribute("matrix"); if(attribute == NULL) { Init(obj); return false; } char* matTemp; GetAttribute(attribute->Value(),matTemp); std::string line, srows, scols; std::stringstream mats; mats.str(matTemp); int r=0; std::string val; // for each line getline(mats,line); while(getline(mats,line)) { // get current line std::stringstream liness(line); for(unsigned int c=0;c bool XMLSerializableObject::Deserialize(Eigen::Matrix*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { obj = new Eigen::PlainObjectBase(); return Deserialize(*obj,doc,element,name); } template bool XMLSerializableObject::Serialize(Eigen::SparseMatrix& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { tinyxml2::XMLElement* matrix = doc->NewElement(name.c_str()); element->InsertEndChild(matrix); const unsigned int rows = obj.rows(); const unsigned int cols = obj.cols(); matrix->SetAttribute("rows",rows); matrix->SetAttribute("cols",cols); std::stringstream ms; ms << "\n"; for (int k=0;k::InnerIterator it(obj,k);it;++it) { ms << it.row() << "," << it.col() << "," << it.value() << "\n"; } } std::string mString = ms.str(); if(mString.size() > 0) mString[mString.size()-1] = '\0'; matrix->SetAttribute("matrix",mString.c_str()); return true; } template bool XMLSerializableObject::Serialize(Eigen::SparseMatrix*& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return Serialize(*obj,doc,element,name); } template bool XMLSerializableObject::Deserialize(Eigen::SparseMatrix& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str()); if(child != NULL) { const unsigned int rows = child->UnsignedAttribute("rows"); const unsigned int cols = child->UnsignedAttribute("cols"); obj.resize(rows,cols); obj.setZero(); const tinyxml2::XMLAttribute* attribute = child->FindAttribute("matrix"); if(attribute == NULL) { Init(obj); return false; } char* matTemp; GetAttribute(attribute->Value(),matTemp); std::string line, srows, scols; std::stringstream mats; mats.str(matTemp); std::vector > triplets; int r=0; std::string val; // for each line getline(mats,line); while(getline(mats,line)) { // get current line std::stringstream liness(line); // row getline(liness, val, ','); int row = atoi(val.c_str()); // col getline(liness, val, ','); int col = atoi(val.c_str()); // val getline(liness, val); T value; GetAttribute(val.c_str(),value); triplets.push_back(Eigen::Triplet(row,col,value)); r++; } obj.setFromTriplets(triplets.begin(),triplets.end()); } else { Init(obj); return false; } return true; } template bool XMLSerializableObject::Deserialize(Eigen::SparseMatrix*& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { obj = new Eigen::SparseMatrix(); return Deserialize(*obj,doc,element,name); } template bool XMLSerializableObject::setElementAttribute(T& obj, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { tinyxml2::XMLElement* child = doc->NewElement(name.c_str()); element->InsertEndChild(child); SetAttribute(child,"val",obj); return true; } template bool XMLSerializableObject::getElementAttribute(T& obj, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element, const std::string& name) { // basic data type const tinyxml2::XMLElement* child = element->FirstChildElement(name.c_str()); if(child != NULL) { XMLSerializableObject::GetAttribute(child->Attribute("val"),obj); return true; } else { Init(obj); return false; } } template XMLSerializableInstance::XMLSerializableInstance(T& obj, const std::string& name, const std::string group) : XMLSerializableObject(name, group), Object(obj) { XMLSerializableObject::Init(DefaultValue); } template XMLSerializableInstance::XMLSerializableInstance(T& obj, const std::string& name, const std::string group, T defaultValue) : XMLSerializableObject(name, group), Object(obj), DefaultValue(defaultValue) { } template XMLSerializableInstance::~XMLSerializableInstance() { } template void XMLSerializableInstance::Init() { XMLSerializableObject::Init(DefaultValue); } template bool XMLSerializableInstance::Serialize(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element) { return XMLSerializableObject::Serialize(Object,doc,element,Name); } template bool XMLSerializableInstance::Deserialize(tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element) { return XMLSerializableObject::Deserialize(Object,doc,element,Name); } template bool XMLSerializer::SaveObject(T& object, const char* filename) { return SaveObject(object,"Object","Serialization",filename,true); } template bool XMLSerializer::SaveObject(T& object, const std::string& objectName, const std::string& groupName, const char* filename, bool overwrite) { bool result = true; XMLSerializer* serializer = new XMLSerializer(groupName); result &= serializer->Add(object,objectName); result &= serializer->Save(objectName,groupName,filename,overwrite); delete serializer; return result; } template bool XMLSerializer::LoadObject(T& object, const char* filename) { return LoadObject(object,"Object","Serialization",filename); } template bool XMLSerializer::LoadObject(T& object, const std::string& objectName, const std::string& groupName, const char* filename) { bool result = true; XMLSerializer* serializer = new XMLSerializer(groupName); result &= serializer->Add(object,objectName); result &= serializer->Load(objectName,groupName,filename); delete serializer; return result; } XMLSerializer::XMLSerializer(const std::string& defaultGroup) { SetCurrentGroup(defaultGroup); } XMLSerializer::~XMLSerializer() { std::map::iterator it; for (it=groups.begin();it!=groups.end();it++) { delete it->second->Objects; delete it->second; } } bool XMLSerializer::Save(const char* filename, bool overwrite) { tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument(); if(overwrite == false) { // Check if file exists tinyxml2::XMLError error = doc->LoadFile(filename); if(error != tinyxml2::XML_NO_ERROR) doc->Clear(); } if(SaveToXMLDoc(doc) == false) return false; // Save tinyxml2::XMLError error = doc->SaveFile(filename); if(error != tinyxml2::XML_NO_ERROR) { doc->PrintError(); return false; } delete doc; return true; } bool XMLSerializer::SaveToXMLDoc(tinyxml2::XMLDocument* doc) { std::map::iterator it; for (it=groups.begin();it!=groups.end();it++) { // Update group tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str()); if(element != NULL) { element->DeleteChildren(); } else { element = doc->NewElement(it->first.c_str()); doc->InsertEndChild(element); } std::vector* group = it->second->Objects; for(unsigned int i=0;isize();i++) { if((*group)[i]->Serialize(doc,element) == false) return false; } } return true; } bool XMLSerializer::Save(const std::string& groupName, const char* filename, bool overwrite) { tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument(); if(overwrite == false) { // Check if file exists tinyxml2::XMLError error = doc->LoadFile(filename); if(error != tinyxml2::XML_NO_ERROR) doc->Clear(); } if(SaveToXMLDoc(groupName, doc) == false) return false; // Save tinyxml2::XMLError error = doc->SaveFile(filename); if(error != tinyxml2::XML_NO_ERROR) { doc->PrintError(); return false; } delete doc; return true; } bool XMLSerializer::SaveToXMLDoc(const std::string& groupName, tinyxml2::XMLDocument* doc) { std::string gn = groupName; EncodeXMLElementName(gn); std::map::iterator it = groups.find(gn); if(it == groups.end()) return false; // Update group tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str()); if(element != NULL) { element->DeleteChildren(); } else { element = doc->NewElement(it->first.c_str()); doc->InsertEndChild(element); } std::vector* groups = it->second->Objects; for(unsigned int i=0;isize();i++) { if((*groups)[i]->Serialize(doc,element) == false) return false; } return true; } bool XMLSerializer::Save(const std::string& objectName, const std::string& groupName, const char* filename, bool overwrite) { tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument(); if(overwrite == false) { // Check if file exists tinyxml2::XMLError error = doc->LoadFile(filename); if(error != tinyxml2::XML_NO_ERROR) doc->Clear(); } if(SaveToXMLDoc(objectName, groupName, doc) == false) return false; // Save tinyxml2::XMLError error = doc->SaveFile(filename); if(error != tinyxml2::XML_NO_ERROR) { doc->PrintError(); return false; } delete doc; return true; } bool XMLSerializer::SaveToXMLDoc(const std::string& objectName, const std::string& groupName, tinyxml2::XMLDocument* doc) { std::string gn = groupName; EncodeXMLElementName(gn); std::string on = objectName; EncodeXMLElementName(on); std::map::iterator it = groups.find(gn); if(it == groups.end()) return false; // Get/Add group tinyxml2::XMLElement* element = findAddGroup(doc, it->first.c_str()); // Serialize std::vector* groups = it->second->Objects; bool found = false; for(unsigned int i=0;isize();i++) { if((*groups)[i]->Name == on) { found = true; tinyxml2::XMLElement* child = element->FirstChildElement(on.c_str()); if(child != NULL) { element->DeleteChild(child); } if((*groups)[i]->Serialize(doc,element) == false) return false; } } return found; } bool XMLSerializer::SaveGroupToXMLElement(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { return SaveGroupToXMLElement(currentGroup->first,doc,element,name); } bool XMLSerializer::SaveGroupToXMLElement(const std::string& groupName, tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* element, const std::string& name) { std::string gn = groupName; EncodeXMLElementName(gn); std::map::iterator it = groups.find(gn); if(it == groups.end()) return false; // Add new group tinyxml2::XMLElement* group = doc->NewElement(name.c_str()); element->InsertEndChild(group); std::vector* groups = it->second->Objects; for(unsigned int i=0;isize();i++) { if((*groups)[i]->Serialize(doc,group) == false) return false; } return true; } bool XMLSerializer::Load(const char* filename) { tinyxml2::XMLDocument* doc = openDoc(filename); if(doc == NULL) return false; if(LoadFromXMLDoc(doc) == false) return false; delete doc; return true; } bool XMLSerializer::LoadFromXMLDoc(tinyxml2::XMLDocument* doc) { std::map::iterator it; for (it=groups.begin();it!=groups.end();it++) { tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str()); if(element == NULL) return false; // Deserialize std::vector* group = it->second->Objects; for(unsigned int i=0;isize();i++) { if(element == NULL || (*group)[i]->Deserialize(doc,element) == false) (*group)[i]->Init(); // Load default value; } } return true; } bool XMLSerializer::Load(const std::string& groupName, const char* filename) { tinyxml2::XMLDocument* doc = openDoc(filename); if(doc == NULL) return false; if(LoadFromXMLDoc(groupName, doc) == false) return false; delete doc; return true; } bool XMLSerializer::LoadFromXMLDoc(const std::string& groupName, tinyxml2::XMLDocument* doc) { std::string gn = groupName; EncodeXMLElementName(gn); std::map::iterator it = groups.find(gn); if(it == groups.end()) return false; tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str()); if(element == NULL) return false; // Deserialize std::vector* groups = it->second->Objects; for(unsigned int i=0;isize();i++) { if(element == NULL || (*groups)[i]->Deserialize(doc,element) == false) (*groups)[i]->Init(); // Load default value; } return true; } bool XMLSerializer::Load(const std::string& objectName, const std::string& groupName, const char* filename) { tinyxml2::XMLDocument* doc = openDoc(filename); if(doc == NULL) return false; if(LoadFromXMLDoc(objectName,groupName,doc) == false) return false; delete doc; return true; } bool XMLSerializer::LoadFromXMLDoc(const std::string& objectName, const std::string& groupName, tinyxml2::XMLDocument* doc) { std::string gn = groupName; EncodeXMLElementName(gn); std::string on = objectName; EncodeXMLElementName(on); std::map::iterator it = groups.find(gn); if(it == groups.end()) return false; tinyxml2::XMLElement* element = doc->FirstChildElement(it->first.c_str()); if(element == NULL) return false; // Deserialize std::vector* groups = it->second->Objects; bool found = false; for(unsigned int i=0;isize();i++) { if((*groups)[i]->Name == on) { found = true; if(element == NULL || (*groups)[i]->Deserialize(doc,element) == false) (*groups)[i]->Init(); // Load default value; } } return found; } bool XMLSerializer::LoadGroupFromXMLElement(const std::string& groupName, tinyxml2::XMLDocument* doc, const tinyxml2::XMLElement* element) { std::string gn = groupName; EncodeXMLElementName(gn); std::map::iterator it = groups.find(gn); std::cerr << it-> first << std::endl; if(it == groups.end()) return false; const tinyxml2::XMLElement* group = element->FirstChildElement(groupName.c_str()); if(group == NULL) return false; // Deserialize std::vector* groups = it->second->Objects; for(unsigned int i=0;isize();i++) { if(element == NULL || (*groups)[i]->Deserialize(doc,group) == false) (*groups)[i]->Init(); // Load default value; } return true; } void XMLSerializer::SetCurrentGroup(const std::string& group) { currentGroup = setGetGroup(group); } std::string XMLSerializer::GetCurrentGroup() { return currentGroup->first; } template bool XMLSerializer::Add(T& obj, const std::string& name) { XMLSerializable* object = static_cast(&obj); object->Name = name; return addObjectToGroup(object,currentGroup); } bool XMLSerializer::Add(char& obj, const std::string& name) { return add(obj,name); } bool XMLSerializer::Add(char*& obj, const std::string& name) { return add(obj,name); } bool XMLSerializer::Add(std::string& obj, const std::string& name) { return add(obj,name); } bool XMLSerializer::Add(bool& obj, const std::string& name) { return add(obj,name); } bool XMLSerializer::Add(unsigned int& obj, const std::string& name) { return add(obj,name); } bool XMLSerializer::Add(int& obj, const std::string& name) { return add(obj,name); } bool XMLSerializer::Add(float& obj, const std::string& name) { return add(obj,name); } bool XMLSerializer::Add(double& obj, const std::string& name) { return add(obj,name); } /*template bool XMLSerializer::Add(std::array& obj, const std::string& name) { return add(obj,name); }*/ template bool XMLSerializer::Add(std::pair& obj, const std::string& name) { return add(obj,name); } template bool XMLSerializer::Add(std::vector& obj, const std::string& name) { return add(obj,name); } template bool XMLSerializer::Add(Eigen::Matrix& obj, const std::string& name) { return add(obj,name); } template bool XMLSerializer::Add(Eigen::SparseMatrix& obj, const std::string& name) { return add(obj,name); } template bool XMLSerializer::Add(T& object, const std::string& name, T defaultValue) { return false; } bool XMLSerializer::Add(char& obj, const std::string& name, char defaultValue) { return add(obj,name,defaultValue); } bool XMLSerializer::Add(char*& obj, const std::string& name, char* defaultValue) { return add(obj,name,defaultValue); } bool XMLSerializer::Add(std::string& obj, const std::string& name, std::string defaultValue) { return add(obj,name,defaultValue); } bool XMLSerializer::Add(bool& obj, const std::string& name, bool defaultValue) { return add(obj,name,defaultValue); } bool XMLSerializer::Add(unsigned int& obj, const std::string& name, unsigned int defaultValue) { return add(obj,name,defaultValue); } bool XMLSerializer::Add(int& obj, const std::string& name, int defaultValue) { return add(obj,name,defaultValue); } bool XMLSerializer::Add(float& obj, const std::string& name, float defaultValue) { return add(obj,name,defaultValue); } bool XMLSerializer::Add(double& obj, const std::string& name, double defaultValue) { return add(obj,name,defaultValue); } template bool XMLSerializer::add(T& obj, const std::string& name) { XMLSerializable* object = new XMLSerializableInstance(obj,name,currentGroup->first); return addObjectToGroup(object,currentGroup); } template bool XMLSerializer::add(T& obj, const std::string& name, T defaultValue) { XMLSerializable* object = new XMLSerializableInstance(obj,name,currentGroup->first,defaultValue); return addObjectToGroup(object,currentGroup); } bool XMLSerializer::addObjectToGroup(XMLSerializable* obj, const std::string& group) { std::map::iterator it = setGetGroup(group); return addObjectToGroup(obj, it); } bool XMLSerializer::addObjectToGroup(XMLSerializable* object, std::map::iterator it) { std::vector* objects = it->second->Objects; for(unsigned int i=0;isize();i++) { if((*objects)[i]->Name == object->Name) return false; } objects->push_back(object); return true; } std::map::iterator XMLSerializer::setGetGroup(const std::string& group) { std::string groupName = group; EncodeXMLElementName(groupName); std::map::iterator it = groups.find(groupName); if(it == groups.end()) { XMLSerializerGroup* newGroup = new XMLSerializerGroup(); newGroup->Objects = new std::vector(); groups[groupName] = newGroup; it = groups.find(groupName); } return it; } tinyxml2::XMLDocument* XMLSerializer::openDoc(const char* filename) { tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument(); tinyxml2::XMLError error = doc->LoadFile(filename); if(error != tinyxml2::XML_NO_ERROR) { doc->PrintError(); doc = NULL; } return doc; } tinyxml2::XMLElement* XMLSerializer::findAddGroup(tinyxml2::XMLDocument* doc, const char* groupName) { tinyxml2::XMLElement* group = doc->FirstChildElement(groupName); if(group == NULL) { group = doc->NewElement(groupName); doc->InsertEndChild(group); } return group; } XMLSerializerTest::XMLSerializerTest() : XMLSerialization("testObject") { xmlSerializer->Add(testInt,"testInt"); xmlSerializer->Add(testVector,"testVector"); testInt = 10; testVector.push_back(1.0001f); testVector.push_back(2.0001f); testVector.push_back(3.0001f); } } } #endif