serialization works for containment and inheritance

This commit is contained in:
Marc Wäckerlin
2009-04-27 10:48:27 +00:00
parent dd834119f3
commit d67a7d2c95
6 changed files with 557 additions and 162 deletions

View File

@@ -12,6 +12,7 @@
#include <sstream>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <memory>
#include <typeinfo>
@@ -42,7 +43,12 @@ class MethodTrace {
};
#define TRACE MethodTrace XXX_METHOD(this, __PRETTY_FUNCTION__)
#define LOG(X) std::clog<<__PRETTY_FUNCTION__<<"\t**** "<<X<<std::endl
#define ASSERT(X, Y) { \
if (!(Y)) { \
LOG(X); \
} \
assert(Y); \
}
/*! @mainpage
@@ -578,6 +584,7 @@ namespace xml {
virtual Node& set(const Attributes& o) throw();
Node& clear() throw ();
std::string name() const throw();
Node& name(const std::string& n) throw();
Node& min(size_type m) throw();
size_type min() const throw();
Node& max(size_type m) throw();
@@ -639,6 +646,7 @@ namespace xml {
Node& operator=(const std::string& contents) throw();
operator std::string() const throw();
operator bool() const throw();
operator char() const throw();
operator signed char() const throw();
operator unsigned char() const throw();
operator signed short() const throw();
@@ -687,8 +695,12 @@ namespace xml {
duplicate_attribute, attributes_in_end_tag,
illegal_attribute, mandatory_attribute_missing,
wrong_node_number);
void reset() throw();
private:
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();
std::auto_ptr<Node> read(std::istream& is, const Node& position)
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!
Serialize() throw();
Serialize(const std::string& className) throw();
Serialize(const Serialize& other) throw();
virtual ~Serialize();
Serialize& operator=(const Serialize& other) 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>
Serialize& persist(TYPE& member, const std::string& name) throw() {
assert(mapName<TYPE>().find(std::make_pair(this, name))==mapName<TYPE>().end());
assert(mapMember<TYPE>().find(&member)==mapMember<TYPE>().end());
assert(_xmlNames.find(name)==_xmlNames.end());
Serialize& persistSimpleType(TYPE& member,
const std::string& name) throw() {
ASSERT("type: "<<typeid(TYPE).name()<<"; name="<<name,
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;
mapMember<TYPE>()[&member] = name;
_xmlNames[name] = &typeid(TYPE);
@@ -825,11 +901,6 @@ namespace xml {
_xmlFactory = schema;
return *this;
}
std::ostream& saveXml(std::ostream& os) const throw();
std::istream& loadXml(std::istream& is);
protected:
virtual void initXmlMembers();
private:
template<typename TYPE>
std::map<std::pair<const Serialize*, std::string>, TYPE*>&
mapName() const {
@@ -841,13 +912,19 @@ namespace xml {
return MAP;
}
template<typename TYPE> void fromNode(TYPE* member, xml::Node& node) {
*member =
(TYPE)dynamic_cast<xml::String&>(node[mapMember<TYPE>()[member]]);
*member = (TYPE)dynamic_cast<xml::String&>(node);
}
/*
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 {
std::stringstream ss;
ss<<*member;
node[mapMember<TYPE>()[member]].text(ss.str());
node.text(ss.str());
}
std::map<std::string, const std::type_info*> _xmlNames;
xml::Factory _xmlFactory;