serialization nearly ready for containment
This commit is contained in:
		
							
								
								
									
										59
									
								
								doc/examples/contain_serialization.cxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								doc/examples/contain_serialization.cxx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | |||||||
|  | /*! @file | ||||||
|  |  | ||||||
|  |     @id $Id: inherit_serialization.cxx 25 2009-04-23 15:10:21Z  $ | ||||||
|  | */ | ||||||
|  | //       1         2         3         4         5         6         7         8 | ||||||
|  | // 45678901234567890123456789012345678901234567890123456789012345678901234567890 | ||||||
|  |  | ||||||
|  | // g++ -I../../src ../../src/xml.cxx contain_serialization.cxx | ||||||
|  |  | ||||||
|  | #include <xml-cxx/xml.hxx> | ||||||
|  | #include <iostream> | ||||||
|  | #include <sstream> | ||||||
|  |  | ||||||
|  | class A: public xml::Serialize { | ||||||
|  |   public: | ||||||
|  |     int a; | ||||||
|  |     std::string txt; | ||||||
|  |   protected: | ||||||
|  |     void initXmlMembers() { | ||||||
|  |       className("a") | ||||||
|  |         .persist(a, "a") | ||||||
|  |         .persist(txt, "txt"); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class B: public xml::Serialize { | ||||||
|  |   public: | ||||||
|  |     int i; | ||||||
|  |     std::string txt; | ||||||
|  |     A a; | ||||||
|  |   protected: | ||||||
|  |     void initXmlMembers() { | ||||||
|  |       className("b") | ||||||
|  |         .persist(i, "i") | ||||||
|  |         .persist(txt, "txt") | ||||||
|  |         .persist(a); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | int main(int, char**) { | ||||||
|  |   { // Serialization as a member | ||||||
|  |     std::stringstream ss("<b>\n" | ||||||
|  |                          "\t<i>1234</i>\n" | ||||||
|  |                          "\t<txt>Dies ist Class B</txt>\n" | ||||||
|  |                          "\t<a>\n" | ||||||
|  |                          "\t\t<a>5678</a>\n" | ||||||
|  |                          "\t\t<txt>Dies ist Class A</txt>\n" | ||||||
|  |                          "\t</a>" | ||||||
|  |                          "</b>"); | ||||||
|  |     B b; | ||||||
|  |     b.loadXml(ss); | ||||||
|  |     if (b.i==1234) b.i=4321; | ||||||
|  |     if (b.a.a==5678) b.a.a=8765; | ||||||
|  |     std::cout<<"Text B: "<<b.txt<<std::endl; | ||||||
|  |     std::cout<<"Text A: "<<b.a.txt<<std::endl; | ||||||
|  |     b.saveXml(std::cout)<<std::endl; | ||||||
|  |   } | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
| @@ -11,7 +11,7 @@ | |||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <sstream> | #include <sstream> | ||||||
|  |  | ||||||
| class B: public xml::Serialize { | class A: public xml::Serialize { | ||||||
|   public: |   public: | ||||||
|     int a; |     int a; | ||||||
|     std::string txt; |     std::string txt; | ||||||
| @@ -23,7 +23,7 @@ class B: public xml::Serialize { | |||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class B: public xml::Serialize { | class B: public A { | ||||||
|   public: |   public: | ||||||
|     int a; |     int a; | ||||||
|     std::string txt; |     std::string txt; | ||||||
|   | |||||||
| @@ -4,11 +4,13 @@ | |||||||
| ## 45678901234567890123456789012345678901234567890123456789012345678901234567890 | ## 45678901234567890123456789012345678901234567890123456789012345678901234567890 | ||||||
|  |  | ||||||
| AM_CXXFLAGS += -I ${top_srcdir}/src | AM_CXXFLAGS += -I ${top_srcdir}/src | ||||||
| AM_LDFLAGS = -L${top_builddir}/src | AM_LDFLAGS = -L${top_builddir}/src -lxml-cxx | ||||||
|  |  | ||||||
| noinst_PROGRAMS = address | noinst_PROGRAMS = address node_macros serialization contain_serialization | ||||||
|  |  | ||||||
| address_SOURCES = address.cxx | address_SOURCES = address.cxx | ||||||
| address_LDADD = -lxml-cxx | node_macros_SOURCES = node_macros.cxx | ||||||
|  | serialization_SOURCES = serialization.cxx | ||||||
|  | contain_serialization_SOURCES = contain_serialization.cxx | ||||||
|  |  | ||||||
| MAINTAINERCLEANFILES = makefile.in | MAINTAINERCLEANFILES = makefile.in | ||||||
|   | |||||||
| @@ -17,6 +17,34 @@ | |||||||
| #include <typeinfo> | #include <typeinfo> | ||||||
| #include <stdexcept> | #include <stdexcept> | ||||||
|  |  | ||||||
|  | #include <cassert> | ||||||
|  | #include <iostream> | ||||||
|  | #include <iomanip> | ||||||
|  | class MethodTrace { | ||||||
|  |   public: | ||||||
|  |     MethodTrace(const void* addr, const std::string& name) throw(): | ||||||
|  |         _addr(addr), _name(name) { | ||||||
|  |       std::clog<<std::hex<<std::setw(15)<<_addr<<": " | ||||||
|  |                <<std::dec<<std::setw(2+_level) | ||||||
|  |                <<std::setfill(' ')<<"\\ "<<_name<<std::endl; | ||||||
|  |                 ++_level; | ||||||
|  |     } | ||||||
|  |     ~MethodTrace() throw() { | ||||||
|  |         --_level; | ||||||
|  |         std::clog<<std::hex<<std::setw(15)<<_addr<<": "<<std::dec | ||||||
|  |                  <<std::setw(2+_level)<<std::setfill(' ') | ||||||
|  |                  <<"/ "<<_name<<std::endl; | ||||||
|  |     } | ||||||
|  |   private: | ||||||
|  |     const void* _addr; | ||||||
|  |     const std::string _name; | ||||||
|  |     static unsigned int _level;   | ||||||
|  | }; | ||||||
|  | #define TRACE MethodTrace XXX_METHOD(this, __PRETTY_FUNCTION__) | ||||||
|  | #define LOG(X) std::clog<<__PRETTY_FUNCTION__<<"\t**** "<<X<<std::endl | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /*! @mainpage | /*! @mainpage | ||||||
|  |  | ||||||
|     @section maintitle C++ XML Class Library |     @section maintitle C++ XML Class Library | ||||||
| @@ -646,6 +674,7 @@ namespace xml { | |||||||
|       Factory& operator=(const Node& t) throw(); |       Factory& operator=(const Node& t) throw(); | ||||||
|       Factory& append(const Node& node) throw(); |       Factory& append(const Node& node) throw(); | ||||||
|       const Node& operator*() const throw(factory_not_valid); |       const Node& operator*() const throw(factory_not_valid); | ||||||
|  |       const Node*const operator->() const throw(factory_not_valid); | ||||||
|       operator bool() const throw(); |       operator bool() const throw(); | ||||||
|       friend std::ostream& operator<<(std::ostream& os, |       friend std::ostream& operator<<(std::ostream& os, | ||||||
|                                       const Factory& factory) throw(); |                                       const Factory& factory) throw(); | ||||||
| @@ -764,9 +793,13 @@ namespace xml { | |||||||
|       Serialize() throw(); |       Serialize() throw(); | ||||||
|       Serialize(const std::string& className) throw(); |       Serialize(const std::string& className) throw(); | ||||||
|       virtual ~Serialize(); |       virtual ~Serialize(); | ||||||
|       void className(const std::string& name) throw(); |       Serialize& className(const std::string& name) throw(); | ||||||
|  |       Serialize& persist(Serialize& ser) throw(); | ||||||
|       template<typename TYPE> |       template<typename TYPE> | ||||||
|           Serialize& persist(TYPE& member, const std::string& name) { |           Serialize& persist(TYPE& member, const std::string& name) throw() { | ||||||
|  |         assert(mapName<TYPE>().find(name)==mapName<TYPE>().end()); | ||||||
|  |         assert(mapMember<TYPE>().find(&member)==mapMember<TYPE>().end()); | ||||||
|  |         assert(_xmlNames.find(name)==_xmlNames.end()); | ||||||
|         mapName<TYPE>()[name] = &member; |         mapName<TYPE>()[name] = &member; | ||||||
|         mapMember<TYPE>()[&member] = name; |         mapMember<TYPE>()[&member] = name; | ||||||
|         _xmlNames[name] = &typeid(TYPE); |         _xmlNames[name] = &typeid(TYPE); | ||||||
|   | |||||||
							
								
								
									
										54
									
								
								src/xml.cxx
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								src/xml.cxx
									
									
									
									
									
								
							| @@ -10,31 +10,7 @@ | |||||||
| #include <sstream> | #include <sstream> | ||||||
| #include <cstdlib> | #include <cstdlib> | ||||||
|  |  | ||||||
| #include <cassert> |  | ||||||
| #include <iomanip> |  | ||||||
| class MethodTrace { |  | ||||||
|   public: |  | ||||||
|     MethodTrace(const void* addr, const std::string& name) throw(): |  | ||||||
|         _addr(addr), _name(name) { |  | ||||||
|       std::clog<<std::hex<<std::setw(15)<<_addr<<": " |  | ||||||
|                <<std::dec<<std::setw(2+_level) |  | ||||||
|                <<std::setfill(' ')<<"\\ "<<_name<<std::endl; |  | ||||||
|                 ++_level; |  | ||||||
|     } |  | ||||||
|     ~MethodTrace() throw() { |  | ||||||
|         --_level; |  | ||||||
|         std::clog<<std::hex<<std::setw(15)<<_addr<<": "<<std::dec |  | ||||||
|                  <<std::setw(2+_level)<<std::setfill(' ') |  | ||||||
|                  <<"/ "<<_name<<std::endl; |  | ||||||
|     } |  | ||||||
|   private: |  | ||||||
|     const void* _addr; |  | ||||||
|     const std::string _name; |  | ||||||
|     static unsigned int _level;   |  | ||||||
| }; |  | ||||||
| unsigned int MethodTrace::_level(0); | unsigned int MethodTrace::_level(0); | ||||||
| #define TRACE MethodTrace XXX_METHOD(this, __PRETTY_FUNCTION__) |  | ||||||
| #define LOG(X) std::clog<<__PRETTY_FUNCTION__<<"\t**** "<<X<<std::endl |  | ||||||
|  |  | ||||||
| namespace xml { | namespace xml { | ||||||
|    |    | ||||||
| @@ -790,6 +766,11 @@ namespace xml { | |||||||
|   } catch (...) { |   } catch (...) { | ||||||
|     throw factory_not_valid(); |     throw factory_not_valid(); | ||||||
|   } |   } | ||||||
|  |   const Node*const Factory::operator->() const throw(factory_not_valid) try { | ||||||
|  |     return &_template[0]; | ||||||
|  |   } catch (...) { | ||||||
|  |     throw factory_not_valid(); | ||||||
|  |   } | ||||||
|   Factory::operator bool() const throw() { |   Factory::operator bool() const throw() { | ||||||
|     return _template.children()>0; |     return _template.children()>0; | ||||||
|   } |   } | ||||||
| @@ -1009,14 +990,35 @@ namespace xml { | |||||||
|  |  | ||||||
|   //============================================================== Serialization |   //============================================================== Serialization | ||||||
|  |  | ||||||
|  |   //---------------------------------------------------------------------------- | ||||||
|  |   template<> void Serialize::fromNode<Serialize>(Serialize* member, | ||||||
|  |                                                  xml::Node& node) { | ||||||
|  |     member->_xmlFactory = node[member->_xmlFactory->name()]; | ||||||
|  |   } | ||||||
|  |   template<> void Serialize::toNode<Serialize>(Serialize* member, | ||||||
|  |                                     xml::Node& node) const { | ||||||
|  |     node[member->_xmlFactory->name()] = *member->_xmlFactory; | ||||||
|  |   } | ||||||
|   //---------------------------------------------------------------------------- |   //---------------------------------------------------------------------------- | ||||||
|   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() {}; |   Serialize::~Serialize() {}; | ||||||
|   void Serialize::className(const std::string& name) throw() { |   Serialize& Serialize::className(const std::string& name) throw() { | ||||||
|     _xmlFactory=xml::Node(xml::String(name).limits(1,1)); |     _xmlFactory=xml::Node(xml::String(name).limits(1,1)); | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|  |   Serialize& Serialize::persist(Serialize& ser) throw() { | ||||||
|  |     ser.initXmlMembers(); | ||||||
|  |     std::string name(ser._xmlFactory->name()); | ||||||
|  |     mapName<Serialize>()[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() { |   std::ostream& Serialize::saveXml(std::ostream& os) const throw() { | ||||||
|     if (!_xmlFactory) const_cast<Serialize*>(this)->initXmlMembers(); |     if (!_xmlFactory) const_cast<Serialize*>(this)->initXmlMembers(); | ||||||
| @@ -1028,6 +1030,7 @@ namespace xml { | |||||||
|       if (*it->second==typeid(TYPE))                \ |       if (*it->second==typeid(TYPE))                \ | ||||||
|         toNode(mapName<TYPE>()[it->first], node);   \ |         toNode(mapName<TYPE>()[it->first], node);   \ | ||||||
|       else |       else | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(Serialize) | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(std::string) |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(std::string) | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(float) |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(float) | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(double) |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(double) | ||||||
| @@ -1060,6 +1063,7 @@ namespace xml { | |||||||
|       if (*it->second==typeid(TYPE))                   \ |       if (*it->second==typeid(TYPE))                   \ | ||||||
|           fromNode(mapName<TYPE>()[it->first], *node); \ |           fromNode(mapName<TYPE>()[it->first], *node); \ | ||||||
|       else |       else | ||||||
|  |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(Serialize) | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(std::string) |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(std::string) | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(float) |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(float) | ||||||
|       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(double) |       QWERTZ_CHECK_TYPE_ZTREWQ___XXX(double) | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
| #include <cppunit/extensions/HelperMacros.h> | #include <cppunit/extensions/HelperMacros.h> | ||||||
| #include <cppunit/extensions/TestFactoryRegistry.h> | #include <cppunit/extensions/TestFactoryRegistry.h> | ||||||
|  |  | ||||||
| class A: public xml::Serialization { | class A: public xml::Serialize { | ||||||
|   public: |   public: | ||||||
|     int _anInteger; |     int _anInteger; | ||||||
|     bool _aBool; |     bool _aBool; | ||||||
| @@ -41,7 +41,7 @@ class SerializationTest: public CppUnit::TestFixture { | |||||||
|       _a._aDouble = 123.456; |       _a._aDouble = 123.456; | ||||||
|       _a._aString = "Hello World"; |       _a._aString = "Hello World"; | ||||||
|       _a._anotherString = "This is another Text"; |       _a._anotherString = "This is another Text"; | ||||||
|       _a._aLong = 4123674622; |       _a._aLong = 4123674622ul; | ||||||
|       try { |       try { | ||||||
|         std::stringstream ss; |         std::stringstream ss; | ||||||
|         _a.saveXml(ss); |         _a.saveXml(ss); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user