serialization works for containment and inheritance
This commit is contained in:
		| @@ -33,7 +33,7 @@ class B: public xml::Serialize { | |||||||
|       className("b") |       className("b") | ||||||
|         .persist(i, "i") |         .persist(i, "i") | ||||||
|         .persist(txt, "txt") |         .persist(txt, "txt") | ||||||
|         .persist(a); |         .persist(a, "a"); | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
| //       1         2         3         4         5         6         7         8 | //       1         2         3         4         5         6         7         8 | ||||||
| // 45678901234567890123456789012345678901234567890123456789012345678901234567890 | // 45678901234567890123456789012345678901234567890123456789012345678901234567890 | ||||||
|  |  | ||||||
| // g++ -I../../src ../../src/xml.cxx serialization.cxx | // g++ -I../../src ../../src/xml.cxx inherit_serialization.cxx | ||||||
|  |  | ||||||
| #include <xml-cxx/xml.hxx> | #include <xml-cxx/xml.hxx> | ||||||
| #include <iostream> | #include <iostream> | ||||||
| @@ -17,7 +17,7 @@ class A: public xml::Serialize { | |||||||
|     std::string txt; |     std::string txt; | ||||||
|   protected: |   protected: | ||||||
|     void initXmlMembers() { |     void initXmlMembers() { | ||||||
|       className("b"); |       className("A"); | ||||||
|       persist(a, "a"); |       persist(a, "a"); | ||||||
|       persist(txt, "txt"); |       persist(txt, "txt"); | ||||||
|     } |     } | ||||||
| @@ -25,68 +25,25 @@ class A: public xml::Serialize { | |||||||
|  |  | ||||||
| class B: public A { | class B: public A { | ||||||
|   public: |   public: | ||||||
|     int a; |     int b; | ||||||
|     std::string txt; |  | ||||||
|   protected: |   protected: | ||||||
|     void initXmlMembers() { |     void initXmlMembers() { | ||||||
|       className("b"); |       A::initXmlMembers(); | ||||||
|       persist(a, "a"); |       className("B"); | ||||||
|       persist(txt, "txt"); |       persist(b, "b"); | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| //! Class with external xml::Serialize |  | ||||||
| class C { |  | ||||||
|   public: |  | ||||||
|     int a; |  | ||||||
|     std::string txt; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| int main(int, char**) { | int main(int, char**) { | ||||||
|   { // Serialization as a member |   std::stringstream ss("<B>\n" | ||||||
|     std::stringstream ss("<a>\n" |                        "\t<b>1234</b>\n" | ||||||
|                          "\t<a>1234</a>\n" |                        "\t<a>5678</a>\n" | ||||||
|                          "\t<txt>Dies ist ein Serialisierungs-Test</txt>\n" |                        "\t<txt>Dies ist ein Serialisierungs-Test</txt>\n" | ||||||
|                          "</a>"); |                        "</B>"); | ||||||
|     A a; |   B b; | ||||||
|     a._ser.loadXml(ss); |   b.loadXml(ss); | ||||||
|     if (a.a==1234) a.a=4321; |   if (b.b==1234) b.b=4321; | ||||||
|     a._ser.saveXml(std::cout)<<std::endl; |   if (b.a==5678) b.a=8765; | ||||||
|   } { // Inherited Serialization |   b.saveXml(std::cout)<<std::endl; | ||||||
|     std::stringstream ss("<b>\n" |  | ||||||
|                          "\t<a>1234</a>\n" |  | ||||||
|                          "\t<txt>Dies ist ein Serialisierungs-Test</txt>\n" |  | ||||||
|                          "</b>"); |  | ||||||
|     B b; |  | ||||||
|     b.loadXml(ss); |  | ||||||
|     if (b.a==1234) b.a=4321; |  | ||||||
|     b.saveXml(std::cout)<<std::endl; |  | ||||||
|   } { // External xml::Serialize: "ser" must live in no longer than "c"! |  | ||||||
|     std::stringstream ss("<c>\n" |  | ||||||
|                          "\t<a>1234</a>\n" |  | ||||||
|                          "\t<txt>Dies ist ein Serialisierungs-Test</txt>\n" |  | ||||||
|                          "</c>"); |  | ||||||
|     C c; |  | ||||||
|     xml::Serialize ser(xml::Serialize("c") |  | ||||||
|                        .persist(c.a, "a") |  | ||||||
|                        .persist(c.txt, "txt")); |  | ||||||
|     ser.loadXml(ss); |  | ||||||
|     if (c.a==1234) c.a=4321; |  | ||||||
|     ser.saveXml(std::cout)<<std::endl; |  | ||||||
|   } { // Use xml::Serialize to store anything, e.g. local variables |  | ||||||
|       // Important: "ser" must live in no longer than the variables! |  | ||||||
|     std::stringstream ss("<d>\n" |  | ||||||
|                          "\t<a>1234</a>\n" |  | ||||||
|                          "\t<txt>Dies ist ein Serialisierungs-Test</txt>\n" |  | ||||||
|                          "</d>"); |  | ||||||
|     int a; |  | ||||||
|     std::string txt; |  | ||||||
|     xml::Serialize ser(xml::Serialize("d") |  | ||||||
|                        .persist(a, "a") |  | ||||||
|                        .persist(txt, "txt")); |  | ||||||
|     ser.loadXml(ss); |  | ||||||
|     if (a==1234) a=4321; |  | ||||||
|     ser.saveXml(std::cout)<<std::endl; |  | ||||||
|   } |  | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,11 +6,15 @@ | |||||||
| AM_CXXFLAGS += -I ${top_srcdir}/src | AM_CXXFLAGS += -I ${top_srcdir}/src | ||||||
| AM_LDFLAGS = -L${top_builddir}/src -lxml-cxx | AM_LDFLAGS = -L${top_builddir}/src -lxml-cxx | ||||||
|  |  | ||||||
| noinst_PROGRAMS = address node_macros serialization contain_serialization | noinst_PROGRAMS = address node_macros serialization \ | ||||||
|  |                   contain_serialization inherit_serialization \ | ||||||
|  | 		  list_serialization | ||||||
|  |  | ||||||
| address_SOURCES = address.cxx | address_SOURCES = address.cxx | ||||||
| node_macros_SOURCES = node_macros.cxx | node_macros_SOURCES = node_macros.cxx | ||||||
| serialization_SOURCES = serialization.cxx | serialization_SOURCES = serialization.cxx | ||||||
| contain_serialization_SOURCES = contain_serialization.cxx | contain_serialization_SOURCES = contain_serialization.cxx | ||||||
|  | inherit_serialization_SOURCES = inherit_serialization.cxx | ||||||
|  | list_serialization_SOURCES = list_serialization.cxx | ||||||
|  |  | ||||||
| MAINTAINERCLEANFILES = makefile.in | MAINTAINERCLEANFILES = makefile.in | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ | |||||||
| #include <sstream> | #include <sstream> | ||||||
| #include <string> | #include <string> | ||||||
| #include <vector> | #include <vector> | ||||||
|  | #include <list> | ||||||
| #include <map> | #include <map> | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <typeinfo> | #include <typeinfo> | ||||||
| @@ -42,7 +43,12 @@ class MethodTrace { | |||||||
| }; | }; | ||||||
| #define TRACE MethodTrace XXX_METHOD(this, __PRETTY_FUNCTION__) | #define TRACE MethodTrace XXX_METHOD(this, __PRETTY_FUNCTION__) | ||||||
| #define LOG(X) std::clog<<__PRETTY_FUNCTION__<<"\t**** "<<X<<std::endl | #define LOG(X) std::clog<<__PRETTY_FUNCTION__<<"\t**** "<<X<<std::endl | ||||||
|  | #define ASSERT(X, Y) {                          \ | ||||||
|  |     if (!(Y)) {                                 \ | ||||||
|  |       LOG(X);                                   \ | ||||||
|  |     }                                           \ | ||||||
|  |     assert(Y);                                  \ | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /*! @mainpage | /*! @mainpage | ||||||
| @@ -578,6 +584,7 @@ namespace xml { | |||||||
|       virtual Node& set(const Attributes& o) throw(); |       virtual Node& set(const Attributes& o) throw(); | ||||||
|       Node& clear() throw (); |       Node& clear() throw (); | ||||||
|       std::string name() const throw(); |       std::string name() const throw(); | ||||||
|  |       Node& name(const std::string& n) throw(); | ||||||
|       Node& min(size_type m) throw(); |       Node& min(size_type m) throw(); | ||||||
|       size_type min() const throw(); |       size_type min() const throw(); | ||||||
|       Node& max(size_type m) throw(); |       Node& max(size_type m) throw(); | ||||||
| @@ -639,6 +646,7 @@ namespace xml { | |||||||
|       Node& operator=(const std::string& contents) throw(); |       Node& operator=(const std::string& contents) throw(); | ||||||
|       operator std::string() const throw(); |       operator std::string() const throw(); | ||||||
|       operator bool() const throw(); |       operator bool() const throw(); | ||||||
|  |       operator char() const throw(); | ||||||
|       operator signed char() const throw(); |       operator signed char() const throw(); | ||||||
|       operator unsigned char() const throw(); |       operator unsigned char() const throw(); | ||||||
|       operator signed short() const throw(); |       operator signed short() const throw(); | ||||||
| @@ -687,8 +695,12 @@ namespace xml { | |||||||
|                 duplicate_attribute, attributes_in_end_tag, |                 duplicate_attribute, attributes_in_end_tag, | ||||||
|                 illegal_attribute, mandatory_attribute_missing, |                 illegal_attribute, mandatory_attribute_missing, | ||||||
|                 wrong_node_number); |                 wrong_node_number); | ||||||
|  |       void reset() throw(); | ||||||
|     private: |     private: | ||||||
|       friend class stream_error; |       friend class stream_error; | ||||||
|  |       friend class Serialize; | ||||||
|  |       Node& operator*() throw(factory_not_valid); | ||||||
|  |       Node*const operator->() throw(factory_not_valid); | ||||||
|       bool ws(char c) throw(); |       bool ws(char c) throw(); | ||||||
|       std::auto_ptr<Node> read(std::istream& is, const Node& position) |       std::auto_ptr<Node> read(std::istream& is, const Node& position) | ||||||
|           throw(wrong_end_tag, wrong_start_tag, tag_expected, type_mismatch, |           throw(wrong_end_tag, wrong_start_tag, tag_expected, type_mismatch, | ||||||
| @@ -809,14 +821,78 @@ namespace xml { | |||||||
|       //! You must call Serialize::className() if you use this constructor! |       //! You must call Serialize::className() if you use this constructor! | ||||||
|       Serialize() throw(); |       Serialize() throw(); | ||||||
|       Serialize(const std::string& className) throw(); |       Serialize(const std::string& className) throw(); | ||||||
|  |       Serialize(const Serialize& other) throw(); | ||||||
|       virtual ~Serialize(); |       virtual ~Serialize(); | ||||||
|  |       Serialize& operator=(const Serialize& other) throw(); | ||||||
|       Serialize& className(const std::string& name) throw(); |       Serialize& className(const std::string& name) throw(); | ||||||
|       Serialize& persist(Serialize& ser) throw(); |       Serialize& persist(Serialize& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       template<typename TYPE, class ALLOC> | ||||||
|  |           Serialize& persist(std::list<TYPE, ALLOC>& member, | ||||||
|  |                              const std::string& name) throw() { | ||||||
|  |         return persist(member, name, name); | ||||||
|  |       } | ||||||
|  |       template<typename TYPE, class ALLOC> | ||||||
|  |           Serialize& persist(std::list<TYPE, ALLOC>& member, | ||||||
|  |                              const std::string& list, | ||||||
|  |                              const std::string& item) throw() { | ||||||
|  |         mapName<std::list<TYPE, ALLOC> >()[std::make_pair(this, list)] | ||||||
|  |           = &member; | ||||||
|  |         mapMember<std::list<TYPE, ALLOC> >()[&member] = list; | ||||||
|  |         _xmlNames[list] = &typeid(TYPE); | ||||||
|  |         Serialize ser(list); | ||||||
|  |         TYPE dummy; | ||||||
|  |         ser.persist(dummy, item); | ||||||
|  |         *_xmlFactory<<(xml::Node(list).limits(1,1) | ||||||
|  |                        <<(*ser._xmlFactory)[0].limits(0, 0)); | ||||||
|  |         return *this; | ||||||
|  |       } | ||||||
|  |       Serialize& persist(bool& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       Serialize& persist(char& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       Serialize& persist(unsigned char& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       Serialize& persist(signed char& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       Serialize& persist(unsigned short& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       Serialize& persist(signed short& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       Serialize& persist(unsigned int& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       Serialize& persist(signed int& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       Serialize& persist(unsigned long& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       Serialize& persist(signed long& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       Serialize& persist(float& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       Serialize& persist(double& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       Serialize& persist(std::string& member, | ||||||
|  |                          const std::string& name) throw(); | ||||||
|  |       std::ostream& saveXml(std::ostream& os, | ||||||
|  |                             const std::string& name = std::string()) const throw(); | ||||||
|  |       std::istream& loadXml(std::istream& is, | ||||||
|  |                             const std::string& name = std::string()); | ||||||
|  |       std::string schema() const throw(); | ||||||
|  |     protected: | ||||||
|  |       virtual void initXmlMembers(); | ||||||
|  |     private: | ||||||
|  |       void clear() throw(); | ||||||
|  |       void copy(const Serialize& o) throw(); | ||||||
|       template<typename TYPE> |       template<typename TYPE> | ||||||
|           Serialize& persist(TYPE& member, const std::string& name) throw() { |           Serialize& persistSimpleType(TYPE& member, | ||||||
|         assert(mapName<TYPE>().find(std::make_pair(this, name))==mapName<TYPE>().end()); |                                        const std::string& name) throw() { | ||||||
|         assert(mapMember<TYPE>().find(&member)==mapMember<TYPE>().end()); |         ASSERT("type: "<<typeid(TYPE).name()<<"; name="<<name, | ||||||
|         assert(_xmlNames.find(name)==_xmlNames.end()); |                mapName<TYPE>().find(std::make_pair(this, name)) | ||||||
|  |                ==mapName<TYPE>().end()); | ||||||
|  |         ASSERT("type: "<<typeid(TYPE).name()<<"; name="<<name, | ||||||
|  |                mapMember<TYPE>().find(&member)==mapMember<TYPE>().end()); | ||||||
|  |         ASSERT("type: "<<typeid(TYPE).name()<<"; name="<<name, | ||||||
|  |                _xmlNames.find(name)==_xmlNames.end()); | ||||||
|         mapName<TYPE>()[std::make_pair(this, name)] = &member; |         mapName<TYPE>()[std::make_pair(this, name)] = &member; | ||||||
|         mapMember<TYPE>()[&member] = name; |         mapMember<TYPE>()[&member] = name; | ||||||
|         _xmlNames[name] = &typeid(TYPE); |         _xmlNames[name] = &typeid(TYPE); | ||||||
| @@ -825,11 +901,6 @@ namespace xml { | |||||||
|         _xmlFactory = schema; |         _xmlFactory = schema; | ||||||
|         return *this; |         return *this; | ||||||
|       } |       } | ||||||
|       std::ostream& saveXml(std::ostream& os) const throw(); |  | ||||||
|       std::istream& loadXml(std::istream& is); |  | ||||||
|     protected: |  | ||||||
|       virtual void initXmlMembers(); |  | ||||||
|     private: |  | ||||||
|       template<typename TYPE> |       template<typename TYPE> | ||||||
|           std::map<std::pair<const Serialize*, std::string>, TYPE*>& |           std::map<std::pair<const Serialize*, std::string>, TYPE*>& | ||||||
|           mapName() const { |           mapName() const { | ||||||
| @@ -841,13 +912,19 @@ namespace xml { | |||||||
|         return MAP; |         return MAP; | ||||||
|       } |       } | ||||||
|       template<typename TYPE> void fromNode(TYPE* member, xml::Node& node) { |       template<typename TYPE> void fromNode(TYPE* member, xml::Node& node) { | ||||||
|         *member = |         *member = (TYPE)dynamic_cast<xml::String&>(node); | ||||||
|           (TYPE)dynamic_cast<xml::String&>(node[mapMember<TYPE>()[member]]); |  | ||||||
|       } |       } | ||||||
|  |       /* | ||||||
|  |       template<typename TYPE, class ALLOC> | ||||||
|  |           void fromNode(std::list<TYPE, ALLOC>* member, xml::Node& node) { | ||||||
|  |         member->clear(); | ||||||
|  |         for (xml::Node::size_type i(0); i<node.children(); ++i) | ||||||
|  |           ... | ||||||
|  |           }*/ | ||||||
|       template<typename TYPE> void toNode(TYPE* member, xml::Node& node) const { |       template<typename TYPE> void toNode(TYPE* member, xml::Node& node) const { | ||||||
|         std::stringstream ss; |         std::stringstream ss; | ||||||
|         ss<<*member; |         ss<<*member; | ||||||
|         node[mapMember<TYPE>()[member]].text(ss.str()); |         node.text(ss.str()); | ||||||
|       } |       } | ||||||
|       std::map<std::string, const std::type_info*> _xmlNames; |       std::map<std::string, const std::type_info*> _xmlNames; | ||||||
|       xml::Factory _xmlFactory; |       xml::Factory _xmlFactory; | ||||||
|   | |||||||
							
								
								
									
										286
									
								
								src/xml.cxx
									
									
									
									
									
								
							
							
						
						
									
										286
									
								
								src/xml.cxx
									
									
									
									
									
								
							| @@ -330,6 +330,11 @@ namespace xml { | |||||||
|   std::string Node::name() const throw() { |   std::string Node::name() const throw() { | ||||||
|     return _name; |     return _name; | ||||||
|   } |   } | ||||||
|  |   //! Set a new node's tag name. | ||||||
|  |   Node& Node::name(const std::string& n) throw() { | ||||||
|  |     _name = n; | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|   //! Set minimum number of instances (in a xml::Factory). |   //! Set minimum number of instances (in a xml::Factory). | ||||||
|   /*! @copydoc limits */ |   /*! @copydoc limits */ | ||||||
|   Node& Node::min(Node::size_type m) throw() { |   Node& Node::min(Node::size_type m) throw() { | ||||||
| @@ -598,6 +603,12 @@ namespace xml { | |||||||
|     ss>>res; |     ss>>res; | ||||||
|     return res; |     return res; | ||||||
|   } |   } | ||||||
|  |   String::operator char() const throw() { | ||||||
|  |     char res; | ||||||
|  |     std::stringstream ss(text()); | ||||||
|  |     ss>>res; | ||||||
|  |     return res; | ||||||
|  |   } | ||||||
|   String::operator signed char() const throw() { |   String::operator signed char() const throw() { | ||||||
|     signed char res; |     signed char res; | ||||||
|     std::stringstream ss(text()); |     std::stringstream ss(text()); | ||||||
| @@ -849,6 +860,21 @@ namespace xml { | |||||||
|     e.line(_line); |     e.line(_line); | ||||||
|     throw; |     throw; | ||||||
|   } |   } | ||||||
|  |   void Factory::reset() throw() { | ||||||
|  |     _line = 0; | ||||||
|  |     _open = 0; | ||||||
|  |     _template = xml::Node("<xml::start>"); | ||||||
|  |   } | ||||||
|  |   Node& Factory::operator*() throw(factory_not_valid) try { | ||||||
|  |     return _template[0]; | ||||||
|  |   } catch (...) { | ||||||
|  |     throw factory_not_valid(); | ||||||
|  |   } | ||||||
|  |   Node*const Factory::operator->() throw(factory_not_valid) try { | ||||||
|  |     return &_template[0]; | ||||||
|  |   } catch (...) { | ||||||
|  |     throw factory_not_valid(); | ||||||
|  |   } | ||||||
|   bool Factory::ws(char c) throw() { |   bool Factory::ws(char c) throw() { | ||||||
|     static char last(0); |     static char last(0); | ||||||
|     if ((c=='\n'||c=='\r')&&last!='\n'&&last!='\r') ++_line; |     if ((c=='\n'||c=='\r')&&last!='\n'&&last!='\r') ++_line; | ||||||
| @@ -995,22 +1021,184 @@ namespace xml { | |||||||
|                                                  xml::Node& node) { |                                                  xml::Node& node) { | ||||||
|     //! @todo improve this (inefficient) |     //! @todo improve this (inefficient) | ||||||
|     std::stringstream ss; // simple but inefficient: rewrite and reread |     std::stringstream ss; // simple but inefficient: rewrite and reread | ||||||
|     ss<<node[member->_xmlFactory->name()]; |     ss<<node; | ||||||
|     member->loadXml(ss); |     member->loadXml(ss, node.name()); | ||||||
|   } |   } | ||||||
|   template<> void Serialize::toNode<Serialize>(Serialize* member, |   template<> void Serialize::toNode<Serialize>(Serialize* member, | ||||||
|                                     xml::Node& node) const { |                                                xml::Node& node) const { | ||||||
|     //! @todo improve this (inefficient) |     std::stringstream ss; | ||||||
|     std::stringstream ss; // simple but inefficient: write and reread |     member->saveXml(ss, node.name()); | ||||||
|     member->saveXml(ss); |     xml::Factory factory(node); | ||||||
|     node[member->_xmlFactory->name()] = *member->_xmlFactory.read(ss); |     node = *factory.read(ss); | ||||||
|   } |   } | ||||||
|   //---------------------------------------------------------------------------- |   //---------------------------------------------------------------------------- | ||||||
|   Serialize::Serialize() throw() {} |   Serialize::Serialize() throw() {} | ||||||
|   Serialize::Serialize(const std::string& className) throw(): |   Serialize::Serialize(const std::string& className) throw(): | ||||||
|       _xmlFactory(xml::Node(xml::String(className).limits(1,1))) { |       _xmlFactory(xml::Node(xml::String(className).limits(1,1))) { | ||||||
|   } |   } | ||||||
|  |   Serialize::Serialize(const Serialize& other) throw() { | ||||||
|  |     copy(other); | ||||||
|  |   } | ||||||
|   Serialize::~Serialize() { |   Serialize::~Serialize() { | ||||||
|  |     clear(); | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::operator=(const Serialize& other) throw() { | ||||||
|  |     copy(other); | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::className(const std::string& name) throw() { | ||||||
|  |     xml::Node node(xml::Node(xml::String(name).limits(1,1))); | ||||||
|  |     if (_xmlFactory) { | ||||||
|  |       for (xml::Node::size_type i(0); i<_xmlFactory->children(); ++i) | ||||||
|  |         node<<(*_xmlFactory)[i]; | ||||||
|  |     } | ||||||
|  |     _xmlFactory=node; | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(Serialize& ser, | ||||||
|  |                                 const std::string& name) throw() { | ||||||
|  |     if (!ser._xmlFactory) ser.initXmlMembers(); | ||||||
|  |     mapName<Serialize>()[std::make_pair(this, name)] = &ser; | ||||||
|  |     mapMember<Serialize>()[&ser] = name; | ||||||
|  |     _xmlNames[name] = &typeid(Serialize); | ||||||
|  |     xml::Node schema(*_xmlFactory); | ||||||
|  |     xml::Node node(xml::Node(name).limits(1,1)); | ||||||
|  |     for (xml::Node::size_type i(0); i<ser._xmlFactory->children(); ++i) | ||||||
|  |       node<<(*ser._xmlFactory)[i]; | ||||||
|  |     _xmlFactory = schema<<node; | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(bool& member, | ||||||
|  |                                 const std::string& name) throw() { | ||||||
|  |     return persistSimpleType(member, name); | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(char& member, | ||||||
|  |                                 const std::string& name) throw() { | ||||||
|  |     return persistSimpleType(member, name); | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(unsigned char& member, | ||||||
|  |                                 const std::string& name) throw() { | ||||||
|  |     return persistSimpleType(member, name); | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(signed char& member, | ||||||
|  |                                 const std::string& name) throw() { | ||||||
|  |     return persistSimpleType(member, name); | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(unsigned short& member, | ||||||
|  |                                 const std::string& name) throw() { | ||||||
|  |     return persistSimpleType(member, name); | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(signed short& member, | ||||||
|  |                                 const std::string& name) throw() { | ||||||
|  |     return persistSimpleType(member, name); | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(unsigned int& member, | ||||||
|  |                                const std::string& name) throw() { | ||||||
|  |     return persistSimpleType(member, name); | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(signed int& member, | ||||||
|  |                                 const std::string& name) throw() { | ||||||
|  |     return persistSimpleType(member, name); | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(unsigned long& member, | ||||||
|  |                                 const std::string& name) throw() { | ||||||
|  |     return persistSimpleType(member, name); | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(signed long& member, | ||||||
|  |                                 const std::string& name) throw() { | ||||||
|  |     return persistSimpleType(member, name); | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(float& member, | ||||||
|  |                                 const std::string& name) throw() { | ||||||
|  |     return persistSimpleType(member, name); | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(double& member, | ||||||
|  |                                 const std::string& name) throw() { | ||||||
|  |     return persistSimpleType(member, name); | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(std::string& member, | ||||||
|  |                                 const std::string& name) throw() { | ||||||
|  |     return persistSimpleType(member, name); | ||||||
|  |   } | ||||||
|  |   std::ostream& Serialize::saveXml(std::ostream& os, | ||||||
|  |                                    const std::string& name) const throw() { | ||||||
|  |     if (!_xmlFactory) const_cast<Serialize*>(this)->initXmlMembers(); | ||||||
|  |     xml::Node node(*_xmlFactory); | ||||||
|  |     if (name.size()) node.name(name); | ||||||
|  |     for (std::map<std::string, const std::type_info*>::const_iterator | ||||||
|  |            it(_xmlNames.begin()); | ||||||
|  |          it!=_xmlNames.end(); ++it) { | ||||||
|  | #define QWERTZ_CHECK_TYPE_ZTREWQ___XXX(TYPE)                            \ | ||||||
|  |       if (*it->second==typeid(TYPE))                                    \ | ||||||
|  |         toNode(mapName<TYPE>()[std::make_pair(this, it->first)],        \ | ||||||
|  |                node[it->first]);                                        \ | ||||||
|  |       else | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(Serialize) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(std::string) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(float) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(double) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(bool) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(char) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed char) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned char) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(short) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed short) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned short) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(int) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed int) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned int) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(long) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed long) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned long) | ||||||
|  |       throw std::runtime_error(it->second->name()); | ||||||
|  | #undef QWERTZ_CHECK_TYPE_ZTREWQ___XXX | ||||||
|  |     }       | ||||||
|  |     os<<node; | ||||||
|  |     return os; | ||||||
|  |   } | ||||||
|  |   std::istream& Serialize::loadXml(std::istream& is, const std::string& name) { | ||||||
|  |     if (!_xmlFactory) initXmlMembers(); | ||||||
|  |     xml::Factory factory(_xmlFactory); | ||||||
|  |     if (name.size()) factory->name(name); | ||||||
|  |     std::auto_ptr<xml::Node> node(factory.read(is)); | ||||||
|  |     for (std::map<std::string, const std::type_info*>::const_iterator | ||||||
|  |            it(_xmlNames.begin()); | ||||||
|  |          it!=_xmlNames.end(); ++it) { | ||||||
|  | #define QWERTZ_CHECK_TYPE_ZTREWQ___XXX(TYPE)                            \ | ||||||
|  |       if (*it->second==typeid(TYPE))                                    \ | ||||||
|  |         fromNode(mapName<TYPE>()[std::make_pair(this, it->first)],      \ | ||||||
|  |                  (*node)[it->first]);                                   \ | ||||||
|  |       else | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(Serialize) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(std::string) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(float) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(double) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(bool) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(char) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed char) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned char) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(short) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed short) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned short) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(int) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed int) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned int) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(long) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed long) | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned long) | ||||||
|  |       throw std::runtime_error(it->second->name()); | ||||||
|  | #undef QWERTZ_CHECK_TYPE_ZTREWQ___XXX | ||||||
|  |     } | ||||||
|  |     return is; | ||||||
|  |   } | ||||||
|  |   std::string Serialize::schema() const throw() { | ||||||
|  |     if (!_xmlFactory) const_cast<Serialize*>(this)->initXmlMembers(); | ||||||
|  |     std::stringstream ss; | ||||||
|  |     ss<<*_xmlFactory; | ||||||
|  |     return ss.str(); | ||||||
|  |   } | ||||||
|  |   void Serialize::initXmlMembers() {} | ||||||
|  |   void Serialize::clear() throw() { | ||||||
|     // Remove my entries from the maps |     // Remove my entries from the maps | ||||||
|     for (std::map<std::string, const std::type_info*>::const_iterator |     for (std::map<std::string, const std::type_info*>::const_iterator | ||||||
|            it(_xmlNames.begin()); |            it(_xmlNames.begin()); | ||||||
| @@ -1042,86 +1230,10 @@ namespace xml { | |||||||
| #undef QWERTZ_CHECK_TYPE_ZTREWQ___XXX | #undef QWERTZ_CHECK_TYPE_ZTREWQ___XXX | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   Serialize& Serialize::className(const std::string& name) throw() { |   void Serialize::copy(const Serialize& o) throw() { | ||||||
|     _xmlFactory=xml::Node(xml::String(name).limits(1,1)); |     clear(); | ||||||
|     return *this; |     _xmlFactory.reset(); | ||||||
|  |     initXmlMembers(); | ||||||
|   } |   } | ||||||
|   Serialize& Serialize::persist(Serialize& ser) throw() { |  | ||||||
|     ser.initXmlMembers(); |  | ||||||
|     std::string name(ser._xmlFactory->name()); |  | ||||||
|     mapName<Serialize>()[std::make_pair(this, name)] = &ser; |  | ||||||
|     mapMember<Serialize>()[&ser] = name; |  | ||||||
|     _xmlNames[name] = &typeid(Serialize); |  | ||||||
|     xml::Node schema(*_xmlFactory); |  | ||||||
|     schema<<*ser._xmlFactory; |  | ||||||
|     _xmlFactory = schema; |  | ||||||
|     return *this; |  | ||||||
|   } |  | ||||||
|   std::ostream& Serialize::saveXml(std::ostream& os) const throw() { |  | ||||||
|     if (!_xmlFactory) const_cast<Serialize*>(this)->initXmlMembers(); |  | ||||||
|     xml::Node node(*_xmlFactory); |  | ||||||
|     for (std::map<std::string, const std::type_info*>::const_iterator |  | ||||||
|            it(_xmlNames.begin()); |  | ||||||
|          it!=_xmlNames.end(); ++it) { |  | ||||||
| #define QWERTZ_CHECK_TYPE_ZTREWQ___XXX(TYPE)                            \ |  | ||||||
|       if (*it->second==typeid(TYPE))                                    \ |  | ||||||
|         toNode(mapName<TYPE>()[std::make_pair(this, it->first)], node); \ |  | ||||||
|       else |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(Serialize) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(std::string) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(float) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(double) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(bool) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(char) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed char) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned char) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(short) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed short) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned short) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(int) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed int) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned int) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(long) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed long) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned long) |  | ||||||
|       throw std::runtime_error(it->second->name()); |  | ||||||
| #undef QWERTZ_CHECK_TYPE_ZTREWQ___XXX |  | ||||||
|     }       |  | ||||||
|     os<<node; |  | ||||||
|     return os; |  | ||||||
|   } |  | ||||||
|   std::istream& Serialize::loadXml(std::istream& is) { |  | ||||||
|     if (!_xmlFactory) initXmlMembers(); |  | ||||||
|     std::auto_ptr<xml::Node> node(_xmlFactory.read(is)); |  | ||||||
|     for (std::map<std::string, const std::type_info*>::const_iterator |  | ||||||
|            it(_xmlNames.begin()); |  | ||||||
|          it!=_xmlNames.end(); ++it) { |  | ||||||
| #define QWERTZ_CHECK_TYPE_ZTREWQ___XXX(TYPE)                               \ |  | ||||||
|       if (*it->second==typeid(TYPE))                                       \ |  | ||||||
|         fromNode(mapName<TYPE>()[std::make_pair(this, it->first)], *node); \ |  | ||||||
|       else |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(Serialize) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(std::string) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(float) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(double) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(bool) |  | ||||||
|       //QWERTZ_CHECK_TYPE_ZTREWQ___XXX(char) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed char) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned char) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(short) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed short) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned short) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(int) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed int) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned int) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(long) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(signed long) |  | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(unsigned long) |  | ||||||
|       throw std::runtime_error(it->second->name()); |  | ||||||
| #undef QWERTZ_CHECK_TYPE_ZTREWQ___XXX |  | ||||||
|     } |  | ||||||
|     return is; |  | ||||||
|   } |  | ||||||
|   void Serialize::initXmlMembers() {} |  | ||||||
|    |    | ||||||
| } | } | ||||||
|   | |||||||
| @@ -31,6 +31,58 @@ class A: public xml::Serialize { | |||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | class B: public xml::Serialize { | ||||||
|  |   public: | ||||||
|  |     long aLong; | ||||||
|  |     char aChar; | ||||||
|  |   protected: | ||||||
|  |     void initXmlMembers() { | ||||||
|  |       className("B"); | ||||||
|  |       persist(aLong, "aLong"); | ||||||
|  |       persist(aChar, "aChar"); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class B2: public B { | ||||||
|  |   public: | ||||||
|  |     float aFloat; | ||||||
|  |     short aShort; | ||||||
|  |   protected: | ||||||
|  |     void initXmlMembers() { | ||||||
|  |       B::initXmlMembers(); | ||||||
|  |       className("B2"); | ||||||
|  |       persist(aFloat, "float"); | ||||||
|  |       persist(aShort, "short"); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // Complex Example: Class A2 is a class that inherits another class | ||||||
|  | // (A) and contains a class (B2) that inherits another class (B) | ||||||
|  | class A2: public A { | ||||||
|  |   public: | ||||||
|  |     std::string aText; | ||||||
|  |     B2 childOfB; | ||||||
|  |   protected: | ||||||
|  |     void initXmlMembers() { | ||||||
|  |       A::initXmlMembers(); | ||||||
|  |       className("A2"); | ||||||
|  |       persist(aText, "aText"); | ||||||
|  |       persist(childOfB, "childOfB"); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class C: public xml::Serialize { | ||||||
|  |   public: | ||||||
|  |     A2 a2; | ||||||
|  |     B2 b2; | ||||||
|  |   protected: | ||||||
|  |     void initXmlMembers() { | ||||||
|  |       className("C") | ||||||
|  |         .persist(a2, "a2") | ||||||
|  |         .persist(b2, "b2"); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  |  | ||||||
| class SerializationTest: public CppUnit::TestFixture { | class SerializationTest: public CppUnit::TestFixture { | ||||||
|   public: |   public: | ||||||
|     std::string _file; |     std::string _file; | ||||||
| @@ -91,10 +143,203 @@ class SerializationTest: public CppUnit::TestFixture { | |||||||
|                            a._anotherString); |                            a._anotherString); | ||||||
|       CPPUNIT_ASSERT_EQUAL(4123674622ul, a._aLong); |       CPPUNIT_ASSERT_EQUAL(4123674622ul, a._aLong); | ||||||
|     } |     } | ||||||
|  |     void complexLoad() { | ||||||
|  |       std::stringstream ss("<A2>\n" | ||||||
|  |                            "  <anInteger>-1234</anInteger>\n" | ||||||
|  |                            "  <aBool>1</aBool>\n" | ||||||
|  |                            "  <aDouble>3.141</aDouble>\n" | ||||||
|  |                            "  <aString>This is A inside of A2</aString>\n" | ||||||
|  |                            "  <anotherString>Another A-String</anotherString>\n" | ||||||
|  |                            "  <aLong>1234567890</aLong>\n" | ||||||
|  |                            "  <aText>Text from A2</aText>\n" | ||||||
|  |                            "  <childOfB>\n" | ||||||
|  |                            "      <aLong>987654321</aLong>\n" | ||||||
|  |                            "      <aChar>Q</aChar>\n" | ||||||
|  |                            "      <float>2.5</float>\n" | ||||||
|  |                            "      <short>-127</short>\n" | ||||||
|  |                            "  </childOfB>\n" | ||||||
|  |                            "</A2>"); | ||||||
|  |       A2 a2; | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(std::string("<A2>\n" | ||||||
|  |                                        "\t<anInteger/>\n" | ||||||
|  |                                        "\t<aBool/>\n" | ||||||
|  |                                        "\t<aDouble/>\n" | ||||||
|  |                                        "\t<aString/>\n" | ||||||
|  |                                        "\t<anotherString/>\n" | ||||||
|  |                                        "\t<aLong/>\n" | ||||||
|  |                                        "\t<aText/>\n" | ||||||
|  |                                        "\t<childOfB>\n" | ||||||
|  |                                        "\t\t<aLong/>\n" | ||||||
|  |                                        "\t\t<aChar/>\n" | ||||||
|  |                                        "\t\t<float/>\n" | ||||||
|  |                                        "\t\t<short/>\n" | ||||||
|  |                                        "\t</childOfB>\n" | ||||||
|  |                                        "</A2>"), a2.schema()); | ||||||
|  |       CPPUNIT_ASSERT_NO_THROW(a2.loadXml(ss)); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(-1234, a2._anInteger); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(true, a2._aBool); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(3.141, a2._aDouble); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(std::string("This is A inside of A2"), a2._aString); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(std::string("Another A-String"), a2._anotherString); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(1234567890ul, a2._aLong); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(std::string("Text from A2"), a2.aText); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(987654321l, a2.childOfB.aLong); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL('Q', a2.childOfB.aChar); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(2.5f, a2.childOfB.aFloat); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL((short)-127, a2.childOfB.aShort); | ||||||
|  |     } | ||||||
|  |     void complexSave() { | ||||||
|  |       A2 a2; | ||||||
|  |       a2._anInteger = -1234; | ||||||
|  |       a2._aBool = true; | ||||||
|  |       a2._aDouble = 3.141; | ||||||
|  |       a2._aString = std::string("This is A inside of A2"); | ||||||
|  |       a2._anotherString = std::string("Another A-String"); | ||||||
|  |       a2._aLong = 1234567890ul; | ||||||
|  |       a2.aText = std::string("Text from A2"); | ||||||
|  |       a2.childOfB.aLong = 987654321l; | ||||||
|  |       a2.childOfB.aChar = 'Q'; | ||||||
|  |       a2.childOfB.aFloat = 2.5f; | ||||||
|  |       a2.childOfB.aShort = (short)-127; | ||||||
|  |       std::stringstream ss; | ||||||
|  |       a2.saveXml(ss); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL | ||||||
|  |         (std::string("<A2>\n" | ||||||
|  |                      "\t<anInteger>-1234</anInteger>\n" | ||||||
|  |                      "\t<aBool>1</aBool>\n" | ||||||
|  |                      "\t<aDouble>3.141</aDouble>\n" | ||||||
|  |                      "\t<aString>This is A inside of A2</aString>\n" | ||||||
|  |                      "\t<anotherString>Another A-String</anotherString>\n" | ||||||
|  |                      "\t<aLong>1234567890</aLong>\n" | ||||||
|  |                      "\t<aText>Text from A2</aText>\n" | ||||||
|  |                      "\t<childOfB>\n" | ||||||
|  |                      "\t\t<aLong>987654321</aLong>\n" | ||||||
|  |                      "\t\t<aChar>Q</aChar>\n" | ||||||
|  |                      "\t\t<float>2.5</float>\n" | ||||||
|  |                      "\t\t<short>-127</short>\n" | ||||||
|  |                      "\t</childOfB>\n" | ||||||
|  |                      "</A2>"), ss.str()); | ||||||
|  |     } | ||||||
|  |     void moreComplexLoad() { | ||||||
|  |       std::stringstream ss | ||||||
|  |         ("<C>\n" | ||||||
|  |          "  <a2>\n" | ||||||
|  |          "    <anInteger>-1234</anInteger>\n" | ||||||
|  |          "    <aBool>1</aBool>\n" | ||||||
|  |          "    <aDouble>3.141</aDouble>\n" | ||||||
|  |          "    <aString>This is A inside of A2</aString>\n" | ||||||
|  |          "    <anotherString>Another A-String</anotherString>\n" | ||||||
|  |          "    <aLong>1234567890</aLong>\n" | ||||||
|  |          "    <aText>Text from A2</aText>\n" | ||||||
|  |          "    <childOfB>\n" | ||||||
|  |          "      <aLong>987654321</aLong>\n" | ||||||
|  |          "      <aChar>Q</aChar>\n" | ||||||
|  |          "      <float>2.5</float>\n" | ||||||
|  |          "      <short>-127</short>\n" | ||||||
|  |          "    </childOfB>\n" | ||||||
|  |          "  </a2>\n" | ||||||
|  |          "  <b2>\n" | ||||||
|  |          "    <aLong>212121</aLong>\n" | ||||||
|  |          "    <aChar>W</aChar>\n" | ||||||
|  |          "    <float>2.25</float>\n" | ||||||
|  |          "    <short>124</short>\n" | ||||||
|  |          "  </b2>\n" | ||||||
|  |          "</C>"); | ||||||
|  |       C c; | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(std::string("<C>\n" | ||||||
|  |                                        "\t<a2>\n" | ||||||
|  |                                        "\t\t<anInteger/>\n" | ||||||
|  |                                        "\t\t<aBool/>\n" | ||||||
|  |                                        "\t\t<aDouble/>\n" | ||||||
|  |                                        "\t\t<aString/>\n" | ||||||
|  |                                        "\t\t<anotherString/>\n" | ||||||
|  |                                        "\t\t<aLong/>\n" | ||||||
|  |                                        "\t\t<aText/>\n" | ||||||
|  |                                        "\t\t<childOfB>\n" | ||||||
|  |                                        "\t\t\t<aLong/>\n" | ||||||
|  |                                        "\t\t\t<aChar/>\n" | ||||||
|  |                                        "\t\t\t<float/>\n" | ||||||
|  |                                        "\t\t\t<short/>\n" | ||||||
|  |                                        "\t\t</childOfB>\n" | ||||||
|  |                                        "\t</a2>\n" | ||||||
|  |                                        "\t<b2>\n" | ||||||
|  |                                        "\t\t<aLong/>\n" | ||||||
|  |                                        "\t\t<aChar/>\n" | ||||||
|  |                                        "\t\t<float/>\n" | ||||||
|  |                                        "\t\t<short/>\n" | ||||||
|  |                                        "\t</b2>\n" | ||||||
|  |                                        "</C>"), c.schema()); | ||||||
|  |       CPPUNIT_ASSERT_NO_THROW(c.loadXml(ss)); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(-1234, c.a2._anInteger); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(true, c.a2._aBool); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(3.141, c.a2._aDouble); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(std::string("This is A inside of A2"), | ||||||
|  |                            c.a2._aString); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(std::string("Another A-String"), | ||||||
|  |                            c.a2._anotherString); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(1234567890ul, c.a2._aLong); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(std::string("Text from A2"), c.a2.aText); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(987654321l, c.a2.childOfB.aLong); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL('Q', c.a2.childOfB.aChar); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(2.5f, c.a2.childOfB.aFloat); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL((short)-127, c.a2.childOfB.aShort); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(212121l, c.b2.aLong); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL('W', c.b2.aChar); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL(2.25f, c.b2.aFloat); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL((short)124, c.b2.aShort); | ||||||
|  |     } | ||||||
|  |     void moreComplexSave() { | ||||||
|  |       C c; | ||||||
|  |       c.a2._anInteger = -1234; | ||||||
|  |       c.a2._aBool = true; | ||||||
|  |       c.a2._aDouble = 3.141; | ||||||
|  |       c.a2._aString = std::string("This is A inside of A2"); | ||||||
|  |       c.a2._anotherString = std::string("Another A-String"); | ||||||
|  |       c.a2._aLong = 1234567890ul; | ||||||
|  |       c.a2.aText = std::string("Text from A2"); | ||||||
|  |       c.a2.childOfB.aLong = 987654321l; | ||||||
|  |       c.a2.childOfB.aChar = 'Q'; | ||||||
|  |       c.a2.childOfB.aFloat = 2.5f; | ||||||
|  |       c.a2.childOfB.aShort = (short)-127; | ||||||
|  |       c.b2.aLong = 212121l; | ||||||
|  |       c.b2.aChar = 'W'; | ||||||
|  |       c.b2.aFloat = 2.25f; | ||||||
|  |       c.b2.aShort = (short)124; | ||||||
|  |       std::stringstream ss; | ||||||
|  |       c.saveXml(ss); | ||||||
|  |       CPPUNIT_ASSERT_EQUAL | ||||||
|  |         (std::string("<C>\n" | ||||||
|  |                      "\t<a2>\n" | ||||||
|  |                      "\t\t<anInteger>-1234</anInteger>\n" | ||||||
|  |                      "\t\t<aBool>1</aBool>\n" | ||||||
|  |                      "\t\t<aDouble>3.141</aDouble>\n" | ||||||
|  |                      "\t\t<aString>This is A inside of A2</aString>\n" | ||||||
|  |                      "\t\t<anotherString>Another A-String</anotherString>\n" | ||||||
|  |                      "\t\t<aLong>1234567890</aLong>\n" | ||||||
|  |                      "\t\t<aText>Text from A2</aText>\n" | ||||||
|  |                      "\t\t<childOfB>\n" | ||||||
|  |                      "\t\t\t<aLong>987654321</aLong>\n" | ||||||
|  |                      "\t\t\t<aChar>Q</aChar>\n" | ||||||
|  |                      "\t\t\t<float>2.5</float>\n" | ||||||
|  |                      "\t\t\t<short>-127</short>\n" | ||||||
|  |                      "\t\t</childOfB>\n" | ||||||
|  |                      "\t</a2>\n" | ||||||
|  |                      "\t<b2>\n" | ||||||
|  |                      "\t\t<aLong>212121</aLong>\n" | ||||||
|  |                      "\t\t<aChar>W</aChar>\n" | ||||||
|  |                      "\t\t<float>2.25</float>\n" | ||||||
|  |                      "\t\t<short>124</short>\n" | ||||||
|  |                      "\t</b2>\n" | ||||||
|  |                      "</C>"), ss.str()); | ||||||
|  |     } | ||||||
|     CPPUNIT_TEST_SUITE(SerializationTest); |     CPPUNIT_TEST_SUITE(SerializationTest); | ||||||
|     CPPUNIT_TEST(memberDeclaration); |     CPPUNIT_TEST(memberDeclaration); | ||||||
|     CPPUNIT_TEST(store); |     CPPUNIT_TEST(store); | ||||||
|     CPPUNIT_TEST(restore); |     CPPUNIT_TEST(restore); | ||||||
|  |     CPPUNIT_TEST(complexLoad); | ||||||
|  |     CPPUNIT_TEST(complexSave); | ||||||
|  |     CPPUNIT_TEST(moreComplexLoad); | ||||||
|  |     CPPUNIT_TEST(moreComplexSave); | ||||||
|     CPPUNIT_TEST_SUITE_END(); |     CPPUNIT_TEST_SUITE_END(); | ||||||
| }; | }; | ||||||
| CPPUNIT_TEST_SUITE_REGISTRATION(SerializationTest); | CPPUNIT_TEST_SUITE_REGISTRATION(SerializationTest); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user