From ee4eb695119bce96515b330f9fc83ddd67da5c62 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 2 Dec 2009 12:26:05 +0200 Subject: Implement de-registering polymorphic type information This is required for DLL/shared library unloading. --- libxsd/xsd/cxx/parser/substitution-map.hxx | 13 +++++- libxsd/xsd/cxx/parser/substitution-map.txx | 8 ++++ .../xsd/cxx/parser/validating/inheritance-map.hxx | 11 ++++- .../xsd/cxx/parser/validating/inheritance-map.txx | 8 ++++ libxsd/xsd/cxx/tree/comparison-map.hxx | 4 ++ libxsd/xsd/cxx/tree/comparison-map.txx | 14 +++++++ libxsd/xsd/cxx/tree/std-ostream-map.hxx | 4 ++ libxsd/xsd/cxx/tree/std-ostream-map.txx | 14 +++++++ libxsd/xsd/cxx/tree/stream-extraction-map.hxx | 8 ++++ libxsd/xsd/cxx/tree/stream-extraction-map.txx | 16 ++++++++ libxsd/xsd/cxx/tree/stream-insertion-map.hxx | 4 ++ libxsd/xsd/cxx/tree/stream-insertion-map.txx | 15 +++++++ libxsd/xsd/cxx/tree/type-factory-map.hxx | 34 +++++++++++++--- libxsd/xsd/cxx/tree/type-factory-map.txx | 47 +++++++++++++++++++++- libxsd/xsd/cxx/tree/type-serializer-map.hxx | 30 +++++++++++--- libxsd/xsd/cxx/tree/type-serializer-map.txx | 47 +++++++++++++++++++--- xsd/cxx/tree/serialization-source.cxx | 4 +- xsd/cxx/tree/tree-source.cxx | 2 +- 18 files changed, 260 insertions(+), 23 deletions(-) diff --git a/libxsd/xsd/cxx/parser/substitution-map.hxx b/libxsd/xsd/cxx/parser/substitution-map.hxx index 60c0ec8..0379164 100644 --- a/libxsd/xsd/cxx/parser/substitution-map.hxx +++ b/libxsd/xsd/cxx/parser/substitution-map.hxx @@ -137,6 +137,12 @@ namespace xsd map_.insert (std::pair (k, v)); } + void + erase (const C* member_ns, const C* member_name) + { + map_.erase (key (member_ns, member_name)); + } + // Check and get the type set if found. // bool @@ -219,6 +225,12 @@ namespace xsd const C* root_ns, const C* root_name, const C* member_type); + + ~substitution_map_entry (); + + private: + const C* member_ns_; + const C* member_name_; }; } } @@ -227,4 +239,3 @@ namespace xsd #include #endif // XSD_CXX_PARSER_SUBSTITUTION_MAP_HXX - diff --git a/libxsd/xsd/cxx/parser/substitution-map.txx b/libxsd/xsd/cxx/parser/substitution-map.txx index c9d4cb1..63d88b9 100644 --- a/libxsd/xsd/cxx/parser/substitution-map.txx +++ b/libxsd/xsd/cxx/parser/substitution-map.txx @@ -67,10 +67,18 @@ namespace xsd const C* root_ns, const C* root_name, const C* member_type) + : member_ns_ (member_ns), member_name_ (member_name) { substitution_map_instance ().insert ( member_ns, member_name, root_ns, root_name, member_type); } + + template + substitution_map_entry:: + ~substitution_map_entry () + { + substitution_map_instance ().erase (member_ns_, member_name_); + } } } } diff --git a/libxsd/xsd/cxx/parser/validating/inheritance-map.hxx b/libxsd/xsd/cxx/parser/validating/inheritance-map.hxx index ebd1d03..b3fc35a 100644 --- a/libxsd/xsd/cxx/parser/validating/inheritance-map.hxx +++ b/libxsd/xsd/cxx/parser/validating/inheritance-map.hxx @@ -39,6 +39,12 @@ namespace xsd map_[derived] = base; } + void + erase (const C* derived) + { + map_.erase (derived); + } + bool check (const C* derived, const ro_string& base) const; @@ -80,6 +86,10 @@ namespace xsd struct inheritance_map_entry { inheritance_map_entry (const C* derived, const C* base); + ~inheritance_map_entry (); + + private: + const C* derived_; }; } } @@ -89,4 +99,3 @@ namespace xsd #include #endif // XSD_CXX_PARSER_VALIDATING_INHERITANCE_MAP_HXX - diff --git a/libxsd/xsd/cxx/parser/validating/inheritance-map.txx b/libxsd/xsd/cxx/parser/validating/inheritance-map.txx index 5e70409..7982011 100644 --- a/libxsd/xsd/cxx/parser/validating/inheritance-map.txx +++ b/libxsd/xsd/cxx/parser/validating/inheritance-map.txx @@ -56,9 +56,17 @@ namespace xsd template inheritance_map_entry:: inheritance_map_entry (const C* derived, const C* base) + : derived_ (derived) { inheritance_map_instance ().insert (derived, base); } + + template + inheritance_map_entry:: + ~inheritance_map_entry () + { + inheritance_map_instance ().erase (derived_); + } } } } diff --git a/libxsd/xsd/cxx/tree/comparison-map.hxx b/libxsd/xsd/cxx/tree/comparison-map.hxx index f8461a0..4f7e51b 100644 --- a/libxsd/xsd/cxx/tree/comparison-map.hxx +++ b/libxsd/xsd/cxx/tree/comparison-map.hxx @@ -29,6 +29,9 @@ namespace xsd void register_type (const type_id&, comparator, bool override = true); + void + unregister_type (const type_id&); + bool compare (const type&, const type&); @@ -99,6 +102,7 @@ namespace xsd struct comparison_initializer { comparison_initializer (); + ~comparison_initializer (); }; } } diff --git a/libxsd/xsd/cxx/tree/comparison-map.txx b/libxsd/xsd/cxx/tree/comparison-map.txx index 38f215f..3af2a42 100644 --- a/libxsd/xsd/cxx/tree/comparison-map.txx +++ b/libxsd/xsd/cxx/tree/comparison-map.txx @@ -219,6 +219,13 @@ namespace xsd } template + void comparison_map:: + unregister_type (const type_id& tid) + { + type_map_.erase (&tid); + } + + template bool comparison_map:: compare (const type& x, const type& y) { @@ -282,6 +289,13 @@ namespace xsd comparison_map_instance ().register_type ( typeid (T), &comparator_impl); } + + template + comparison_initializer:: + ~comparison_initializer () + { + comparison_map_instance ().unregister_type (typeid (T)); + } } } } diff --git a/libxsd/xsd/cxx/tree/std-ostream-map.hxx b/libxsd/xsd/cxx/tree/std-ostream-map.hxx index 25f225f..2bf786c 100644 --- a/libxsd/xsd/cxx/tree/std-ostream-map.hxx +++ b/libxsd/xsd/cxx/tree/std-ostream-map.hxx @@ -31,6 +31,9 @@ namespace xsd register_type (const type_id&, inserter, bool override = true); void + unregister_type (const type_id&); + + void insert (std::ostream&, const type&); public: @@ -100,6 +103,7 @@ namespace xsd struct std_ostream_initializer { std_ostream_initializer (); + ~std_ostream_initializer (); }; } } diff --git a/libxsd/xsd/cxx/tree/std-ostream-map.txx b/libxsd/xsd/cxx/tree/std-ostream-map.txx index c1187ef..ee46f16 100644 --- a/libxsd/xsd/cxx/tree/std-ostream-map.txx +++ b/libxsd/xsd/cxx/tree/std-ostream-map.txx @@ -219,6 +219,13 @@ namespace xsd template void std_ostream_map:: + unregister_type (const type_id& tid) + { + type_map_.erase (&tid); + } + + template + void std_ostream_map:: insert (std::ostream& os, const type& x) { if (inserter i = find (typeid (x))) @@ -274,6 +281,13 @@ namespace xsd std_ostream_map_instance ().register_type ( typeid (T), &inserter_impl); } + + template + std_ostream_initializer:: + ~std_ostream_initializer () + { + std_ostream_map_instance ().unregister_type (typeid (T)); + } } } } diff --git a/libxsd/xsd/cxx/tree/stream-extraction-map.hxx b/libxsd/xsd/cxx/tree/stream-extraction-map.hxx index 14a5423..5d31b6a 100644 --- a/libxsd/xsd/cxx/tree/stream-extraction-map.hxx +++ b/libxsd/xsd/cxx/tree/stream-extraction-map.hxx @@ -35,6 +35,9 @@ namespace xsd extractor, bool override = true); + void + unregister_type (const qualified_name& name); + std::auto_ptr extract (istream&, flags, container*); @@ -87,6 +90,11 @@ namespace xsd struct stream_extraction_initializer { stream_extraction_initializer (const C* name, const C* ns); + ~stream_extraction_initializer (); + + private: + const C* name_; + const C* ns_; }; } } diff --git a/libxsd/xsd/cxx/tree/stream-extraction-map.txx b/libxsd/xsd/cxx/tree/stream-extraction-map.txx index 5534da6..ca0a44e 100644 --- a/libxsd/xsd/cxx/tree/stream-extraction-map.txx +++ b/libxsd/xsd/cxx/tree/stream-extraction-map.txx @@ -226,6 +226,13 @@ namespace xsd } template + void stream_extraction_map:: + unregister_type (const qualified_name& name) + { + type_map_.erase (name); + } + + template std::auto_ptr stream_extraction_map:: extract (istream& s, flags f, container* c) { @@ -285,10 +292,19 @@ namespace xsd template stream_extraction_initializer:: stream_extraction_initializer (const C* name, const C* ns) + : name_ (name), ns_ (ns) { stream_extraction_map_instance ().register_type ( xml::qualified_name (name, ns), &extractor_impl); } + + template + stream_extraction_initializer:: + ~stream_extraction_initializer () + { + stream_extraction_map_instance ().unregister_type ( + xml::qualified_name (name_, ns_)); + } } } } diff --git a/libxsd/xsd/cxx/tree/stream-insertion-map.hxx b/libxsd/xsd/cxx/tree/stream-insertion-map.hxx index 77d930c..0fdef0b 100644 --- a/libxsd/xsd/cxx/tree/stream-insertion-map.hxx +++ b/libxsd/xsd/cxx/tree/stream-insertion-map.hxx @@ -37,6 +37,9 @@ namespace xsd bool override = true); void + unregister_type (const type_id&); + + void insert (ostream&, const type&); public: @@ -140,6 +143,7 @@ namespace xsd struct stream_insertion_initializer { stream_insertion_initializer (const C* name, const C* ns); + ~stream_insertion_initializer (); }; } } diff --git a/libxsd/xsd/cxx/tree/stream-insertion-map.txx b/libxsd/xsd/cxx/tree/stream-insertion-map.txx index c3cf9b5..f9d5745 100644 --- a/libxsd/xsd/cxx/tree/stream-insertion-map.txx +++ b/libxsd/xsd/cxx/tree/stream-insertion-map.txx @@ -256,6 +256,13 @@ namespace xsd template void stream_insertion_map:: + unregister_type (const type_id& tid) + { + type_map_.erase (&tid); + } + + template + void stream_insertion_map:: insert (ostream& s, const type& x) { if (const type_info* ti = find (typeid (x))) @@ -320,6 +327,14 @@ namespace xsd xml::qualified_name (name, ns), &inserter_impl); } + + template + stream_insertion_initializer:: + ~stream_insertion_initializer (const C* name, const C* ns) + { + stream_insertion_map_instance ().unregister_type ( + typeid (T)); + } } } } diff --git a/libxsd/xsd/cxx/tree/type-factory-map.hxx b/libxsd/xsd/cxx/tree/type-factory-map.hxx index 8cf916e..e191ff7 100644 --- a/libxsd/xsd/cxx/tree/type-factory-map.hxx +++ b/libxsd/xsd/cxx/tree/type-factory-map.hxx @@ -38,10 +38,17 @@ namespace xsd bool override = true); void + unregister_type (const qualified_name& name); + + void register_element (const qualified_name& root, const qualified_name& subst, factory); + void + unregister_element (const qualified_name& root, + const qualified_name& subst); + std::auto_ptr create (const C* name, // element name const C* ns, // element namespace @@ -133,14 +140,29 @@ namespace xsd template struct type_factory_initializer { - // Register type. - // type_factory_initializer (const C* name, const C* ns); + ~type_factory_initializer (); - // Register element. - // - type_factory_initializer (const C* root_name, const C* root_ns, - const C* subst_name, const C* subst_ns); + private: + const C* name_; + const C* ns_; + }; + + // + // + template + struct element_factory_initializer + { + element_factory_initializer (const C* root_name, const C* root_ns, + const C* subst_name, const C* subst_ns); + + ~element_factory_initializer (); + + private: + const C* root_name_; + const C* root_ns_; + const C* subst_name_; + const C* subst_ns_; }; } } diff --git a/libxsd/xsd/cxx/tree/type-factory-map.txx b/libxsd/xsd/cxx/tree/type-factory-map.txx index 215f033..ee376f8 100644 --- a/libxsd/xsd/cxx/tree/type-factory-map.txx +++ b/libxsd/xsd/cxx/tree/type-factory-map.txx @@ -234,6 +234,13 @@ namespace xsd template void type_factory_map:: + unregister_type (const qualified_name& name) + { + type_map_.erase (name); + } + + template + void type_factory_map:: register_element (const qualified_name& root, const qualified_name& subst, factory f) @@ -242,6 +249,22 @@ namespace xsd } template + void type_factory_map:: + unregister_element (const qualified_name& root, + const qualified_name& subst) + { + typename element_map::iterator i (element_map_.find (root)); + + if (i != element_map_.end ()) + { + i->second.erase (subst); + + if (i->second.empty ()) + element_map_.erase (i); + } + } + + template typename type_factory_map::factory type_factory_map:: find (const qualified_name& name) const { @@ -416,6 +439,7 @@ namespace xsd template type_factory_initializer:: type_factory_initializer (const C* name, const C* ns) + : name_ (name), ns_ (ns) { type_factory_map_instance ().register_type ( xml::qualified_name (name, ns), &factory_impl); @@ -423,14 +447,35 @@ namespace xsd template type_factory_initializer:: - type_factory_initializer (const C* root_name, const C* root_ns, + ~type_factory_initializer () + { + type_factory_map_instance ().unregister_type ( + xml::qualified_name (name_, ns_)); + } + + // + // + template + element_factory_initializer:: + element_factory_initializer (const C* root_name, const C* root_ns, const C* subst_name, const C* subst_ns) + : root_name_ (root_name), root_ns_ (root_ns), + subst_name_ (subst_name), subst_ns_ (subst_ns) { type_factory_map_instance ().register_element ( xml::qualified_name (root_name, root_ns), xml::qualified_name (subst_name, subst_ns), &factory_impl); } + + template + element_factory_initializer:: + ~element_factory_initializer () + { + type_factory_map_instance ().unregister_element ( + xml::qualified_name (root_name_, root_ns_), + xml::qualified_name (subst_name_, subst_ns_)); + } } } } diff --git a/libxsd/xsd/cxx/tree/type-serializer-map.hxx b/libxsd/xsd/cxx/tree/type-serializer-map.hxx index b1ca479..8c7bfca 100644 --- a/libxsd/xsd/cxx/tree/type-serializer-map.hxx +++ b/libxsd/xsd/cxx/tree/type-serializer-map.hxx @@ -38,11 +38,17 @@ namespace xsd bool override = true); void + unregister_type (const type_id&); + + void register_element (const qualified_name& root, const qualified_name& subst, const type_id&, serializer); + void + unregister_element (const qualified_name& root, const type_id&); + public: void serialize (const C* name, // element name @@ -196,17 +202,29 @@ namespace xsd serializer_impl (xercesc::DOMElement&, const type&); + // + // template struct type_serializer_initializer { - // Register type. - // type_serializer_initializer (const C* name, const C* ns); + ~type_serializer_initializer (); + }; - // Register element. - // - type_serializer_initializer (const C* root_name, const C* root_ns, - const C* subst_name, const C* subst_ns); + + // + // + template + struct element_serializer_initializer + { + element_serializer_initializer (const C* root_name, const C* root_ns, + const C* subst_name, const C* subst_ns); + + ~element_serializer_initializer (); + + private: + const C* root_name_; + const C* root_ns_; }; } } diff --git a/libxsd/xsd/cxx/tree/type-serializer-map.txx b/libxsd/xsd/cxx/tree/type-serializer-map.txx index 797cb13..232e239 100644 --- a/libxsd/xsd/cxx/tree/type-serializer-map.txx +++ b/libxsd/xsd/cxx/tree/type-serializer-map.txx @@ -263,6 +263,13 @@ namespace xsd template void type_serializer_map:: + unregister_type (const type_id& tid) + { + type_map_.erase (&tid); + } + + template + void type_serializer_map:: register_element (const qualified_name& root, const qualified_name& subst, const type_id& tid, @@ -273,6 +280,21 @@ namespace xsd template void type_serializer_map:: + unregister_element (const qualified_name& root, const type_id& tid) + { + typename element_map::iterator i (element_map_.find (root)); + + if (i != element_map_.end ()) + { + i->second.erase (&tid); + + if (i->second.empty ()) + element_map_.erase (root); + } + } + + template + void type_serializer_map:: serialize (const C* name, // element name const C* ns, // element namespace bool global, @@ -508,7 +530,6 @@ namespace xsd e << static_cast (x); } - // type_serializer_initializer // template @@ -523,10 +544,18 @@ namespace xsd template type_serializer_initializer:: - type_serializer_initializer (const C* root_name, - const C* root_ns, - const C* subst_name, - const C* subst_ns) + ~type_serializer_initializer () + { + type_serializer_map_instance ().unregister_type (typeid (T)); + } + + // element_serializer_initializer + // + template + element_serializer_initializer:: + element_serializer_initializer (const C* root_name, const C* root_ns, + const C* subst_name, const C* subst_ns) + : root_name_ (root_name), root_ns_ (root_ns) { type_serializer_map_instance ().register_element ( xml::qualified_name (root_name, root_ns), @@ -534,6 +563,14 @@ namespace xsd typeid (T), &serializer_impl); } + + template + element_serializer_initializer:: + ~element_serializer_initializer () + { + type_serializer_map_instance ().unregister_element ( + xml::qualified_name (root_name_, root_ns_), typeid (T)); + } } } } diff --git a/xsd/cxx/tree/serialization-source.cxx b/xsd/cxx/tree/serialization-source.cxx index dda363f..68d14fa 100644 --- a/xsd/cxx/tree/serialization-source.cxx +++ b/xsd/cxx/tree/serialization-source.cxx @@ -862,13 +862,13 @@ namespace CXX String const& name (ename (e)); os << "static" << endl - << "const ::xsd::cxx::tree::type_serializer_initializer< 0, " << + << "const ::xsd::cxx::tree::element_serializer_initializer< 0, " << char_type << ", "; belongs (e, belongs_); os << " >" << endl - << "_xsd_" << name << "_element_name_init (" << endl + << "_xsd_" << name << "_element_serializer_init (" << endl << L << strlit (r.name ()) << "," << endl << L << strlit (r.namespace_ ().name ()) << "," << endl << L << strlit (e.name ()) << "," << endl diff --git a/xsd/cxx/tree/tree-source.cxx b/xsd/cxx/tree/tree-source.cxx index d1353b0..fa9046f 100644 --- a/xsd/cxx/tree/tree-source.cxx +++ b/xsd/cxx/tree/tree-source.cxx @@ -3317,7 +3317,7 @@ namespace CXX Type& r (e.substitutes ().root ()); os << "static" << endl - << "const ::xsd::cxx::tree::type_factory_initializer< 0, " << + << "const ::xsd::cxx::tree::element_factory_initializer< 0, " << char_type << ", "; belongs (e, belongs_); -- cgit v1.1