summaryrefslogtreecommitdiff
path: root/xsd/xsd/cxx/tree/stream-source.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'xsd/xsd/cxx/tree/stream-source.cxx')
-rw-r--r--xsd/xsd/cxx/tree/stream-source.cxx496
1 files changed, 496 insertions, 0 deletions
diff --git a/xsd/xsd/cxx/tree/stream-source.cxx b/xsd/xsd/cxx/tree/stream-source.cxx
new file mode 100644
index 0000000..eeb3ca3
--- /dev/null
+++ b/xsd/xsd/cxx/tree/stream-source.cxx
@@ -0,0 +1,496 @@
+// file : xsd/cxx/tree/stream-source.cxx
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd/cxx/tree/stream-source.hxx>
+
+#include <libxsd-frontend/semantic-graph.hxx>
+#include <libxsd-frontend/traversal.hxx>
+
+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<SemanticGraph::Fundamental::Double> ())
+ base += L", ::xsd::cxx::tree::schema_type::double_";
+ else if (item_type.is_a<SemanticGraph::Fundamental::Decimal> ())
+ base += L", ::xsd::cxx::tree::schema_type::decimal";
+
+ base += L" >";
+
+ os << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "& o, " <<
+ "const " << name << "& i)"
+ << "{"
+ << "return o << static_cast< const " << base << "& > (i);"
+ << "}";
+
+ // Register with ostream 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::std_ostream_initializer< " <<
+ poly_plate << ", " << char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_std_ostream_init;"
+ << 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;
+
+ os << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "& o, " <<
+ "const " << name << "& i)"
+ << "{"
+ << "return o << static_cast< const " << xs_string_type << "& > (i);"
+ << "}";
+
+ // Register with ostream 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::std_ostream_initializer< " <<
+ poly_plate << ", " << char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_std_ostream_init;"
+ << 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* be (0);
+ IsEnumBasedType t (be);
+ t.dispatch (e);
+
+ enum_based = (be != 0);
+ }
+
+ // If we are based on an enum then the value type is just an
+ // alias and we don't need to generate this operator again.
+ //
+ if (string_based && !enum_based)
+ {
+ os << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "& o, " <<
+ name << "::" << evalue (e) << " i)"
+ << "{"
+ << "return o << " << name << "::_xsd_" << name <<
+ "_literals_[i];"
+ << "}";
+ }
+
+ os << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "& o, " <<
+ "const " << name << "& i)"
+ << "{"
+ << "return o << static_cast< const ";
+
+ inherits (e, inherits_base_);
+
+ os << "& > (i);"
+ << "}";
+
+ // Register with ostream 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::std_ostream_initializer< " <<
+ poly_plate << ", " << char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_std_ostream_init;"
+ << endl;
+ }
+ }
+
+ private:
+ Traversal::Inherits inherits_base_;
+ BaseTypeName base_;
+ };
+
+ struct Element: Traversal::Element, Context
+ {
+ Element (Context& c, String const& scope_)
+ : Context (c), scope (scope_)
+ {
+ }
+
+ virtual void
+ traverse (Type& e)
+ {
+ if (skip (e))
+ return;
+
+ String const& aname (eaname (e));
+
+ // Check if we need to handle xsi:type and substitution groups.
+ // If this element'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.
+ //
+ SemanticGraph::Type& t (e.type ());
+ bool poly (polymorphic && polymorphic_p (t) && !anonymous_p (t));
+
+ if (poly)
+ {
+ os << "{"
+ << "::xsd::cxx::tree::std_ostream_map< " << char_type
+ << " >& om (" << endl
+ << "::xsd::cxx::tree::std_ostream_map_instance< " <<
+ poly_plate << ", " << char_type << " > ());"
+ << endl;
+ }
+
+ if (max (e) != 1)
+ {
+ // sequence
+ //
+ os << "for (" << scope << "::" << econst_iterator (e) << endl
+ << "b (i." << aname << " ().begin ()), " <<
+ "e (i." << aname << " ().end ());" << endl
+ << "b != e; ++b)"
+ << "{"
+ << "o << ::std::endl << " << strlit (e.name () + L": ");
+
+ if (!poly)
+ os << " << *b;";
+ else
+ os << ";"
+ << "om.insert (o, *b);";
+
+ os << "}";
+ }
+ else if (min (e) == 0)
+ {
+ // optional
+ //
+
+ os << "if (i." << aname << " ())"
+ << "{"
+ << "o << ::std::endl << " << strlit (e.name () + L": ");
+
+ if (!poly)
+ os << " << *i." << aname << " ();";
+ else
+ os << ";"
+ << "om.insert (o, *i." << aname << " ());";
+
+ os << "}";
+ }
+ else
+ {
+ // one
+ //
+ os << "o << ::std::endl << " << strlit (e.name () + L": ");
+
+ if (!poly)
+ os << " << i." << aname << " ();";
+ else
+ os << ";"
+ << "om.insert (o, i." << aname << " ());";
+ }
+
+ if (poly)
+ os << "}";
+ }
+
+ private:
+ String scope;
+ };
+
+ struct Attribute: Traversal::Attribute, Context
+ {
+ Attribute (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual void
+ traverse (Type& a)
+ {
+ String const& aname (eaname (a));
+
+ if (a.optional_p () && !a.default_p ())
+ {
+ os << "if (i." << aname << " ())"
+ << "{"
+ << "o << ::std::endl << " << strlit (a.name () + L": ") <<
+ " << *i." << aname << " ();"
+ << "}";
+ }
+ else
+ {
+ os << "o << ::std::endl << " << strlit (a.name () + L": ") <<
+ " << i." << aname << " ();";
+ }
+ }
+ };
+
+
+ struct Complex: Traversal::Complex, Context
+ {
+ Complex (Context& c)
+ : Context (c), base_ (c)
+ {
+ inherits_ >> base_;
+ }
+
+ virtual void
+ traverse (Type& c)
+ {
+ 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 has_body (has<Traversal::Member> (c) || c.inherits_p ());
+
+ os << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "& o, " <<
+ "const " << name << "&" << (has_body ? " i" : "") << ")"
+ << "{";
+
+ if (c.inherits_p ())
+ {
+ os << "o << static_cast< const ";
+
+ inherits (c, inherits_);
+
+ os << "& > (i);"
+ << endl;
+ }
+
+ {
+ Traversal::Names names_member;
+ Element element (*this, name);
+ Attribute attribute (*this);
+
+ names_member >> element;
+ names_member >> attribute;
+
+ names (c, names_member);
+ }
+
+ os << "return o;"
+ << "}";
+
+ // Register with ostream 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::std_ostream_initializer< " <<
+ poly_plate << ", " << char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_std_ostream_init;"
+ << endl;
+ }
+ }
+
+ private:
+ Traversal::Inherits inherits_;
+ BaseTypeName base_;
+ };
+ }
+
+ void
+ generate_stream_source (Context& ctx, size_t first, size_t last)
+ {
+ String c (ctx.char_type);
+
+ ctx.os << "#include <ostream>" << endl
+ << endl;
+
+ if (ctx.polymorphic)
+ {
+ ctx.os << "#include <xsd/cxx/tree/std-ostream-map.hxx>" << 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"
+ << "{"
+ << "#ifdef _MSC_VER" << endl;
+
+ if (export_maps)
+ ctx.os << "template struct __declspec (dllexport) " <<
+ "std_ostream_plate< " << ctx.poly_plate << ", " <<
+ ctx.char_type << " >;";
+
+ if (import_maps)
+ ctx.os << "template struct __declspec (dllimport) " <<
+ "std_ostream_plate< " << ctx.poly_plate << ", " <<
+ ctx.char_type << " >;";
+
+ ctx.os << "#elif defined(__GNUC__) && __GNUC__ >= 4" << endl
+ << "template struct __attribute__ ((visibility(\"default\"))) " <<
+ "std_ostream_plate< " << ctx.poly_plate << ", " << ctx.char_type <<
+ " >;";
+
+ ctx.os << "#elif defined(XSD_MAP_VISIBILITY)" << endl
+ << "template struct XSD_MAP_VISIBILITY " <<
+ "std_ostream_plate< " << ctx.poly_plate << ", " << ctx.char_type <<
+ " >;";
+
+ ctx.os << "#endif" << endl
+ << "}" // tree
+ << "}" // cxx
+ << "}" // xsd
+ << "#endif // XSD_NO_EXPORT" << endl
+ << endl;
+ }
+
+ ctx.os << "namespace _xsd"
+ << "{"
+ << "static" << endl
+ << "const ::xsd::cxx::tree::std_ostream_plate< " <<
+ ctx.poly_plate << ", " << ctx.char_type << " >" << endl
+ << "std_ostream_plate_init;"
+ << "}";
+ }
+
+ Traversal::Schema schema;
+
+ Sources sources;
+ Traversal::Names names_ns, names;
+
+ Namespace ns (ctx, first, last);
+
+ 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);
+ }
+ }
+}