summaryrefslogtreecommitdiff
path: root/xsd/xsd/cxx/tree/serialization-source.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'xsd/xsd/cxx/tree/serialization-source.cxx')
-rw-r--r--xsd/xsd/cxx/tree/serialization-source.cxx370
1 files changed, 250 insertions, 120 deletions
diff --git a/xsd/xsd/cxx/tree/serialization-source.cxx b/xsd/xsd/cxx/tree/serialization-source.cxx
index 40ae031..559a3cf 100644
--- a/xsd/xsd/cxx/tree/serialization-source.cxx
+++ b/xsd/xsd/cxx/tree/serialization-source.cxx
@@ -1,6 +1,5 @@
// file : xsd/cxx/tree/serialization-source.cxx
-// author : Boris Kolpackov <boris@codesynthesis.com>
-// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// copyright : Copyright (c) 2005-2014 Code Synthesis Tools CC
// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
#include <cxx/tree/serialization-source.hxx>
@@ -42,7 +41,7 @@ namespace CXX
{
}
- virtual Void
+ virtual void
traverse (Type& l)
{
String name (ename (l));
@@ -91,7 +90,9 @@ namespace CXX
<< "l << static_cast< const " << base << "& > (i);"
<< "}";
- // Register with type factory map.
+ // Register with type factory map. If this type is anonymous
+ // but substitutes, then it will be registered as part of the
+ // substitution registration.
//
if (polymorphic && polymorphic_p (l) && !anonymous_p (l))
{
@@ -100,8 +101,8 @@ namespace CXX
String const& name (ename (l));
os << "static" << endl
- << "const ::xsd::cxx::tree::type_serializer_initializer< 0, " <<
- char_type << ", " << name << " >" << endl
+ << "const ::xsd::cxx::tree::type_serializer_initializer< " <<
+ poly_plate << ", " << char_type << ", " << name << " >" << endl
<< "_xsd_" << name << "_type_serializer_init (" << endl
<< strlit (l.name ()) << "," << endl
<< strlit (xml_ns_name (l)) << ");"
@@ -131,7 +132,7 @@ namespace CXX
{
}
- virtual Void
+ virtual void
traverse (Type& u)
{
String name (ename (u));
@@ -171,7 +172,9 @@ namespace CXX
<< "l << static_cast< const " << base << "& > (i);"
<< "}";
- // Register with type factory map.
+ // Register with type factory map. If this type is anonymous
+ // but substitutes, then it will be registered as part of the
+ // substitution registration.
//
if (polymorphic && polymorphic_p (u) && !anonymous_p (u))
{
@@ -180,8 +183,8 @@ namespace CXX
String const& name (ename (u));
os << "static" << endl
- << "const ::xsd::cxx::tree::type_serializer_initializer< 0, " <<
- char_type << ", " << name << " >" << endl
+ << "const ::xsd::cxx::tree::type_serializer_initializer< " <<
+ poly_plate << ", " << char_type << ", " << name << " >" << endl
<< "_xsd_" << name << "_type_serializer_init (" << endl
<< strlit (u.name ()) << "," << endl
<< strlit (xml_ns_name (u)) << ");"
@@ -200,7 +203,7 @@ namespace CXX
inherits_base_ >> base_;
}
- virtual Void
+ virtual void
traverse (Type& e)
{
String name (ename (e));
@@ -253,7 +256,9 @@ namespace CXX
<< "}";
- // Register with type factory map.
+ // Register with type factory map. If this type is anonymous
+ // but substitutes, then it will be registered as part of the
+ // substitution registration.
//
if (polymorphic && polymorphic_p (e) && !anonymous_p (e))
{
@@ -262,8 +267,8 @@ namespace CXX
String const& name (ename (e));
os << "static" << endl
- << "const ::xsd::cxx::tree::type_serializer_initializer< 0, " <<
- char_type << ", " << name << " >" << endl
+ << "const ::xsd::cxx::tree::type_serializer_initializer< " <<
+ poly_plate << ", " << char_type << ", " << name << " >" << endl
<< "_xsd_" << name << "_type_serializer_init (" << endl
<< strlit (e.name ()) << "," << endl
<< strlit (xml_ns_name (e)) << ");"
@@ -284,12 +289,17 @@ namespace CXX
{
}
- virtual Void
+ virtual void
traverse (Type& e)
{
if (skip (e))
return;
+ SemanticGraph::Complex& c (
+ dynamic_cast<SemanticGraph::Complex&> (e.scope ()));
+
+ bool ordered (ordered_p (c));
+
String const& aname (eaname (e));
String ns (e.qualified_p () ? e.namespace_ ().name () : "");
String type (scope + L"::" + etype (e));
@@ -301,20 +311,23 @@ namespace CXX
// dynamically-type with xsi:type.
//
SemanticGraph::Type& t (e.type ());
- Boolean poly (polymorphic && polymorphic_p (t) && !anonymous_p (t));
+ bool poly (polymorphic && polymorphic_p (t) && !anonymous_p (t));
os << "// " << comment (e.name ()) << endl
<< "//" << endl;
- // aCC cannot handle an inline call to type_serializer_map_instance.
- //
+ if (ordered)
+ os << "case " << scope << "::" <<
+ e.context ().get<String> ("ordered-id-name") << ":"
+ << "{";
+
if (poly)
{
- os << "{"
+ os << (ordered ? "" : "{")
<< "::xsd::cxx::tree::type_serializer_map< " << char_type
<< " >& tsm (" << endl
- << "::xsd::cxx::tree::type_serializer_map_instance< 0, " <<
- char_type << " > ());"
+ << "::xsd::cxx::tree::type_serializer_map_instance< " <<
+ poly_plate << ", " << char_type << " > ());"
<< endl;
}
@@ -322,15 +335,22 @@ namespace CXX
{
// sequence
//
- os << "for (" << scope << "::" << econst_iterator (e) << endl
- << "b (i." << aname << " ().begin ()), " <<
- "n (i." << aname << " ().end ());" << endl
- << "b != n; ++b)"
- << "{";
+ if (ordered)
+ os << "const " << type << "& x (i." << aname <<
+ " ()[b->index]);"
+ << endl;
+ else
+ os << "for (" << scope << "::" << econst_iterator (e) << endl
+ << "b (i." << aname << " ().begin ()), " <<
+ "n (i." << aname << " ().end ());" << endl
+ << "b != n; ++b)"
+ << "{";
+
+ char const* x (ordered ? "x" : "*b");
if (poly)
{
- os << "if (typeid (" << type << ") == typeid (*b))"
+ os << "if (typeid (" << type << ") == typeid (" << x << "))"
<< "{"
<< xerces_ns << "::DOMElement& s (" << endl
<< "::xsd::cxx::xml::dom::create_element (" << endl
@@ -338,14 +358,14 @@ namespace CXX
<< (ns ? strlit (ns) + L",\n" : L"")
<< "e));"
<< endl
- << "s << *b;"
+ << "s << " << x << ";"
<< "}"
<< "else" << endl
<< "tsm.serialize (" << endl
<< strlit (e.name ()) << "," << endl
<< strlit (ns) << "," << endl
<< (e.global_p () ? "true" : "false") << ", " <<
- (e.qualified_p () ? "true" : "false") << ", e, *b);";
+ (e.qualified_p () ? "true" : "false") << ", e, " << x << ");";
}
else
{
@@ -360,30 +380,29 @@ namespace CXX
{
case st_other:
{
- os << "s << *b;";
+ os << "s << " << x << ";";
break;
}
case st_double:
{
- os << "s << " << as_double_type << " (*b);";
+ os << "s << " << as_double_type << " (" << x << ");";
break;
}
case st_decimal:
{
- os << "s << " << as_decimal_type << " (*b);";
+ os << "s << " << as_decimal_type << " (" << x << ");";
break;
}
}
}
-
- os << "}";
}
else if (min (e) == 0)
{
// optional
//
- os << "if (i." << aname << " ())"
- << "{";
+ if (!ordered)
+ os << "if (i." << aname << " ())"
+ << "{";
if (poly)
{
@@ -433,8 +452,6 @@ namespace CXX
}
}
}
-
- os << "}";
}
else
{
@@ -462,8 +479,10 @@ namespace CXX
}
else
{
- os << "{"
- << xerces_ns << "::DOMElement& s (" << endl
+ if (!ordered)
+ os << "{";
+
+ os << xerces_ns << "::DOMElement& s (" << endl
<< "::xsd::cxx::xml::dom::create_element (" << endl
<< strlit (e.name ()) << "," << endl
<< (ns ? strlit (ns) + L",\n" : L"")
@@ -488,13 +507,26 @@ namespace CXX
break;
}
}
-
- os << "}";
}
}
- if (poly)
+ if (ordered)
+ {
+ // See comment for bool text (false); below.
+ //
+ if (mixed_p (c) && c.context ().get<size_t> ("ordered-start") != 1)
+ os << "text = true;";
+
+ os << "continue;"
+ << "}";
+ }
+ else
+ {
os << "}";
+
+ if (poly && (max (e) != 1 || min (e) == 0))
+ os << "}"; // There is no extra block for poly one.
+ }
}
private:
@@ -508,51 +540,80 @@ namespace CXX
{
}
- virtual Void
+ virtual void
traverse (Type& a)
{
+ SemanticGraph::Complex& c (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ()));
+
+ bool ordered (ordered_p (c));
+
String const& aname (eaname (a));
os << "// " << ename (a) << endl
<< "//" << endl;
+ if (ordered)
+ os << "case " << scope << "::" <<
+ a.context ().get<String> ("ordered-id-name") << ":";
+
if (max (a) != 1)
{
// sequence
//
- os << "for (" << scope << "::" << econst_iterator (a) << endl
- << "b (i." << aname << " ().begin ()), " <<
- "n (i." << aname << " ().end ());" << endl
- << "b != n; ++b)"
- << "{"
+ if (!ordered)
+ os << "for (" << scope << "::" << econst_iterator (a) << endl
+ << "b (i." << aname << " ().begin ()), " <<
+ "n (i." << aname << " ().end ());" << endl
+ << "b != n; ++b)";
+
+ os << "{"
<< "e.appendChild (" << endl
<< "e.getOwnerDocument ()->importNode (" << endl
<< "const_cast< " << xerces_ns <<
- "::DOMElement* > (&(*b)), true));"
- << "}";
+ "::DOMElement* > (&(" <<
+ (ordered ? (L"i." + aname + L" ()[b->index]") : L"*b") <<
+ ")), true));";
}
else if (min (a) == 0)
{
// optional
//
- os << "if (i." << aname << " ())"
- << "{"
+ if (!ordered)
+ os << "if (i." << aname << " ())";
+
+ os << "{"
<< "e.appendChild (" << endl
<< "e.getOwnerDocument ()->importNode (" << endl
<< "const_cast< " << xerces_ns << "::DOMElement* > (&(*i." <<
- aname << " ())), true));"
- << "}";
+ aname << " ())), true));";
}
else
{
// one
//
+ if (ordered)
+ os << "{";
+
os << "e.appendChild (" << endl
<< "e.getOwnerDocument ()->importNode (" << endl
<< "const_cast< " << xerces_ns << "::DOMElement* > (&(i." <<
aname << " ())), true));"
<< endl;
}
+
+ if (ordered)
+ {
+ // See comment for bool text (false); below.
+ //
+ if (mixed_p (c) && c.context ().get<size_t> ("ordered-start") != 1)
+ os << "text = true;";
+
+ os << "continue;";
+ }
+
+ if (ordered || max (a) != 1 || min (a) == 0)
+ os << "}";
}
private:
@@ -566,7 +627,7 @@ namespace CXX
{
}
- virtual Void
+ virtual void
traverse (Type& a)
{
String const& aname (eaname (a));
@@ -611,8 +672,7 @@ namespace CXX
{
// Make sure we serialize required fixed attributes.
//
- if (a.optional_p () &&
- options.value<CLI::omit_default_attributes> ())
+ if (a.optional_p () && options.omit_default_attributes ())
{
os << "if (i." << aname << " () != " << scope <<
"::" << edefault_value (a) << " ())";
@@ -660,7 +720,7 @@ namespace CXX
{
}
- virtual Void
+ virtual void
traverse (Type& a)
{
String const& aname (eaname (a));
@@ -697,9 +757,11 @@ namespace CXX
inherits_ >> base_;
}
- virtual Void
+ 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
@@ -729,7 +791,7 @@ namespace CXX
// Serialize anyAttribute content first so that is gets
// overriden by schema-defined attributes.
//
- if (options.value<CLI::generate_wildcard> ())
+ if (options.generate_wildcard ())
{
AnyAttribute any_attribute (*this, name);
Traversal::Names names (any_attribute);
@@ -738,24 +800,109 @@ namespace CXX
}
{
+ bool o (ordered_p (c));
+ size_t start, count;
+
+ if (o)
+ {
+ start = ctx.get<size_t> ("ordered-start");
+ count = ctx.get<size_t> ("ordered-count");
+
+ if (start != count)
+ {
+ String const& ci (ctx.get<String> ("order-const-iterator"));
+ String const& an (ctx.get<String> ("order-aname"));
+
+ // If we have mixed content and a base, then we have to
+ // skip the text content until we serialize one of "our"
+ // elements.
+ //
+ if (mixed_p (c) && start != 1)
+ os << "bool text (false);"
+ << endl;
+
+ os << "for (" << name << "::" << ci << endl
+ << "b (i." << an << " ().begin ()), n (i." << an <<
+ " ().end ());" << endl
+ << "b != n; ++b)"
+ << "{"
+ << "switch (b->id)"
+ << "{";
+ }
+ }
+
Traversal::Names names;
Any any (*this, name);
Element element (*this, name);
- Attribute attribute (*this, name);
names >> element;
- names >> attribute;
- if (options.value<CLI::generate_wildcard> ())
+ if (options.generate_wildcard ())
names >> any;
Complex::names (c, names);
+
+ if (o)
+ {
+ if (start != count)
+ {
+ if (mixed_p (c))
+ {
+ //@@ propagate mixed-ordered-id to derived
+
+ os << "// text_content" << endl
+ << "//" << endl
+ << "case " << name << "::" <<
+ ctx.get<String> ("mixed-ordered-id-name") << ":"
+ << "{";
+
+ // See the comment above.
+ //
+ if (start != 1)
+ os << "if (text)" << endl;
+
+ os << "e.appendChild (" << endl
+ << "e.getOwnerDocument ()->createTextNode (" << endl
+ << "::xsd::cxx::xml::string (" << endl
+ << "i." << ctx.get<String> ("mixed-aname") <<
+ " ()[b->index].c_str ()).c_str ()));";
+
+ // os << "e << i." << ctx.get<String> ("mixed-aname") <<
+ // " ()[b->index];";
+
+ os << "continue;"
+ << "}";
+ }
+
+ // Ignore content before our id range and stop serializing
+ // if we see anything past. This handles inheritance.
+ //
+ os << "default:"
+ << "{";
+
+ if (start != 1)
+ os << "if (b->id < " << start << "UL)" << endl
+ << "continue;";
+
+ os << "break;" // Stop (see break below).
+ << "}";
+
+ os << "}" // switch
+ << "break;" // Unknown element past our elements.
+ << "}"; // for
+ }
+ }
}
- os << "}";
+ {
+ Attribute attribute (*this, name);
+ Traversal::Names names (attribute);
+ Complex::names (c, names);
+ }
+ os << "}";
- Boolean simple (true);
+ bool simple (true);
{
IsSimpleType t (simple);
t.dispatch (c);
@@ -763,7 +910,7 @@ namespace CXX
if (simple)
{
- Boolean hb (c.inherits_p ());
+ bool hb (c.inherits_p ());
// operator<< (xercesc::DOMAttr)
//
@@ -805,7 +952,9 @@ namespace CXX
os << "}";
}
- // Register with type factory map.
+ // Register with type factory map. If this type is anonymous
+ // but substitutes, then it will be registered as part of the
+ // substitution registration.
//
if (polymorphic && polymorphic_p (c) && !anonymous_p (c))
{
@@ -814,8 +963,8 @@ namespace CXX
String const& name (ename (c));
os << "static" << endl
- << "const ::xsd::cxx::tree::type_serializer_initializer< 0, " <<
- char_type << ", " << name << " >" << endl
+ << "const ::xsd::cxx::tree::type_serializer_initializer< " <<
+ poly_plate << ", " << char_type << ", " << name << " >" << endl
<< "_xsd_" << name << "_type_serializer_init (" << endl
<< strlit (c.name ()) << "," << endl
<< strlit (xml_ns_name (c)) << ");"
@@ -842,7 +991,7 @@ namespace CXX
belongs_ >> type_name_;
}
- virtual Void
+ virtual void
traverse (Type& e)
{
if (polymorphic && e.substitutes_p ())
@@ -852,8 +1001,8 @@ namespace CXX
String const& name (ename (e));
os << "static" << endl
- << "const ::xsd::cxx::tree::element_serializer_initializer< 0, " <<
- char_type << ", ";
+ << "const ::xsd::cxx::tree::element_serializer_initializer< " <<
+ poly_plate << ", " << char_type << ", ";
belongs (e, belongs_);
@@ -881,11 +1030,11 @@ namespace CXX
ElementType (Context& c)
: GlobalElementBase (c),
Context (c),
- element_map_ (c.options.value<CLI::generate_element_map> ())
+ element_map_ (c.options.generate_element_map ())
{
}
- virtual Void
+ virtual void
traverse (Type& e)
{
if (doc_root_p (e))
@@ -921,7 +1070,7 @@ namespace CXX
}
private:
- Boolean element_map_;
+ bool element_map_;
};
struct ElementFunction: Traversal::Element,
@@ -933,7 +1082,7 @@ namespace CXX
{
}
- virtual Void
+ virtual void
traverse (Type& e)
{
if (!doc_root_p (e))
@@ -954,7 +1103,7 @@ namespace CXX
// If this element's type is anonymous then we don't need to do
// anything.
//
- Boolean poly (polymorphic &&
+ bool poly (polymorphic &&
polymorphic_p (type) &&
!anonymous_p (type));
@@ -1137,18 +1286,11 @@ namespace CXX
if (poly)
{
- // aCC cannot handle an inline call to
- // type_serializer_map_instance.
- //
os << "}"
<< "else"
<< "{"
- << "::xsd::cxx::tree::type_serializer_map< " << char_type
- << " >& tsm (" << endl
- << "::xsd::cxx::tree::type_serializer_map_instance< 0, " <<
- char_type << " > ());"
- << endl
- << "tsm.serialize (" << endl
+ << "::xsd::cxx::tree::type_serializer_map_instance< " <<
+ poly_plate << ", " << char_type << " > ().serialize (" << endl
<< strlit (e.name ()) << "," << endl
<< strlit (e.namespace_().name ()) << "," << endl
<< "e, n, s);"
@@ -1168,37 +1310,23 @@ namespace CXX
if (poly)
{
- // aCC cannot handle an inline call to
- // type_serializer_map_instance as well as the direct
- // auto_ptr assignment.
- //
os << dom_auto_ptr << "< " << xerces_ns << "::DOMDocument > d;"
<< endl
<< "if (typeid (" << type_name (e) << ") == typeid (s))"
<< "{"
- << dom_auto_ptr << "< " << xerces_ns <<
- "::DOMDocument > r (" << endl
- << "::xsd::cxx::xml::dom::serialize< " <<
+ << "d = ::xsd::cxx::xml::dom::serialize< " <<
char_type << " > (" << endl
<< strlit (e.name ()) << "," << endl
<< strlit (ns) << "," << endl
- << "m, f));"
- << "d = r;"
+ << "m, f);"
<< "}"
<< "else"
<< "{"
- << "::xsd::cxx::tree::type_serializer_map< " << char_type
- << " >& tsm (" << endl
- << "::xsd::cxx::tree::type_serializer_map_instance< 0, " <<
- char_type << " > ());"
- << endl
- << dom_auto_ptr << "< " << xerces_ns <<
- "::DOMDocument > r (" << endl
- << "tsm.serialize (" << endl
+ << "d = ::xsd::cxx::tree::type_serializer_map_instance< " <<
+ poly_plate << ", " << char_type << " > ().serialize (" << endl
<< strlit (e.name ()) << "," << endl
<< strlit (e.namespace_().name ()) << "," << endl
- << "m, s, f));"
- << "d = r;"
+ << "m, s, f);"
<< "}";
}
else
@@ -1233,12 +1361,10 @@ namespace CXX
};
}
- Void
- generate_serialization_source (Context& ctx,
- UnsignedLong first,
- UnsignedLong last)
+ void
+ generate_serialization_source (Context& ctx, size_t first, size_t last)
{
- Boolean elemen_type (ctx.options.value<CLI::generate_element_type> ());
+ bool elemen_type (ctx.options.generate_element_type ());
if (!elemen_type)
ctx.os << "#include <ostream>" << endl
@@ -1252,8 +1378,8 @@ namespace CXX
ctx.os << "#include <xsd/cxx/tree/type-serializer-map.hxx>" << endl
<< endl;
- Boolean import_maps (ctx.options.value<CLI::import_maps> ());
- Boolean export_maps (ctx.options.value<CLI::export_maps> ());
+ bool import_maps (ctx.options.import_maps ());
+ bool export_maps (ctx.options.export_maps ());
if (import_maps || export_maps)
{
@@ -1269,19 +1395,23 @@ namespace CXX
if (export_maps)
ctx.os << "template struct __declspec (dllexport) " <<
- "type_serializer_plate< 0, " << ctx.char_type << " >;";
+ "type_serializer_plate< " << ctx.poly_plate << ", " <<
+ ctx.char_type << " >;";
if (import_maps)
ctx.os << "template struct __declspec (dllimport) " <<
- "type_serializer_plate< 0, " << ctx.char_type << " >;";
+ "type_serializer_plate< " << ctx.poly_plate << ", " <<
+ ctx.char_type << " >;";
ctx.os << "#elif defined(__GNUC__) && __GNUC__ >= 4" << endl
<< "template struct __attribute__ ((visibility(\"default\"))) " <<
- "type_serializer_plate< 0, " << ctx.char_type << " >;";
+ "type_serializer_plate< " << ctx.poly_plate << ", " <<
+ ctx.char_type << " >;";
ctx.os << "#elif defined(XSD_MAP_VISIBILITY)" << endl
<< "template struct XSD_MAP_VISIBILITY " <<
- "type_serializer_plate< 0, " << ctx.char_type << " >;";
+ "type_serializer_plate< " << ctx.poly_plate << ", " <<
+ ctx.char_type << " >;";
ctx.os << "#endif" << endl
<< "}" // tree
@@ -1294,15 +1424,15 @@ namespace CXX
ctx.os << "namespace _xsd"
<< "{"
<< "static" << endl
- << "const ::xsd::cxx::tree::type_serializer_plate< 0, " <<
- ctx.char_type << " >" << endl
+ << "const ::xsd::cxx::tree::type_serializer_plate< " <<
+ ctx.poly_plate << ", " << ctx.char_type << " >" << endl
<< "type_serializer_plate_init;"
<< "}";
}
Traversal::Schema schema;
- Traversal::Sources sources;
+ Sources sources;
Traversal::Names names_ns, names;
Namespace ns (ctx, first, last);