From 7527065053f2799e805137d5fa84cf9ccbc07305 Mon Sep 17 00:00:00 2001 From: randomdan Date: Sun, 14 Sep 2014 23:45:28 +0000 Subject: Fix support for json to deserialize inherited types --- slicer/json/serializer.cpp | 18 ++++++++++++------ slicer/test/initial/inherit-c.json | 1 + slicer/test/run-slicer.cpp | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 slicer/test/initial/inherit-c.json diff --git a/slicer/json/serializer.cpp b/slicer/json/serializer.cpp index 0aae914..48b6b36 100644 --- a/slicer/json/serializer.cpp +++ b/slicer/json/serializer.cpp @@ -112,7 +112,7 @@ namespace Slicer { class DocumentTreeIterate : public boost::static_visitor<> { public: - DocumentTreeIterate(ModelPartPtr mp) : modelPart(mp) + DocumentTreeIterate(ModelPartPtr & mp) : modelPart(mp) { } template @@ -128,13 +128,17 @@ namespace Slicer { } void operator()(const json::Object & o) const { + auto typeAttrItr = o.find("slicer-typeid"); + if (typeAttrItr != o.end() && boost::get(typeAttrItr->second.get())) { + modelPart = modelPart->GetSubclassModelPart(boost::get(*typeAttrItr->second)); + } modelPart->Create(); BOOST_FOREACH(const auto & element, o) { auto emp = modelPart->GetChild(element.first); if (emp) { emp->Create(); boost::apply_visitor(DocumentTreeIterate(emp), *element.second); - emp->Complete(); + emp->Complete(); } } modelPart->Complete(); @@ -147,13 +151,13 @@ namespace Slicer { if (emp) { emp->Create(); boost::apply_visitor(DocumentTreeIterate(emp), *element); - emp->Complete(); + emp->Complete(); } } modelPart->Complete(); } private: - ModelPartPtr modelPart; + ModelPartPtr & modelPart; }; void @@ -241,7 +245,8 @@ namespace Slicer { Glib::ustring doc(buffer.str()); Glib::ustring::const_iterator itr = doc.begin(); json::Value obj = json::parseValue(itr); - boost::apply_visitor(DocumentTreeIterate(modelRoot->GetChild(std::string())), obj); + auto mp = modelRoot->GetChild(std::string()); + boost::apply_visitor(DocumentTreeIterate(mp), obj); } void @@ -261,7 +266,8 @@ namespace Slicer { void JsonValue::Deserialize(ModelPartPtr modelRoot) { - boost::apply_visitor(DocumentTreeIterate(modelRoot->GetChild(std::string())), value); + auto mp = modelRoot->GetChild(std::string()); + boost::apply_visitor(DocumentTreeIterate(mp), value); } void diff --git a/slicer/test/initial/inherit-c.json b/slicer/test/initial/inherit-c.json new file mode 100644 index 0000000..cd5768a --- /dev/null +++ b/slicer/test/initial/inherit-c.json @@ -0,0 +1 @@ +{"b":{"a":1.000000,"b":2.000000,"slicer-typeid":"::TestModule::D1"},"bm":[{"key":10.000000,"value":{"a":11.000000,"b":100.000000,"slicer-typeid":"::TestModule::D1"}},{"key":12.000000,"value":{"a":13.000000,"c":100.000000,"d":200.000000,"slicer-typeid":"::TestModule::D3"}},{"key":14.000000,"value":{"a":15.000000}}],"bs":[{"a":1.000000,"c":100.000000,"slicer-typeid":"::TestModule::D2"},{"a":2.000000,"c":100.000000,"d":200.000000,"slicer-typeid":"::TestModule::D3"},{"a":3.000000}]} \ No newline at end of file diff --git a/slicer/test/run-slicer.cpp b/slicer/test/run-slicer.cpp index 73d5be8..1f0c986 100644 --- a/slicer/test/run-slicer.cpp +++ b/slicer/test/run-slicer.cpp @@ -140,6 +140,36 @@ checkBuiltIns_valuesCorrect(const TestModule::BuiltIns & bt) BOOST_ASSERT(bt.mstring == "Sample text"); } +void +checkInherits_types(const TestModule::InheritanceCont & i) +{ + BOOST_ASSERT(i.b); + BOOST_ASSERT(TestModule::D1Ptr::dynamicCast(i.b)); + BOOST_ASSERT(TestModule::D1Ptr::dynamicCast(i.b)->a == 1); + BOOST_ASSERT(TestModule::D1Ptr::dynamicCast(i.b)->b == 2); + BOOST_ASSERT(i.bs.size() == 3); + BOOST_ASSERT(i.bs[0]); + BOOST_ASSERT(TestModule::D2Ptr::dynamicCast(i.bs[0])); + BOOST_ASSERT(TestModule::D2Ptr::dynamicCast(i.bs[0])->a == 1); + BOOST_ASSERT(TestModule::D2Ptr::dynamicCast(i.bs[0])->c == 100); + BOOST_ASSERT(i.bs[1]); + BOOST_ASSERT(TestModule::D3Ptr::dynamicCast(i.bs[1])); + BOOST_ASSERT(TestModule::D3Ptr::dynamicCast(i.bs[1])->a == 2); + BOOST_ASSERT(TestModule::D3Ptr::dynamicCast(i.bs[1])->c == 100); + BOOST_ASSERT(TestModule::D3Ptr::dynamicCast(i.bs[1])->d == 200); + BOOST_ASSERT(i.bs[2]); + BOOST_ASSERT(i.bs[2]->a == 3); + BOOST_ASSERT(!TestModule::D1Ptr::dynamicCast(i.bs[2])); + BOOST_ASSERT(!TestModule::D2Ptr::dynamicCast(i.bs[2])); + BOOST_ASSERT(!TestModule::D3Ptr::dynamicCast(i.bs[2])); + BOOST_ASSERT(i.bm.size() == 3); + BOOST_ASSERT(TestModule::D1Ptr::dynamicCast(i.bm.find(10)->second)); + BOOST_ASSERT(TestModule::D3Ptr::dynamicCast(i.bm.find(12)->second)); + BOOST_ASSERT(!TestModule::D1Ptr::dynamicCast(i.bm.find(14)->second)); + BOOST_ASSERT(!TestModule::D2Ptr::dynamicCast(i.bm.find(14)->second)); + BOOST_ASSERT(!TestModule::D3Ptr::dynamicCast(i.bm.find(14)->second)); +} + void checkOptionals_notset(const TestModule::Optionals & opts) { @@ -243,10 +273,11 @@ main(int, char ** argv) verifyByFile(root, tmpf, "optionals-notset.xml", checkOptionals_notset); verifyByFile(root, tmpf, "optionals-areset.xml", checkOptionals_areset); verifyByFile(root, tmpf, "inherit-a.xml"); - verifyByFile(root, tmpf, "inherit-b.xml"); + verifyByFile(root, tmpf, "inherit-b.xml", checkInherits_types); verifyByFile(root, tmpf, "conv-datetime.xml"); verifyByFile(root, tmpf, "builtins2.json", checkBuiltIns_valuesCorrect); verifyByFile(root, tmpf, "optionals-areset2.json", checkOptionals_areset); + verifyByFile(root, tmpf, "inherit-c.json", checkInherits_types); verifyByHelper(root, tmph, "optionals-areset2.json", readJson, writeJson, freeJson, checkOptionals_areset); verifyByHelper(root, tmph, "optionals-areset.xml", readXml, writeXml, freeXml, checkOptionals_areset); -- cgit v1.2.3