|
|
@ -245,7 +245,7 @@ namespace xml { |
|
|
|
it!=o._contents.end(); ++it) |
|
|
|
it!=o._contents.end(); ++it) |
|
|
|
_contents.push_back((*it)->clone(this).release()); |
|
|
|
_contents.push_back((*it)->clone(this).release()); |
|
|
|
} |
|
|
|
} |
|
|
|
//! Clones But clears the parent.
|
|
|
|
//! Clones But resets the parent reference.
|
|
|
|
/*! You get a new instance of the node, but detached from the
|
|
|
|
/*! You get a new instance of the node, but detached from the
|
|
|
|
parent. It is then ready to be inserted below a new parent. |
|
|
|
parent. It is then ready to be inserted below a new parent. |
|
|
|
|
|
|
|
|
|
|
@ -1026,7 +1026,7 @@ namespace xml { |
|
|
|
copy(other); |
|
|
|
copy(other); |
|
|
|
} |
|
|
|
} |
|
|
|
Serialize::~Serialize() { |
|
|
|
Serialize::~Serialize() { |
|
|
|
clear(); |
|
|
|
reset(); |
|
|
|
} |
|
|
|
} |
|
|
|
Serialize& Serialize::operator=(const Serialize& other) throw() { |
|
|
|
Serialize& Serialize::operator=(const Serialize& other) throw() { |
|
|
|
copy(other); |
|
|
|
copy(other); |
|
|
@ -1043,7 +1043,7 @@ namespace xml { |
|
|
|
} |
|
|
|
} |
|
|
|
Serialize& Serialize::persist(Serialize& ser, |
|
|
|
Serialize& Serialize::persist(Serialize& ser, |
|
|
|
const std::string& name) throw() { |
|
|
|
const std::string& name) throw() { |
|
|
|
if (!ser._xmlFactory) ser.initXmlMembers(); |
|
|
|
ser.checkInit(); |
|
|
|
_xmlNames[name] = &ser; |
|
|
|
_xmlNames[name] = &ser; |
|
|
|
xml::Node schema(*_xmlFactory); |
|
|
|
xml::Node schema(*_xmlFactory); |
|
|
|
xml::Node node(xml::Node(name).limits(1,1)); |
|
|
|
xml::Node node(xml::Node(name).limits(1,1)); |
|
|
@ -1106,7 +1106,7 @@ namespace xml { |
|
|
|
} |
|
|
|
} |
|
|
|
std::ostream& Serialize::saveXml(std::ostream& os, |
|
|
|
std::ostream& Serialize::saveXml(std::ostream& os, |
|
|
|
const std::string& name) const throw() { |
|
|
|
const std::string& name) const throw() { |
|
|
|
if (!_xmlFactory) const_cast<Serialize*>(this)->initXmlMembers(); |
|
|
|
checkInit(); |
|
|
|
xml::Node node(*_xmlFactory); |
|
|
|
xml::Node node(*_xmlFactory); |
|
|
|
if (name.size()) node.name(name); |
|
|
|
if (name.size()) node.name(name); |
|
|
|
for (std::map<std::string, boost::any>::const_iterator |
|
|
|
for (std::map<std::string, boost::any>::const_iterator |
|
|
@ -1117,7 +1117,7 @@ namespace xml { |
|
|
|
return os; |
|
|
|
return os; |
|
|
|
} |
|
|
|
} |
|
|
|
std::istream& Serialize::loadXml(std::istream& is, const std::string& name) { |
|
|
|
std::istream& Serialize::loadXml(std::istream& is, const std::string& name) { |
|
|
|
if (!_xmlFactory) initXmlMembers(); |
|
|
|
checkInit(); |
|
|
|
xml::Factory factory(_xmlFactory); |
|
|
|
xml::Factory factory(_xmlFactory); |
|
|
|
if (name.size()) factory->name(name); |
|
|
|
if (name.size()) factory->name(name); |
|
|
|
std::auto_ptr<xml::Node> node(factory.read(is)); |
|
|
|
std::auto_ptr<xml::Node> node(factory.read(is)); |
|
|
@ -1128,21 +1128,54 @@ namespace xml { |
|
|
|
return is; |
|
|
|
return is; |
|
|
|
} |
|
|
|
} |
|
|
|
std::string Serialize::schema() const throw() { |
|
|
|
std::string Serialize::schema() const throw() { |
|
|
|
if (!_xmlFactory) const_cast<Serialize*>(this)->initXmlMembers(); |
|
|
|
checkInit(); |
|
|
|
std::stringstream ss; |
|
|
|
std::stringstream ss; |
|
|
|
ss<<*_xmlFactory; |
|
|
|
ss<<*_xmlFactory; |
|
|
|
return ss.str(); |
|
|
|
return ss.str(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Serialize::registerFromNode(Serialize::FromNodeFunc fromNodeFunc) { |
|
|
|
|
|
|
|
_fromNode.insert(fromNodeFunc); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Serialize::registerToNode(Serialize::ToNodeFunc toNodeFunc) { |
|
|
|
|
|
|
|
_toNode.insert(toNodeFunc); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void Serialize::initXmlMembers() {} |
|
|
|
|
|
|
|
void Serialize::reset() throw() { |
|
|
|
|
|
|
|
_xmlFactory.reset(); |
|
|
|
|
|
|
|
_xmlNames.clear(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void Serialize::copy(const Serialize& o) throw() { |
|
|
|
|
|
|
|
reset(); |
|
|
|
|
|
|
|
initXmlMembers(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void Serialize::fromNode(boost::any member, const xml::Node& node) { |
|
|
|
|
|
|
|
for (std::set<FromNodeFunc>::const_iterator it(_fromNode.begin()); |
|
|
|
|
|
|
|
it!=_fromNode.end(); ++it) |
|
|
|
|
|
|
|
if ((**it)(member, node)) return; // found match
|
|
|
|
|
|
|
|
throw type_not_registered(member.type().name(), node.name(), node); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void Serialize::toNode(const boost::any member, xml::Node& node) const { |
|
|
|
|
|
|
|
for (std::set<ToNodeFunc>::const_iterator it(_toNode.begin()); |
|
|
|
|
|
|
|
it!=_toNode.end(); ++it) |
|
|
|
|
|
|
|
if ((**it)(member, node)) return; // found match
|
|
|
|
|
|
|
|
throw type_not_registered(member.type().name(), node.name(), node); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
std::set<Serialize::FromNodeFunc> Serialize::_fromNode; |
|
|
|
|
|
|
|
std::set<Serialize::ToNodeFunc> Serialize::_toNode; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//=============================================================== Assign Types
|
|
|
|
template<typename TYPE> bool assignFromNode(boost::any member, |
|
|
|
template<typename TYPE> bool assignFromNode(boost::any member, |
|
|
|
const xml::Node& node) { |
|
|
|
const xml::Node& node) { |
|
|
|
if (member.type()!=typeid(TYPE*)) return false; |
|
|
|
if (!boost::any_cast<TYPE*>(&member)) return false; |
|
|
|
*boost::any_cast<TYPE*>(member) = |
|
|
|
*boost::any_cast<TYPE*>(member) = |
|
|
|
(TYPE)dynamic_cast<const xml::String&>(node); |
|
|
|
(TYPE)dynamic_cast<const xml::String&>(node); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
template<typename TYPE> bool assignToNode(const boost::any member, |
|
|
|
template<typename TYPE> bool assignToNode(const boost::any member, |
|
|
|
xml::Node& node) { |
|
|
|
xml::Node& node) { |
|
|
|
if (member.type()!=typeid(TYPE*)) return false; |
|
|
|
if (!boost::any_cast<TYPE*>(&member)) return false; |
|
|
|
std::stringstream ss; |
|
|
|
std::stringstream ss; |
|
|
|
ss<<*boost::any_cast<TYPE*>(member); |
|
|
|
ss<<*boost::any_cast<TYPE*>(member); |
|
|
|
node.text(ss.str()); |
|
|
|
node.text(ss.str()); |
|
|
@ -1172,66 +1205,26 @@ namespace xml { |
|
|
|
} |
|
|
|
} |
|
|
|
template<> bool assignFromNode<Serialize>(boost::any member, |
|
|
|
template<> bool assignFromNode<Serialize>(boost::any member, |
|
|
|
const xml::Node& node) { |
|
|
|
const xml::Node& node) { |
|
|
|
if (member.type()!=typeid(Serialize*)) return false; |
|
|
|
if (!boost::any_cast<Serialize*>(&member)) return false; |
|
|
|
//! @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; |
|
|
|
ss<<node; |
|
|
|
boost::any_cast<Serialize*>(member)->loadXml(ss, node.name()); |
|
|
|
boost::any_cast<Serialize*>(member)->loadXml(ss, node.name()); |
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
Serialize* ser(boost::any_cast<Serialize*>(member)); |
|
|
|
|
|
|
|
for (xml::Node::size_type i(0); i<node.children(); ++i) |
|
|
|
|
|
|
|
ser->fromNode(ser->_xmlNames[*node[i]], node[i]);*/ |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
template<> bool assignToNode<Serialize>(const boost::any member, |
|
|
|
template<> bool assignToNode<Serialize>(const boost::any member, |
|
|
|
xml::Node& node) { |
|
|
|
xml::Node& node) { |
|
|
|
if (member.type()!=typeid(Serialize*)) return false; |
|
|
|
if (!boost::any_cast<Serialize*>(&member)) return false; |
|
|
|
std::stringstream ss; |
|
|
|
std::stringstream ss; |
|
|
|
boost::any_cast<Serialize*>(member)->saveXml(ss, node.name()); |
|
|
|
boost::any_cast<Serialize*>(member)->saveXml(ss, node.name()); |
|
|
|
xml::Factory factory(node); |
|
|
|
xml::Factory factory(node); |
|
|
|
node = *factory.read(ss); |
|
|
|
node = *factory.read(ss); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
// template<typename TYPE, template<class TYPE> class CONTAINER>
|
|
|
|
|
|
|
|
// bool containerFromNode(boost::any member,
|
|
|
|
|
|
|
|
// const xml::Node& node) {
|
|
|
|
|
|
|
|
// if (member.type()!=typeid(TYPE*)) return false;
|
|
|
|
|
|
|
|
// LOG("ASSIGN List");
|
|
|
|
|
|
|
|
// return false;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// template<typename TYPE, class ALLOC>
|
|
|
|
|
|
|
|
// bool assignToNode(const boost::any member, xml::Node& node) {
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Serialize::registerFromNode(Serialize::FromNodeFunc fromNodeFunc) { |
|
|
|
|
|
|
|
_fromNode.insert(fromNodeFunc); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Serialize::registerToNode(Serialize::ToNodeFunc toNodeFunc) { |
|
|
|
|
|
|
|
_toNode.insert(toNodeFunc); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void Serialize::initXmlMembers() {} |
|
|
|
|
|
|
|
void Serialize::clear() throw() { |
|
|
|
|
|
|
|
_xmlFactory.reset(); |
|
|
|
|
|
|
|
_xmlNames.clear(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void Serialize::copy(const Serialize& o) throw() { |
|
|
|
|
|
|
|
clear(); |
|
|
|
|
|
|
|
initXmlMembers(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void Serialize::fromNode(boost::any member, const xml::Node& node) { |
|
|
|
|
|
|
|
if (!_fromNode.size()) registerFromNode(&assignFromNode<std::string>); |
|
|
|
|
|
|
|
for (std::set<FromNodeFunc>::const_iterator it(_fromNode.begin()); |
|
|
|
|
|
|
|
it!=_fromNode.end(); ++it) |
|
|
|
|
|
|
|
if ((**it)(member, node)) return; // found match
|
|
|
|
|
|
|
|
throw std::runtime_error(node.name()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void Serialize::toNode(const boost::any member, xml::Node& node) const { |
|
|
|
|
|
|
|
if (!_toNode.size()) registerToNode(&assignToNode<std::string>); |
|
|
|
|
|
|
|
for (std::set<ToNodeFunc>::const_iterator it(_toNode.begin()); |
|
|
|
|
|
|
|
it!=_toNode.end(); ++it) |
|
|
|
|
|
|
|
if ((**it)(member, node)) return; // found match
|
|
|
|
|
|
|
|
throw std::runtime_error(node.name()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
std::set<Serialize::FromNodeFunc> Serialize::_fromNode; |
|
|
|
|
|
|
|
std::set<Serialize::ToNodeFunc> Serialize::_toNode; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Register for all simple Types =============================================
|
|
|
|
// Register for all simple Types =============================================
|
|
|
|
template<int NUM> struct SimpleTypes {}; |
|
|
|
template<int NUM> struct SimpleTypes {}; |
|
|
|
template<> struct SimpleTypes<1> {typedef std::string Type;}; |
|
|
|
template<> struct SimpleTypes<1> {typedef std::string Type;}; |
|
|
|