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