diff options
Diffstat (limited to 'xsd/xsd/cxx/tree/serialization-source.cxx')
-rw-r--r-- | xsd/xsd/cxx/tree/serialization-source.cxx | 370 |
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); |