From e4c22d3686da0e973e21eae0561c1169c0eeff36 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 26 Mar 2009 17:09:53 +0200 Subject: Implement support for XML Schema polymorphism in C++/Hybrid examples/cxx/hybrid/polyroot/ examples/cxx/hybrid/polymorphism/: new examples tests/cxx/hybrid/polymorphism/: new tests --- xsde/cxx/hybrid/serializer-aggregate-source.cxx | 169 ++++++++++++++++++++++-- 1 file changed, 161 insertions(+), 8 deletions(-) (limited to 'xsde/cxx/hybrid/serializer-aggregate-source.cxx') diff --git a/xsde/cxx/hybrid/serializer-aggregate-source.cxx b/xsde/cxx/hybrid/serializer-aggregate-source.cxx index 7e305b6..0422031 100644 --- a/xsde/cxx/hybrid/serializer-aggregate-source.cxx +++ b/xsde/cxx/hybrid/serializer-aggregate-source.cxx @@ -4,6 +4,7 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include +#include #include #include @@ -16,10 +17,6 @@ namespace CXX { namespace { - typedef - Cult::Containers::Map - TypeInstanceMap; - // // struct ParticleArg: Traversal::Element, Context @@ -186,6 +183,62 @@ namespace CXX TypeInstanceMap& map_; }; + // + // + struct SerializerMapConnect: Traversal::Complex, + Traversal::Element, + Context + { + SerializerMapConnect (Context& c, + String const& inst, + String const& map) + : Context (c), inst_ (inst), map_ (map) + { + *this >> inherits_ >> *this; + + *this >> contains_compositor_; + contains_compositor_ >> compositor_; + compositor_ >> contains_particle_; + contains_particle_ >> compositor_; + contains_particle_ >> *this; + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + inherits (c); + + if (!restriction_p (c)) + contains_compositor (c); + } + + virtual Void + traverse (SemanticGraph::Element& e) + { + SemanticGraph::Type& t (e.type ()); + + if (polymorphic (t)) + { + os << "this->" << inst_ << "." << + e.context ().get ("s:serializer") << " (" << + map_ << ");"; + } + } + + private: + String const& inst_; + String const& map_; + + Traversal::Inherits inherits_; + + Traversal::Compositor compositor_; + Traversal::Element particle_; + Traversal::ContainsCompositor contains_compositor_; + Traversal::ContainsParticle contains_particle_; + }; + + // + // struct GlobalType: Traversal::Type, Context { GlobalType (Context& c) @@ -208,18 +261,68 @@ namespace CXX << "//" << endl << endl; + TypeIdInstanceMap* tid_map (0); + + if (poly_code && tc.count ("saggr-tid-map")) + tid_map = &tc.get ("saggr-tid-map"); + // c-tor () // os << name << "::" << endl - << name << " ()" - << "{"; + << name << " ()"; + + if (tid_map) + { + os << endl + << ": " << tc.get ("saggr-serializer-map") << " (" << + tc.get ("saggr-serializer-map-entries") << ", " << + tid_map->size () << "UL)"; + } + + os << "{"; + // Populate the polymorphic serializer map. + // + if (tid_map) + { + String const& entry ( + tc.get ("saggr-serializer-map-entries")); + + Size n (0); + + for (TypeIdInstanceMap::Iterator i (tid_map->begin ()); + i != tid_map->end (); + ++i, ++n) + { + os << entry << "[" << n << "UL].type_id = " << + fq_name (*i->second.type, "s:name") << "::_static_type ();" + << entry << "[" << n << "UL].serializer = &this->" << + i->second.name << ";" + << endl; + } + } + + // Connect parsers. + // SerializerConnect connect (*this, map); for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) connect.dispatch (*i->first); + // Connect the serializer map. + // + if (tid_map) + { + for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); + i != end; ++i) + { + SerializerMapConnect t ( + *this, i->second, tc.get ("saggr-serializer-map")); + t.dispatch (*i->first); + } + } + os << "}"; } }; @@ -246,18 +349,68 @@ namespace CXX << "//" << endl << endl; + TypeIdInstanceMap* tid_map (0); + + if (poly_code && ec.count ("saggr-tid-map")) + tid_map = &ec.get ("saggr-tid-map"); + // c-tor () // os << name << "::" << endl - << name << " ()" - << "{"; + << name << " ()"; + + if (tid_map) + { + os << endl + << ": " << ec.get ("saggr-serializer-map") << " (" << + ec.get ("saggr-serializer-map-entries") << ", " << + tid_map->size () << "UL)"; + } + + os << "{"; + + // Populate the polymorphic serializer map. + // + if (tid_map) + { + String const& entry ( + ec.get ("saggr-serializer-map-entries")); + + Size n (0); + + for (TypeIdInstanceMap::Iterator i (tid_map->begin ()); + i != tid_map->end (); + ++i, ++n) + { + os << entry << "[" << n << "UL].type_id = " << + fq_name (*i->second.type, "s:name") << "::_static_type ();" + << entry << "[" << n << "UL].serializer = &this->" << + i->second.name << ";" + << endl; + } + } + // Connect parsers. + // SerializerConnect connect (*this, map); for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); i != end; ++i) connect.dispatch (*i->first); + // Connect the serializer map. + // + if (tid_map) + { + for (TypeInstanceMap::Iterator i (map.begin ()), end (map.end ()); + i != end; ++i) + { + SerializerMapConnect t ( + *this, i->second, ec.get ("saggr-serializer-map")); + t.dispatch (*i->first); + } + } + os << "}"; // root_name () -- cgit v1.1