summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2015-01-08 21:10:12 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2015-01-08 21:10:12 +0000
commit501c4533bd24766f0425626c8f0e189a034e0cbc (patch)
treef2823097be93c132cb69deb1aa89f2764be18595
parentSupport getting a reference to a child, for access to its metadata, and then ... (diff)
downloadslicer-501c4533bd24766f0425626c8f0e189a034e0cbc.tar.bz2
slicer-501c4533bd24766f0425626c8f0e189a034e0cbc.tar.xz
slicer-501c4533bd24766f0425626c8f0e189a034e0cbc.zip
Support for bare containers in XML
-rw-r--r--slicer/xml/serializer.cpp47
-rw-r--r--slicer/xml/serializer.h5
2 files changed, 33 insertions, 19 deletions
diff --git a/slicer/xml/serializer.cpp b/slicer/xml/serializer.cpp
index 99c4e1c..e3482f2 100644
--- a/slicer/xml/serializer.cpp
+++ b/slicer/xml/serializer.cpp
@@ -11,6 +11,8 @@
namespace Slicer {
const std::string md_attribute = "xml:attribute";
const std::string md_text = "xml:text";
+ const std::string md_bare = "xml:bare";
+ const auto defaultElementCreator = boost::bind(&xmlpp::Element::add_child, _1, _2, Glib::ustring());
class BadBooleanValue : public std::invalid_argument {
public:
@@ -170,21 +172,27 @@ namespace Slicer {
{
while (node) {
if (auto element = dynamic_cast<const xmlpp::Element *>(node)) {
- auto smp = mp->GetChild(element->get_name(),
+ auto smpr = mp->GetChildRef(element->get_name(),
boost::bind(metaDataFlagNotSet, boost::bind(&Slicer::HookCommon::GetMetadata, _1), md_attribute));
- if (smp) {
- if (auto typeIdPropName = smp->GetTypeIdProperty()) {
- if (auto typeAttr = element->get_attribute(*typeIdPropName)) {
- smp = smp->GetSubclassModelPart(typeAttr->get_value());
- }
+ if (smpr) {
+ auto smp = smpr->Child();
+ if (metaDataFlagSet(smpr->ChildMetaData(), md_bare)) {
+ smp = smp->GetChild();
}
- smp->Create();
- auto attrs(element->get_attributes());
- if (!attrs.empty()) {
- DocumentTreeIterate(attrs.front(), smp);
+ if (smp) {
+ if (auto typeIdPropName = smp->GetTypeIdProperty()) {
+ if (auto typeAttr = element->get_attribute(*typeIdPropName)) {
+ smp = smp->GetSubclassModelPart(typeAttr->get_value());
+ }
+ }
+ smp->Create();
+ auto attrs(element->get_attributes());
+ if (!attrs.empty()) {
+ DocumentTreeIterate(attrs.front(), smp);
+ }
+ DocumentTreeIterate(element->get_first_child(), smp);
+ smp->Complete();
}
- DocumentTreeIterate(element->get_first_child(), smp);
- smp->Complete();
}
}
else if (auto attribute = dynamic_cast<const xmlpp::Attribute *>(node)) {
@@ -219,7 +227,7 @@ namespace Slicer {
}
void
- XmlSerializer::ModelTreeIterate(xmlpp::Element * n, const std::string & name, ModelPartPtr mp, HookCommonPtr hp)
+ XmlSerializer::ModelTreeIterate(xmlpp::Element * n, const std::string & name, ModelPartPtr mp, HookCommonPtr hp, const ElementCreator & ec)
{
if (!mp || name.empty()) {
return;
@@ -231,12 +239,17 @@ namespace Slicer {
mp->GetValue(new XmlContentValueTarget(n));
}
else {
- ModelTreeProcessElement(n->add_child(name), mp);
+ if (hp && metaDataFlagSet(hp->GetMetadata(), md_bare)) {
+ ModelTreeProcessElement(n, mp, boost::bind(&xmlpp::Element::add_child, _1, name, Glib::ustring()));
+ }
+ else {
+ ModelTreeProcessElement(ec(n, name), mp, defaultElementCreator);
+ }
}
}
void
- XmlSerializer::ModelTreeProcessElement(xmlpp::Element * element, ModelPartPtr mp)
+ XmlSerializer::ModelTreeProcessElement(xmlpp::Element * element, ModelPartPtr mp, const ElementCreator & ec)
{
auto typeIdPropName = mp->GetTypeIdProperty();
auto typeId = mp->GetTypeId();
@@ -245,13 +258,13 @@ namespace Slicer {
mp = mp->GetSubclassModelPart(*typeId);
}
mp->GetValue(new XmlContentValueTarget(element));
- mp->OnEachChild(boost::bind(&XmlSerializer::ModelTreeIterate, element, _1, _2, _3));
+ mp->OnEachChild(boost::bind(&XmlSerializer::ModelTreeIterate, element, _1, _2, _3, ec));
}
void
XmlSerializer::ModelTreeIterateRoot(xmlpp::Document * doc, const std::string & name, ModelPartPtr mp)
{
- ModelTreeProcessElement(doc->create_root_node(name), mp);
+ ModelTreeProcessElement(doc->create_root_node(name), mp, defaultElementCreator);
}
XmlFileSerializer::XmlFileSerializer(const boost::filesystem::path & p) :
diff --git a/slicer/xml/serializer.h b/slicer/xml/serializer.h
index 5b738ca..1e5cc5f 100644
--- a/slicer/xml/serializer.h
+++ b/slicer/xml/serializer.h
@@ -7,11 +7,12 @@
namespace Slicer {
class XmlSerializer : public Serializer {
protected:
- static void ModelTreeIterate(xmlpp::Element *, const std::string &, ModelPartPtr mp, HookCommonPtr hp);
+ typedef boost::function<xmlpp::Element *(xmlpp::Element *, const Glib::ustring &)> ElementCreator;
+ static void ModelTreeIterate(xmlpp::Element *, const std::string &, ModelPartPtr mp, HookCommonPtr hp, const ElementCreator &);
static void ModelTreeIterateRoot(xmlpp::Document *, const std::string &, ModelPartPtr mp);
private:
- static void ModelTreeProcessElement(xmlpp::Element * n, ModelPartPtr mp);
+ static void ModelTreeProcessElement(xmlpp::Element * n, ModelPartPtr mp, const ElementCreator &);
};
class XmlFileSerializer : public XmlSerializer {