From 5e527213a2430bb3018e5eebd909aef294edf9b5 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 18 Dec 2020 18:48:46 +0300 Subject: Switch to build2 --- xsd/xsd/cxx/tree/stream-extraction-source.cxx | 864 ++++++++++++++++++++++++++ 1 file changed, 864 insertions(+) create mode 100644 xsd/xsd/cxx/tree/stream-extraction-source.cxx (limited to 'xsd/xsd/cxx/tree/stream-extraction-source.cxx') diff --git a/xsd/xsd/cxx/tree/stream-extraction-source.cxx b/xsd/xsd/cxx/tree/stream-extraction-source.cxx new file mode 100644 index 0000000..5a5ed66 --- /dev/null +++ b/xsd/xsd/cxx/tree/stream-extraction-source.cxx @@ -0,0 +1,864 @@ +// file : xsd/cxx/tree/stream-extraction-source.cxx +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +#include +#include + +namespace CXX +{ + namespace Tree + { + namespace + { + struct List: Traversal::List, Context + { + List (Context& c) + : Context (c) + { + } + + virtual void + traverse (Type& l) + { + String name (ename (l)); + + // If renamed name is empty then we do not need to generate + // anything for this type. + // + if (renamed_type (l, name) && !name) + return; + + SemanticGraph::Type& item_type (l.argumented ().type ()); + String base (L"::xsd::cxx::tree::list< " + + item_type_name (item_type) + L", " + char_type); + + if (item_type.is_a ()) + base += L", ::xsd::cxx::tree::schema_type::double_"; + else if (item_type.is_a ()) + base += L", ::xsd::cxx::tree::schema_type::decimal"; + + base += L" >"; + + size_t n (0); + NarrowStrings const& st (options.generate_extraction ()); + for (NarrowStrings::const_iterator i (st.begin ()); + i != st.end (); ++i) + { + os << name << "::" << endl + << name << " (" << istream_type << "< " << + i->c_str () << " >& s," << endl + << flags_type << " f," << endl + << container << "* c)" << endl + << ": " << any_simple_type << " (s, f, c)," << endl + << " " << base << " (s, f, this)" + << "{" + << "}"; + + // Register with type map. + // + if (polymorphic && + polymorphic_p (l) && + (!anonymous_p (l) || anonymous_substitutes_p (l))) + { + // Note that we are using the original type name. + // + String const& name (ename (l)); + + os << "static" << endl + << "const ::xsd::cxx::tree::stream_extraction_initializer< " << + poly_plate << ", " << i->c_str () << ", " << char_type << + ", " << name << " >" << endl + << "_xsd_" << name << "_stream_extraction_init_" << + n++ << " (" << endl + << strlit (l.name ()) << "," << endl + << strlit (xml_ns_name (l)) << ");" + << endl; + } + } + } + + private: + String + item_type_name (SemanticGraph::Type& t) + { + std::wostringstream o; + + MemberTypeName type (*this, o); + type.dispatch (t); + + return o.str (); + } + }; + + + struct Union: Traversal::Union, Context + { + Union (Context& c) + : Context (c) + { + } + + virtual void + traverse (Type& u) + { + String name (ename (u)); + + // If renamed name is empty then we do not need to generate + // anything for this type. + // + if (renamed_type (u, name) && !name) + return; + + String const& base (xs_string_type); + + size_t n (0); + NarrowStrings const& st (options.generate_extraction ()); + for (NarrowStrings::const_iterator i (st.begin ()); i != st.end (); + ++i) + { + os << name << "::" << endl + << name << " (" << istream_type << "< " << + i->c_str () << " >& s," << endl + << flags_type << " f," << endl + << container << "* c)" << endl + << ": " << base << " (s, f, c)" + << "{" + << "}"; + + // Register with type map. + // + if (polymorphic && + polymorphic_p (u) && + (!anonymous_p (u) || anonymous_substitutes_p (u))) + { + // Note that we are using the original type name. + // + String const& name (ename (u)); + + os << "static" << endl + << "const ::xsd::cxx::tree::stream_extraction_initializer< " << + poly_plate << ", " << i->c_str () << ", " << char_type << + ", " << name << " >" << endl + << "_xsd_" << name << "_stream_extraction_init_" << + n++ << " (" << endl + << strlit (u.name ()) << "," << endl + << strlit (xml_ns_name (u)) << ");" + << endl; + } + } + } + }; + + + struct Enumeration: Traversal::Enumeration, Context + { + Enumeration (Context& c) + : Context (c), base_ (c) + { + inherits_base_ >> base_; + } + + virtual void + traverse (Type& e) + { + String name (ename (e)); + + // If renamed name is empty then we do not need to generate + // anything for this type. + // + if (renamed_type (e, name) && !name) + return; + + bool string_based (false); + { + IsStringBasedType t (string_based); + t.dispatch (e); + } + + bool enum_based (false); + if (string_based) + { + SemanticGraph::Enumeration* base_enum (0); + IsEnumBasedType t (base_enum); + t.dispatch (e); + + enum_based = (base_enum != 0); + } + + String value; + if (string_based) + value = evalue (e); + + size_t n (0); + NarrowStrings const& st (options.generate_extraction ()); + for (NarrowStrings::const_iterator i (st.begin ()); i != st.end (); + ++i) + { + os << name << "::" << endl + << name << " (" << istream_type << "< " << + i->c_str () << " >& s," << endl + << flags_type << " f," << endl + << container << "* c)" << endl + << ": "; + + inherits (e, inherits_base_); + + if (string_based && !enum_based) + { + // Use copy c-tor to pass the flags and container. + // + os << " (" << endl; + inherits (e, inherits_base_); + os << " (_xsd_" << name << "_literals_[s.read_uint ()]), f, c)"; + } + else + os << " (s, f, c)"; + + os << "{"; + + if (string_based) + os << "_xsd_" << name << "_convert ();"; + + os << "}"; + + // Register with type map. + // + if (polymorphic && + polymorphic_p (e) && + (!anonymous_p (e) || anonymous_substitutes_p (e))) + { + // Note that we are using the original type name. + // + String const& name (ename (e)); + + os << "static" << endl + << "const ::xsd::cxx::tree::stream_extraction_initializer< " << + poly_plate << ", " << i->c_str () << ", " << char_type << + ", " << name << " >" << endl + << "_xsd_" << name << "_stream_extraction_init_" << + n++ << " (" << endl + << strlit (e.name ()) << "," << endl + << strlit (xml_ns_name (e)) << ");" + << endl; + } + } + } + + private: + Traversal::Inherits inherits_base_; + BaseTypeName base_; + }; + + struct CtorMember: Traversal::Member, Context + { + CtorMember (Context& c) + : Context (c) + { + } + + virtual void + traverse (SemanticGraph::Member& m) + { + if (skip (m)) + return; + + os << "," << endl + << " " << emember (m) << " (this)"; + } + }; + + struct CtorAny: Traversal::Any, + Traversal::AnyAttribute, + Context + { + CtorAny (Context& c) + : Context (c) + { + } + + virtual void + traverse (SemanticGraph::Any& a) + { + String const& member (emember (a)); + String const& dom_doc ( + edom_document ( + dynamic_cast (a.scope ()))); + + os << "," << endl + << " " << member << " (this->" << dom_doc << " ())"; + } + + virtual void + traverse (SemanticGraph::AnyAttribute& a) + { + String const& member (emember (a)); + String const& dom_doc ( + edom_document ( + dynamic_cast (a.scope ()))); + + os << "," << endl + << " " << member << " (this->" << dom_doc << " ())"; + } + }; + + struct Element: Traversal::Element, Context + { + Element (Context& c, String const& stream_) + : Context (c), stream (stream_) + { + } + + virtual void + traverse (Type& e) + { + if (skip (e)) + return; + + String const& member (emember (e)); + + SemanticGraph::Type& t (e.type ()); + String type (etype (e)); + String tr (etraits (e)); // traits type name + + bool fund (false); + { + IsFundamentalType traverser (fund); + traverser.dispatch (t); + } + + // Figure out if we need to generate polymorphic code. If this + // elemen's type is anonymous then we don't need to do anything. + // Note that if the type is anonymous then it can't be derived + // from which makes it impossible to substitute or dynamically- + // type with xsi:type. + // + bool poly (polymorphic && polymorphic_p (t) && !anonymous_p (t)); + + // Check if this element is abstract. + // + bool abst (false); + if (poly) + { + SemanticGraph::Complex* tc; + abst = (tc = dynamic_cast (&t)) != 0 && + tc->abstract_p (); + } + + char const* r ( + (poly || !fund) && std >= cxx_version::cxx11 + ? "::std::move (r)" + : "r"); + + if (max (e) != 1) + { + // sequence + // + String container (econtainer (e)); + + os << "{" + << "::std::size_t n;" + << "::xsd::cxx::tree::istream_common::as_size< " << + "::std::size_t > as (n);" + << "s >> as;" + << "if (n > 0)" + << "{" + << container << "& c (this->" << member << ");" + << "c.reserve (n);" + << "while (n--)" + << "{"; + + if (poly) + { + os << auto_ptr << "< " << type << " > r;"; + + if (!abst) + os << "bool d;" + << "s >> d;" + << endl + << "if (!d)" << endl + << "r.reset (new " << type << " (s, f, this));" + << "else" + << "{"; + + os << auto_ptr << "< ::xsd::cxx::tree::type > tmp (" << endl + << "::xsd::cxx::tree::stream_extraction_map_instance< " << + poly_plate << ", " << stream << ", " << char_type << + " > ().extract (" << endl + << "s, f, this));" + << "r.reset (dynamic_cast< " << type << "* > (tmp.get ()));" + << "if (r.get ())" << endl + << "tmp.release ();" + << "else" << endl + << "throw ::xsd::cxx::tree::not_derived< " << char_type << + " > ();"; + + if (!abst) + os << "}"; + } + else if (fund) + { + os << type << " r;" + << "s >> r;"; + } + else + { + os << auto_ptr << "< " << type << " > r (" << endl + << tr << "::create (s, f, this));"; + } + + os << "c.push_back (" << r << ");" + << "}" // while + << "}" // if + << "}"; + } + else if (min (e) == 0) + { + // optional + // + os << "{" + << "bool p;" + << "s >> p;" + << "if (p)" + << "{"; + + if (poly) + { + os << auto_ptr << "< " << type << " > r;"; + + if (!abst) + os << "bool d;" + << "s >> d;" + << endl + << "if (!d)" << endl + << "r.reset (new " << type << " (s, f, this));" + << "else" + << "{"; + + os << auto_ptr << "< ::xsd::cxx::tree::type > tmp (" << endl + << "::xsd::cxx::tree::stream_extraction_map_instance< " << + poly_plate << ", " << stream << ", " << char_type << + " > ().extract (" << endl + << "s, f, this));" + << "r.reset (dynamic_cast< " << type << "* > (tmp.get ()));" + << "if (r.get ())" << endl + << "tmp.release ();" + << "else" << endl + << "throw ::xsd::cxx::tree::not_derived< " << char_type << + " > ();"; + + if (!abst) + os << "}"; + } + else if (fund) + { + os << type << " r;" + << "s >> r;"; + } + else + { + os << auto_ptr << "< " << type << " > r (" << endl + << tr << "::create (s, f, this));"; + } + + os << "this->" << member << ".set (" << r << ");" + << "}" // if (p) + << "}"; + } + else + { + // one + // + os << "{"; + + if (poly) + { + os << auto_ptr << "< " << type << " > r;"; + + if (!abst) + os << "bool d;" + << "s >> d;" + << endl + << "if (!d)" << endl + << "r.reset (new " << type << " (s, f, this));" + << "else" + << "{"; + + os << auto_ptr << "< ::xsd::cxx::tree::type > tmp (" << endl + << "::xsd::cxx::tree::stream_extraction_map_instance< " << + poly_plate << ", " << stream << ", " << char_type << + " > ().extract (" << endl + << "s, f, this));" + << "r.reset (dynamic_cast< " << type << "* > (tmp.get ()));" + << "if (r.get ())" << endl + << "tmp.release ();" + << "else" << endl + << "throw ::xsd::cxx::tree::not_derived< " << char_type << + " > ();"; + + if (!abst) + os << "}"; + } + else if (fund) + { + os << type << " r;" + << "s >> r;"; + } + else + { + os << auto_ptr << "< " << type << " > r (" << endl + << tr << "::create (s, f, this));"; + } + + os << "this->" << member << ".set (" << r << ");" + << "}"; + } + } + + private: + String stream; + }; + + struct Attribute: Traversal::Attribute, Context + { + Attribute (Context& c) + : Context (c) + { + } + + virtual void + traverse (Type& a) + { + String const& member (emember (a)); + String type (etype (a)); + String tr (etraits (a)); // traits type name + + bool fund (false); + { + IsFundamentalType traverser (fund); + traverser.dispatch (a.type ()); + } + + if (a.optional_p () && !a.default_p ()) + { + os << "{" + << "bool p;" + << "s >> p;" + << "if (p)" + << "{"; + + if (fund) + { + os << type << " r;" + << "s >> r;" + << "this->" << member << ".set (r);"; + } + else + { + os << "this->" << member << ".set (" << tr << + "::create (s, f, this));"; + } + + os << "}" // if (p) + << "}"; + } + else + { + os << "{"; + + if (fund) + { + os << type << " r;" + << "s >> r;" + << "this->" << member << ".set (r);"; + } + else + { + os << "this->" << member << ".set (" << tr << + "::create (s, f, this));"; + } + + os << "}"; + } + } + }; + + struct Complex: Traversal::Complex, Context + { + Complex (Context& c) + : Context (c), base_ (c), ctor_any_ (c), ctor_member_ (c) + { + inherits_ >> base_; + names_ctor_member_ >> ctor_member_; + + if (options.generate_wildcard ()) + names_ctor_member_ >> ctor_any_; + } + + virtual void + traverse (Type& c) + { + SemanticGraph::Context& ctx (c.context ()); + + String name (ename (c)); + + // If renamed name is empty then we do not need to generate + // anything for this type. + // + if (renamed_type (c, name) && !name) + return; + + bool ordered (ordered_p (c) && !ctx.count ("order-in-base")); + bool has_members (has (c)); + + bool facets (false); + if (c.inherits_p ()) + { + // See if we have any facets that we need to handle. + // + using SemanticGraph::Restricts; + using SemanticGraph::Fundamental::Decimal; + + if (Restricts* r = dynamic_cast (&c.inherits ())) + { + if (!r->facet_empty () && + (r->facet_find ("fractionDigits") != r->facet_end () || + r->facet_find ("totalDigits") != r->facet_end ()) && + ultimate_base (c).is_a ()) + facets = true; + } + } + + size_t n (0); + NarrowStrings const& st (options.generate_extraction ()); + for (NarrowStrings::const_iterator i (st.begin ()); i != st.end (); + ++i) + { + os << name << "::" << endl + << name << " (" << istream_type << "< " << + i->c_str () << " >& s," << endl + << flags_type << " f," << endl + << container << "* c)" << endl + << ": "; + + if (c.inherits_p ()) + inherits (c, inherits_); + else + os << any_type; + + os << " (s, f, c)"; + + if (edom_document_member_p (c)) + { + os << "," << endl + << " " << edom_document_member (c) << " (" << + "::xsd::cxx::xml::dom::create_document< " << char_type << + " > ())"; + } + + names (c, names_ctor_member_); + + os << "{"; + + if (facets) + os << "this->_facet_table (_xsd_" << name << "_facet_table);" + << endl; + + if (has_members) + os << "this->" << unclash (name, "parse") << " (s, f);"; + + os << "}"; + + // Parse + // + if (ordered || has_members) + { + os << "void " << name << "::" << endl + << unclash (name, "parse") << " (" << + istream_type << "< " << i->c_str () << " >& s," << endl + << flags_type << " f)" + << "{" + << "XSD_UNUSED (f);"; // Can be unused. + + // Read the order sequence. + // + if (ordered) + { + String const& t (ctx.get ("order-type")); + String const& m (ctx.get ("order-member")); + + os << "{" + << "::std::size_t n;" + << "::xsd::cxx::tree::istream_common::as_size< " << + "::std::size_t > na (n);" + << "s >> na;" + << "if (n > 0)" + << "{" + << "this->" << m << ".reserve (n);" + << "while (n--)" + << "{" + << "::std::size_t id, in;" + << "::xsd::cxx::tree::istream_common::as_size< " << + "::std::size_t > ida (id), ina (in);" + << "s >> ida;" + << "s >> ina;" + << "this->" << m << ".push_back (" << t << " (id, in));" + << "}" // while + << "}" // if + << "}"; + } + + { + Element element (*this, *i); + Attribute attribute (*this); + Traversal::Names names_; + + names_ >> element; + names_ >> attribute; + + names (c, names_); + } + + os << "}"; + } + + + // Register with type map. + // + if (polymorphic && + polymorphic_p (c) && + !c.abstract_p () && + (!anonymous_p (c) || anonymous_substitutes_p (c))) + { + // Note that we are using the original type name. + // + String const& name (ename (c)); + + os << "static" << endl + << "const ::xsd::cxx::tree::stream_extraction_initializer< " << + poly_plate << ", " << i->c_str () << ", " << char_type << + ", " << name << " >" << endl + << "_xsd_" << name << "_stream_extraction_init_" << + n++ << " (" << endl + << strlit (c.name ()) << "," << endl + << strlit (xml_ns_name (c)) << ");" + << endl; + } + } + } + + private: + Traversal::Inherits inherits_; + BaseTypeName base_; + + CtorAny ctor_any_; + CtorMember ctor_member_; + + Traversal::Names names_ctor_member_; + }; + } + + void + generate_stream_extraction_source (Context& ctx) + { + if (ctx.polymorphic) + { + NarrowStrings const& st (ctx.options.generate_extraction ()); + + ctx.os << "#include " << endl + << endl; + + bool import_maps (ctx.options.import_maps ()); + bool export_maps (ctx.options.export_maps ()); + + if (import_maps || export_maps) + { + ctx.os << "#ifndef XSD_NO_EXPORT" << endl + << endl + << "namespace xsd" + << "{" + << "namespace cxx" + << "{" + << "namespace tree" + << "{"; + + for (NarrowStrings::const_iterator i (st.begin ()); i != st.end (); + ++i) + { + String stream (*i); + + ctx.os << "#ifdef _MSC_VER" << endl; + + if (export_maps) + ctx.os << "template struct __declspec (dllexport) " << + "stream_extraction_plate< " << ctx.poly_plate << ", " << + stream << ", " << ctx.char_type << " >;"; + + if (import_maps) + ctx.os << "template struct __declspec (dllimport) " << + "stream_extraction_plate< " << ctx.poly_plate << ", " << + stream << ", " << ctx.char_type << " >;"; + + ctx.os << "#elif defined(__GNUC__) && __GNUC__ >= 4" << endl + << "template struct __attribute__ ((visibility(\"default\"))) " << + "stream_extraction_plate< " << ctx.poly_plate << ", " << + stream << ", " << ctx.char_type << " >;" + << "#elif defined(XSD_MAP_VISIBILITY)" << endl + << "template struct XSD_MAP_VISIBILITY " << + "stream_extraction_plate< " << ctx.poly_plate << ", " << + stream << ", " << ctx.char_type << " >;" + << "#endif" << endl; + } + + ctx.os << "}" // tree + << "}" // cxx + << "}" // xsd + << "#endif // XSD_NO_EXPORT" << endl + << endl; + + } + + ctx.os << "namespace _xsd" + << "{"; + + size_t n (0); + for (NarrowStrings::const_iterator i (st.begin ()); i != st.end (); + ++i) + { + String stream (*i); + + ctx.os << "static" << endl + << "const ::xsd::cxx::tree::stream_extraction_plate< " << + ctx.poly_plate << ", " << stream << ", " << ctx.char_type << + " >" << endl + << "stream_extraction_plate_init_" << n++ << ";"; + } + + ctx.os << "}"; + } + + Traversal::Schema schema; + + Sources sources; + Traversal::Names names_ns, names; + + Namespace ns (ctx); + + List list (ctx); + Union union_ (ctx); + Complex complex (ctx); + Enumeration enumeration (ctx); + + schema >> sources >> schema; + schema >> names_ns >> ns >> names; + + names >> list; + names >> union_; + names >> complex; + names >> enumeration; + + schema.dispatch (ctx.schema_root); + } + } +} -- cgit v1.1