From dd834119f3bfea1ce399fc94dba226eec0ca9e37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Fri, 24 Apr 2009 15:12:44 +0000 Subject: [PATCH] containment can be serialized --- doc/examples/contain_serialization.cxx | 5 ++ src/xml-cxx/xml.hxx | 107 +++++++++++++++---------- src/xml.cxx | 57 ++++++++++--- 3 files changed, 115 insertions(+), 54 deletions(-) diff --git a/doc/examples/contain_serialization.cxx b/doc/examples/contain_serialization.cxx index e362185..8bfec40 100644 --- a/doc/examples/contain_serialization.cxx +++ b/doc/examples/contain_serialization.cxx @@ -37,6 +37,10 @@ class B: public xml::Serialize { } }; +std::ostream& fn(std::ostream& os) { + os<\n" @@ -54,6 +58,7 @@ int main(int, char**) { std::cout<<"Text B: "<void saveXml(std::ostream&) const - - method void loadXml(std::istream&) - @todo Up to now: Only base types plus std::string are supported, - no list, no inheritance is possible and no optional members. + int main(int, char**) { + A a; + B b; + // ... do something with a and b, then write it to stdout: + a.saveXml(std::out)< Serialize& persist(TYPE& member, const std::string& name) throw() { - assert(mapName().find(name)==mapName().end()); + assert(mapName().find(std::make_pair(this, name))==mapName().end()); assert(mapMember().find(&member)==mapMember().end()); assert(_xmlNames.find(name)==_xmlNames.end()); - mapName()[name] = &member; + mapName()[std::make_pair(this, name)] = &member; mapMember()[&member] = name; _xmlNames[name] = &typeid(TYPE); xml::Node schema(*_xmlFactory); @@ -813,8 +830,10 @@ namespace xml { protected: virtual void initXmlMembers(); private: - template std::map& mapName() const { - static std::map MAP; + template + std::map, TYPE*>& + mapName() const { + static std::map, TYPE*> MAP; return MAP; } template std::map& mapMember() const { diff --git a/src/xml.cxx b/src/xml.cxx index c138d4f..85440e4 100644 --- a/src/xml.cxx +++ b/src/xml.cxx @@ -993,18 +993,55 @@ namespace xml { //---------------------------------------------------------------------------- template<> void Serialize::fromNode(Serialize* member, xml::Node& node) { - member->_xmlFactory = node[member->_xmlFactory->name()]; + //! @todo improve this (inefficient) + std::stringstream ss; // simple but inefficient: rewrite and reread + ss<_xmlFactory->name()]; + member->loadXml(ss); } template<> void Serialize::toNode(Serialize* member, xml::Node& node) const { - node[member->_xmlFactory->name()] = *member->_xmlFactory; + //! @todo improve this (inefficient) + std::stringstream ss; // simple but inefficient: write and reread + member->saveXml(ss); + node[member->_xmlFactory->name()] = *member->_xmlFactory.read(ss); } //---------------------------------------------------------------------------- Serialize::Serialize() throw() {} Serialize::Serialize(const std::string& className) throw(): _xmlFactory(xml::Node(xml::String(className).limits(1,1))) { } - Serialize::~Serialize() {}; + Serialize::~Serialize() { + // Remove my entries from the maps + for (std::map::const_iterator + it(_xmlNames.begin()); + it!=_xmlNames.end(); ++it) { +#define QWERTZ_CHECK_TYPE_ZTREWQ___XXX(TYPE) \ + if (*it->second==typeid(TYPE)) { \ + mapMember() \ + .erase(mapName()[std::make_pair(this, it->first)]); \ + mapName().erase(std::make_pair(this, 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) + {} // ignore coding error here, but memory leaks - better abort? +#undef QWERTZ_CHECK_TYPE_ZTREWQ___XXX + } + } Serialize& Serialize::className(const std::string& name) throw() { _xmlFactory=xml::Node(xml::String(name).limits(1,1)); return *this; @@ -1012,7 +1049,7 @@ namespace xml { Serialize& Serialize::persist(Serialize& ser) throw() { ser.initXmlMembers(); std::string name(ser._xmlFactory->name()); - mapName()[name] = &ser; + mapName()[std::make_pair(this, name)] = &ser; mapMember()[&ser] = name; _xmlNames[name] = &typeid(Serialize); xml::Node schema(*_xmlFactory); @@ -1026,9 +1063,9 @@ namespace xml { for (std::map::const_iterator it(_xmlNames.begin()); it!=_xmlNames.end(); ++it) { -#define QWERTZ_CHECK_TYPE_ZTREWQ___XXX(TYPE) \ - if (*it->second==typeid(TYPE)) \ - toNode(mapName()[it->first], node); \ +#define QWERTZ_CHECK_TYPE_ZTREWQ___XXX(TYPE) \ + if (*it->second==typeid(TYPE)) \ + toNode(mapName()[std::make_pair(this, it->first)], node); \ else QWERTZ_CHECK_TYPE_ZTREWQ___XXX(Serialize) QWERTZ_CHECK_TYPE_ZTREWQ___XXX(std::string) @@ -1059,9 +1096,9 @@ namespace xml { for (std::map::const_iterator it(_xmlNames.begin()); it!=_xmlNames.end(); ++it) { -#define QWERTZ_CHECK_TYPE_ZTREWQ___XXX(TYPE) \ - if (*it->second==typeid(TYPE)) \ - fromNode(mapName()[it->first], *node); \ +#define QWERTZ_CHECK_TYPE_ZTREWQ___XXX(TYPE) \ + if (*it->second==typeid(TYPE)) \ + fromNode(mapName()[std::make_pair(this, it->first)], *node); \ else QWERTZ_CHECK_TYPE_ZTREWQ___XXX(Serialize) QWERTZ_CHECK_TYPE_ZTREWQ___XXX(std::string)