C++/Tree Mapping Runtime Library
elements.hxx
Go to the documentation of this file.
1// file : xsd/cxx/tree/elements.hxx
2// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
3
15#ifndef XSD_CXX_TREE_ELEMENTS_HXX
16#define XSD_CXX_TREE_ELEMENTS_HXX
17
18#include <xsd/cxx/config.hxx> // XSD_AUTO_PTR, XSD_CXX11
19
20#include <map>
21#include <string>
22#include <memory> // std::auto_ptr/unique_ptr
23#include <cstddef> // std::size_t
24#include <istream>
25#include <sstream>
26#include <cassert>
27
28#ifdef XSD_CXX11
29# include <utility> // std::move
30#endif
31
32#include <xercesc/dom/DOMNode.hpp>
33#include <xercesc/dom/DOMAttr.hpp>
34#include <xercesc/dom/DOMElement.hpp>
35#include <xercesc/dom/DOMDocument.hpp>
36#include <xercesc/dom/DOMNamedNodeMap.hpp>
37
38#include <xercesc/util/XercesVersion.hpp>
39
40#include <xsd/cxx/xml/elements.hxx> // xml::properties
41#include <xsd/cxx/xml/dom/auto-ptr.hxx> // dom::auto_ptr/unique_ptr
42#include <xsd/cxx/xml/dom/wildcard-source.hxx> // dom::create_document()
43
44#include <xsd/cxx/tree/facet.hxx>
46#include <xsd/cxx/tree/istream-fwd.hxx>
47#include <xsd/cxx/tree/containers-wildcard.hxx>
48
49#if _XERCES_VERSION < 30000
50# error Xerces-C++ 2-series is not supported
51#endif
52
53namespace xsd
54{
55 namespace cxx
56 {
65 namespace tree
66 {
75 class flags
76 {
77 public:
82
86 static const unsigned long keep_dom = 0x00000100UL;
87
96 static const unsigned long own_dom = 0x00000200UL;
97
102 static const unsigned long dont_validate = 0x00000400UL;
103
108 static const unsigned long extract_content = 0x00000800UL;
109
113 static const unsigned long dont_initialize = 0x00000001UL;
114
118 static const unsigned long no_xml_declaration = 0x00010000UL;
119
124 static const unsigned long dont_pretty_print = 0x00020000UL;
125
126 //@cond
127
128 // The following flags are for internal use.
129 //
130 static const unsigned long base = 0x01000000UL;
131
132 //@endcond
133
134 // Notes on flag blocks:
135 //
136 // 0x000000FF - common (applicable to both parsing and serialization)
137 // 0x0000FF00 - parsing (values aligned with XML parsing)
138 // 0x00FF0000 - serialization (values aligned with XML serialization)
139 // 0xFF000000 - internal
140
142
143 public:
149 flags (unsigned long x = 0)
150 : x_ (x)
151 {
152 }
153
159 operator unsigned long () const
160 {
161 return x_;
162 }
163
169 friend flags
170 operator| (const flags& a, const flags& b)
171 {
172 return flags (a.x_ | b.x_);
173 }
174
180 friend flags
181 operator| (const flags& a, unsigned long b)
182 {
183 return flags (a.x_ | b);
184 }
185
191 friend flags
192 operator| (unsigned long a, const flags& b)
193 {
194 return flags (a | b.x_);
195 }
196
197 private:
198 unsigned long x_;
199 };
200
201 // Parsing properties. Refer to xsd/cxx/xml/elements.hxx for XML-
202 // related properties.
203 //
204 template <typename C>
205 class properties: public xml::properties<C>
206 {
207 };
208
215 {
222 content_order (std::size_t id, std::size_t index = 0)
223 : id (id), index (index)
224 {
225 }
226
230 std::size_t id;
231
235 std::size_t index;
236 };
237
238 //@cond
239
240 bool
242
243 bool
245
246 bool
247 operator< (const content_order&, const content_order&);
248
249 // DOM user data keys.
250 //
251 template <int dummy>
252 struct user_data_keys_template
253 {
254 // Back pointers to tree nodes.
255 //
256 static const XMLCh node[21];
257 };
258
259 typedef user_data_keys_template<0> user_data_keys;
260
261 //
262 //
263 struct identity
264 {
265 virtual
266 ~identity ()
267 {
268 }
269
270 identity ()
271 {
272 }
273
274 virtual bool
275 before (const identity&) const = 0;
276
277 virtual void
278 throw_duplicate_id () const = 0;
279
280 private:
281 identity (const identity&);
282
283 identity&
284 operator= (const identity&);
285 };
286
287 //@endcond
288
289
290 // anyType. VC++ has a name injection bug that makes it impossible
291 // to have a member with the same name as a base type. To address
292 // that we will have to choose some unique name for the definition
293 // and typedef it to 'type'.
294 //
295 class _type;
296
301 typedef _type type;
302
308
317 class _type
318 {
319 public:
320 virtual
321 ~_type ()
322 {
323 // Everything should have been unregistered by now.
324 //
325 assert (map_.get () == 0 || map_->size () == 0);
326 }
327
328 public:
333
338
349 template <typename C>
350 explicit
351 _type (const C* s);
352
353 public:
363 _type (const type& x, flags f = 0, container* c = 0);
364
376 virtual type*
377 _clone (flags f = 0, container* c = 0) const
378 {
379 return new type (*this, f, c);
380 }
381
382 public:
392 template <typename S>
393 _type (istream<S>& s, flags f = 0, container* c = 0);
394
403 _type (const xercesc::DOMElement& e,
405 container* c = 0);
406
415 _type (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
416
426 template <typename C>
427 _type (const std::basic_string<C>& s,
428 const xercesc::DOMElement* e,
429 flags f = 0,
430 container* c = 0);
432
433 public:
440 type&
441 operator= (const type& x)
442 {
443 if (this != &x)
444 {
445 if (x.content_.get () == 0)
446 content_.reset ();
447 else
448 content_ = x.content_->clone ();
449
450 // Drop DOM association.
451 //
452 dom_info_.reset ();
453 }
454
455 return *this;
456 }
457
458 // anyType content API.
459 //
460 public:
461 //@cond
462 typedef element_optional dom_content_optional;
463 //@endcond
464
474 const dom_content_optional&
475 dom_content () const;
476
485 dom_content_optional&
487
496 void
497 dom_content (const xercesc::DOMElement& e);
498
510 void
511 dom_content (xercesc::DOMElement* e);
512
522 void
523 dom_content (const dom_content_optional& d);
524
534 const xercesc::DOMDocument&
536
546 xercesc::DOMDocument&
548
559 bool
560 null_content () const;
561
562 //
563 //
564 public:
572 friend bool
573 operator== (const type& x, const type& y)
574 {
575 return x.content_.get () != 0 &&
576 x.content_->compare (y.content_.get ());
577 }
578
586 friend bool
587 operator!= (const type& x, const type& y) {return !(x == y);}
588
589 // Container API.
590 //
591 public:
599 const container*
600 _container () const
601 {
602 return container_;
603 }
604
612 container*
614 {
615 return container_;
616 }
617
624 virtual void
626 {
627 container* dr (0);
628
629 if (c != 0)
630 {
631 dr = c->_root ();
632
633 if (dr == 0)
634 dr = c;
635 }
636
637 XSD_AUTO_PTR<map>& m (dr ? dr->map_ : map_);
638
639 if (container_ == 0)
640 {
641 if (c != 0 && map_.get () != 0)
642 {
643 // Transfer our IDs to the new root.
644 //
645 if (m.get () != 0)
646 {
647 m->insert (map_->begin (), map_->end ());
648 map_.reset ();
649 }
650 else
651 {
652#ifdef XSD_CXX11
653 m = std::move (map_);
654#else
655 m = map_;
656#endif
657 }
658 }
659 }
660 else
661 {
662 container* sr (_root ());
663
664 if (sr->map_.get () != 0)
665 {
666 // Transfer IDs that belong to this subtree.
667 //
668 for (map::iterator i (sr->map_->begin ()), e (sr->map_->end ());
669 i != e;)
670 {
671 type* x (i->second);
672 for (; x != this && x != sr; x = x->_container ()) ;
673
674 if (x != sr)
675 {
676 // Part of our subtree.
677 //
678 if (m.get () == 0)
679 m.reset (new map);
680
681 m->insert (*i);
682 sr->map_->erase (i++);
683 }
684 else
685 ++i;
686 }
687 }
688 }
689
690 container_ = c;
691 }
692
699 const container*
700 _root () const
701 {
702 const container* r (container_);
703
704 for (const container* c (r); c != 0; c = c->container_)
705 r = c;
706
707 return r;
708 }
709
716 container*
718 {
719 container* r (container_);
720
721 for (container* c (r); c != 0; c = c->container_)
722 r = c;
723
724 return r;
725 }
726
727 // DOM association.
728 //
729 public:
736 const xercesc::DOMNode*
737 _node () const
738 {
739 return dom_info_.get () ? dom_info_->node() : 0;
740 }
741
748 xercesc::DOMNode*
750 {
751 return dom_info_.get () ? dom_info_->node () : 0;
752 }
753
758 class bad_dom_node_type: public std::exception //@@ Inherit exception<C>.
759 {
760 public:
766 virtual const char*
767 what () const throw ()
768 {
769 return "DOM node is not an attribute node or element node";
770 }
771 };
772
785 void
786 _node (xercesc::DOMNode* n)
787 {
788 switch (n->getNodeType ())
789 {
790 case xercesc::DOMNode::ELEMENT_NODE:
791 {
792 if (container_ != 0)
793 {
794 assert (_root ()->_node () != 0);
795 assert (_root ()->_node ()->getOwnerDocument () ==
796 n->getOwnerDocument ());
797 }
798
799 dom_info_ =
800 dom_info_factory::create (
801 *static_cast<xercesc::DOMElement*> (n),
802 *this,
803 container_ == 0);
804
805 break;
806 }
807 case xercesc::DOMNode::ATTRIBUTE_NODE:
808 {
809 assert (container_ != 0);
810 assert (_root ()->_node () != 0);
811 assert (_root ()->_node ()->getOwnerDocument () ==
812 n->getOwnerDocument ());
813
814 dom_info_ =
815 dom_info_factory::create (
816 *static_cast<xercesc::DOMAttr*> (n),
817 *this);
818
819 break;
820 }
821 default:
822 {
823 throw bad_dom_node_type ();
824 }
825 }
826 }
827
828 public:
829 //@cond
830
831 void
832 _register_id (const identity& i, type* t)
833 {
834 // We should be the root.
835 //
836 assert (container_ == 0);
837
838 if (map_.get () == 0)
839 map_.reset (new map);
840
841 if (!map_->insert (
842 std::pair<const identity*, type*> (&i, t)).second)
843 {
844 i.throw_duplicate_id ();
845 }
846 }
847
848 //@@ Does not inherit from exception<C>.
849 //
850 struct not_registered: std::exception
851 {
852 virtual const char*
853 what () const throw ()
854 {
855 return "attempt to unregister non-existent id";
856 }
857 };
858
859 void
860 _unregister_id (const identity& id)
861 {
862 // We should be the root.
863 //
864 assert (container_ == 0);
865
866 if (map_.get () == 0 || map_->erase (&id) == 0)
867 throw not_registered ();
868 }
869
870 type*
871 _lookup_id (const identity& id) const
872 {
873 if (map_.get ())
874 {
875 map::const_iterator it (map_->find (&id));
876
877 if (it != map_->end ())
878 return it->second;
879 }
880
881 return 0;
882 }
883
884 //@endcond
885
886 private:
887 //@cond
888
889 struct dom_info
890 {
891 virtual
892 ~dom_info () {}
893
894 dom_info () {}
895
896 virtual XSD_AUTO_PTR<dom_info>
897 clone (type& tree_node, container*) const = 0;
898
899 virtual xercesc::DOMNode*
900 node () = 0;
901
902 private:
903 dom_info (const dom_info&);
904 dom_info& operator= (const dom_info&);
905 };
906
907 struct dom_element_info: public dom_info
908 {
909 dom_element_info (xercesc::DOMElement& e, type& n, bool root)
910 : e_ (e)
911 {
912 e_.setUserData (user_data_keys::node, &n, 0);
913
914 if (root)
915 {
916 // The caller should have associated a dom::auto/unique_ptr
917 // object that owns this document with the document node
918 // using the xml_schema::dom::tree_node_key key.
919 //
920 XSD_DOM_AUTO_PTR<xercesc::DOMDocument>* pd (
921 reinterpret_cast<XSD_DOM_AUTO_PTR<xercesc::DOMDocument>*> (
922 e.getOwnerDocument ()->getUserData (user_data_keys::node)));
923
924 assert (pd != 0);
925 assert (pd->get () == e.getOwnerDocument ());
926
927 // Transfer ownership.
928#ifdef XSD_CXX11
929 doc_ = std::move (*pd);
930#else
931 doc_ = *pd;
932#endif
933 }
934 }
935
936 virtual XSD_AUTO_PTR<dom_info>
937 clone (type& tree_node, container* c) const
938 {
939 // Check if we are a document root.
940 //
941 if (c == 0)
942 {
943 // We preserver DOM associations only in complete
944 // copies from root.
945 //
946 return XSD_AUTO_PTR<dom_info> (
947 doc_.get () == 0
948 ? 0
949 : new dom_element_info (*doc_, tree_node));
950 }
951
952 // Check if our container does not have DOM association (e.g.,
953 // because it wasn't a complete copy of the tree).
954 //
955 using xercesc::DOMNode;
956
957 DOMNode* cn (c->_node ());
958
959 if (cn == 0)
960 return XSD_AUTO_PTR<dom_info> ();
961
962 // Now we are going to find the corresponding element in
963 // the new tree.
964 //
965 {
966 using xercesc::DOMElement;
967
968 DOMNode& pn (*e_.getParentNode ());
969 assert (pn.getNodeType () == DOMNode::ELEMENT_NODE);
970
971 DOMNode* sn (pn.getFirstChild ()); // Source.
972 DOMNode* dn (cn->getFirstChild ()); // Destination.
973
974 // We should have at least one child.
975 //
976 assert (sn != 0);
977
978 // Move in parallel until we get to the needed node.
979 //
980 for (; sn != 0 && !e_.isSameNode (sn);)
981 {
982 sn = sn->getNextSibling ();
983 dn = dn->getNextSibling ();
984 }
985
986 // e_ should be on the list.
987 //
988 assert (sn != 0);
989
990 assert (dn->getNodeType () == DOMNode::ELEMENT_NODE);
991
992 return XSD_AUTO_PTR<dom_info> (
993 new dom_element_info (static_cast<DOMElement&> (*dn),
994 tree_node,
995 false));
996 }
997 }
998
999 virtual xercesc::DOMNode*
1000 node ()
1001 {
1002 return &e_;
1003 }
1004
1005 private:
1006 dom_element_info (const xercesc::DOMDocument& d, type& n)
1007 : doc_ (static_cast<xercesc::DOMDocument*> (
1008 d.cloneNode (true))),
1009 e_ (*doc_->getDocumentElement ())
1010 {
1011 e_.setUserData (user_data_keys::node, &n, 0);
1012 }
1013
1014 private:
1015 XSD_DOM_AUTO_PTR<xercesc::DOMDocument> doc_;
1016 xercesc::DOMElement& e_;
1017 };
1018
1019
1020 struct dom_attribute_info: public dom_info
1021 {
1022 dom_attribute_info (xercesc::DOMAttr& a, type& n)
1023 : a_ (a)
1024 {
1025 a_.setUserData (user_data_keys::node, &n, 0);
1026 }
1027
1028 virtual XSD_AUTO_PTR<dom_info>
1029 clone (type& tree_node, container* c) const
1030 {
1031 // Check if we are a document root.
1032 //
1033 if (c == 0)
1034 {
1035 // We preserver DOM associations only in complete
1036 // copies from root.
1037 //
1038 return XSD_AUTO_PTR<dom_info> ();
1039 }
1040
1041 // Check if our container does not have DOM association (e.g.,
1042 // because it wasn't a complete copy of the tree).
1043 //
1044 using xercesc::DOMNode;
1045
1046 DOMNode* cn (c->_node ());
1047
1048 if (cn == 0)
1049 return XSD_AUTO_PTR<dom_info> ();
1050
1051 // We are going to find the corresponding attribute in
1052 // the new tree.
1053 //
1054 using xercesc::DOMAttr;
1055 using xercesc::DOMElement;
1056 using xercesc::DOMNamedNodeMap;
1057
1058 DOMElement& p (*a_.getOwnerElement ());
1059 DOMNamedNodeMap& nl (*p.getAttributes ());
1060
1061 XMLSize_t size (nl.getLength ()), i (0);
1062
1063 // We should have at least one child.
1064 //
1065 assert (size != 0);
1066
1067 for ( ;i < size && !a_.isSameNode (nl.item (i)); ++i)/*noop*/;
1068
1069 // a_ should be in the list.
1070 //
1071 assert (i < size);
1072
1073 DOMNode& n (*cn->getAttributes ()->item (i));
1074 assert (n.getNodeType () == DOMNode::ATTRIBUTE_NODE);
1075
1076 return XSD_AUTO_PTR<dom_info> (
1077 new dom_attribute_info (static_cast<DOMAttr&> (n), tree_node));
1078 }
1079
1080 virtual xercesc::DOMNode*
1081 node ()
1082 {
1083 return &a_;
1084 }
1085
1086 private:
1087 xercesc::DOMAttr& a_;
1088 };
1089
1090 // For Sun C++ 5.6.
1091 //
1092 struct dom_info_factory;
1093 friend struct _type::dom_info_factory;
1094
1095 struct dom_info_factory
1096 {
1097 static XSD_AUTO_PTR<dom_info>
1098 create (const xercesc::DOMElement& e, type& n, bool root)
1099 {
1100 return XSD_AUTO_PTR<dom_info> (
1101 new dom_element_info (
1102 const_cast<xercesc::DOMElement&> (e), n, root));
1103 }
1104
1105 static XSD_AUTO_PTR<dom_info>
1106 create (const xercesc::DOMAttr& a, type& n)
1107 {
1108 return XSD_AUTO_PTR<dom_info> (
1109 new dom_attribute_info (
1110 const_cast<xercesc::DOMAttr&> (a), n));
1111 }
1112 };
1113
1114 //@endcond
1115
1116 XSD_AUTO_PTR<dom_info> dom_info_;
1117
1118
1119 // ID/IDREF map.
1120 //
1121 private:
1122
1123 //@cond
1124
1125 struct identity_comparator
1126 {
1127 bool operator () (const identity* x, const identity* y) const
1128 {
1129 return x->before (*y);
1130 }
1131 };
1132
1133 //@endcond
1134
1135 typedef
1136 std::map<const identity*, type*, identity_comparator>
1137 map;
1138
1139 XSD_AUTO_PTR<map> map_;
1140
1141 // anyType and anySimpleType content.
1142 //
1143 protected:
1144
1145 //@cond
1146
1147 struct content_type
1148 {
1149 virtual
1150 ~content_type () {}
1151
1152 content_type () {}
1153
1154 virtual XSD_AUTO_PTR<content_type>
1155 clone () const = 0;
1156
1157 virtual bool
1158 compare (const content_type*) const = 0;
1159
1160 private:
1161 content_type (const content_type&);
1162 content_type& operator= (const content_type&);
1163 };
1164
1165 struct dom_content_type: content_type
1166 {
1167 dom_content_type ()
1168 : doc (xml::dom::create_document<char> ()), dom (*doc) {}
1169
1170 explicit
1171 dom_content_type (const xercesc::DOMElement& e)
1172 : doc (xml::dom::create_document<char> ()), dom (e, *doc) {}
1173
1174 explicit
1175 dom_content_type (xercesc::DOMElement* e)
1176 : doc (xml::dom::create_document<char> ()), dom (e, *doc) {}
1177
1178 explicit
1179 dom_content_type (const dom_content_optional& d)
1180 : doc (xml::dom::create_document<char> ()), dom (d, *doc) {}
1181
1182 virtual XSD_AUTO_PTR<content_type>
1183 clone () const
1184 {
1185 return XSD_AUTO_PTR<content_type> (new dom_content_type (dom));
1186 }
1187
1188 virtual bool
1189 compare (const content_type* c) const
1190 {
1191 if (const dom_content_type* dc =
1192 dynamic_cast<const dom_content_type*> (c))
1193 return dom == dc->dom;
1194
1195 return false;
1196 }
1197
1198 public:
1199 XSD_DOM_AUTO_PTR<xercesc::DOMDocument> doc;
1200 dom_content_optional dom;
1201 };
1202
1203 mutable XSD_AUTO_PTR<content_type> content_;
1204
1205 //@endcond
1206
1207 private:
1208 container* container_;
1209 };
1210
1217 template <typename C, typename B>
1218 class simple_type: public B
1219 {
1220 public:
1225
1230
1236 simple_type (const C* s);
1237
1243 simple_type (const std::basic_string<C>& s);
1244
1245 public:
1255 simple_type (const simple_type& x, flags f = 0, container* c = 0);
1256
1257#ifdef XSD_CXX11
1259 operator= (const simple_type&) = default;
1260#endif
1261
1273 virtual simple_type*
1274 _clone (flags f = 0, container* c = 0) const;
1275
1276 public:
1286 template <typename S>
1287 simple_type (istream<S>& s,
1289 container* c = 0);
1290
1299 simple_type (const xercesc::DOMElement& e,
1301 container* c = 0);
1302
1311 simple_type (const xercesc::DOMAttr& a,
1313 container* c = 0);
1314
1324 simple_type (const std::basic_string<C>& s,
1325 const xercesc::DOMElement* e,
1327 container* c = 0);
1329
1330 // anySimpleType content API.
1331 //
1332 public:
1339 const std::basic_string<C>&
1341
1348 std::basic_string<C>&
1350
1356 void
1357 text_content (const std::basic_string<C>& t);
1358
1359 protected:
1360 //@cond
1361
1362 typedef typename B::content_type content_type;
1363
1364 struct text_content_type: content_type
1365 {
1366 text_content_type () {}
1367
1368 explicit
1369 text_content_type (const std::basic_string<C>& t): text (t) {}
1370
1371 explicit
1372 text_content_type (const C* t): text (t) {}
1373
1374 virtual XSD_AUTO_PTR<content_type>
1375 clone () const
1376 {
1377 return XSD_AUTO_PTR<content_type> (new text_content_type (text));
1378 }
1379
1380 virtual bool
1381 compare (const content_type* c) const
1382 {
1383 if (const text_content_type* tc =
1384 dynamic_cast<const text_content_type*> (c))
1385 return text == tc->text;
1386
1387 return false;
1388 }
1389
1390 public:
1391 // It would have been more elegant to store text content as DOMText.
1392 // However, that would require Xerces-C++ initialization. Also
1393 // having a separate DOMDocument for each text node seems like
1394 // an overkill.
1395 //
1396 std::basic_string<C> text;
1397 };
1398
1399 //@endcond
1400 };
1401
1402
1410 template <typename C, typename T>
1412 {
1413 public:
1414 virtual
1415 ~element_type ()
1416 {
1417 }
1418
1429 virtual element_type*
1430 _clone (flags f = 0) const = 0;
1431
1438 virtual const std::basic_string<C>&
1439 _name () const = 0;
1440
1448 virtual const std::basic_string<C>&
1449 _namespace () const = 0;
1450
1457 virtual T*
1458 _value () = 0;
1459
1466 virtual const T*
1467 _value () const = 0;
1468 };
1469
1470
1471 //@cond
1472
1473 // Extra schema type id to disambiguate certain cases where
1474 // different XML Schema types (e.g., double and decimal) are
1475 // mapped to the same fundamental C++ type (e.g., double).
1476 //
1477 struct schema_type
1478 {
1479 enum value
1480 {
1481 other,
1482 double_,
1483 decimal
1484 };
1485 };
1486
1487 //@endcond
1488
1489
1490 //@cond
1491 template <typename T,
1492 typename C,
1493 schema_type::value ST = schema_type::other>
1494 struct traits
1495 {
1496 typedef T type;
1497
1498 static XSD_AUTO_PTR<T>
1499 create (const xercesc::DOMElement& e, flags f, container* c)
1500 {
1501 return XSD_AUTO_PTR<T> (new T (e, f, c));
1502 }
1503
1504 static XSD_AUTO_PTR<T>
1505 create (const xercesc::DOMAttr& a, flags f, container* c)
1506 {
1507 return XSD_AUTO_PTR<T> (new T (a, f, c));
1508 }
1509
1510 static XSD_AUTO_PTR<T>
1511 create (const std::basic_string<C>& s,
1512 const xercesc::DOMElement* e,
1513 flags f,
1514 container* c)
1515 {
1516 return XSD_AUTO_PTR<T> (new T (s, e, f, c));
1517 }
1518
1519 // For now for istream we only go through traits for non-
1520 // fundamental types.
1521 //
1522 template <typename S>
1523 static XSD_AUTO_PTR<T>
1524 create (istream<S>& s, flags f, container* c)
1525 {
1526 return XSD_AUTO_PTR<T> (new T (s, f, c));
1527 }
1528 };
1529
1530 template <typename B,
1531 typename C,
1532 schema_type::value ST>
1533 struct traits<simple_type<C, B>, C, ST>
1534 {
1535 typedef simple_type<C, B> type;
1536
1537 static XSD_AUTO_PTR<type>
1538 create (const xercesc::DOMElement& e, flags f, container* c)
1539 {
1540 return XSD_AUTO_PTR<type> (
1541 new type (e, f | flags::extract_content, c));
1542 }
1543
1544 static XSD_AUTO_PTR<type>
1545 create (const xercesc::DOMAttr& a, flags f, container* c)
1546 {
1547 return XSD_AUTO_PTR<type> (
1548 new type (a, f | flags::extract_content, c));
1549 }
1550
1551 static XSD_AUTO_PTR<type>
1552 create (const std::basic_string<C>& s,
1553 const xercesc::DOMElement* e,
1554 flags f,
1555 container* c)
1556 {
1557 return XSD_AUTO_PTR<type> (
1558 new type (s, e, f | flags::extract_content, c));
1559 }
1560
1561 template <typename S>
1562 static XSD_AUTO_PTR<type>
1563 create (istream<S>& s, flags f, container* c)
1564 {
1565 return XSD_AUTO_PTR<type> (
1566 new type (s, f | flags::extract_content, c));
1567 }
1568 };
1569 //@endcond
1570
1571
1578 template <typename T,
1579 typename C,
1580 typename B,
1581 schema_type::value ST = schema_type::other>
1582 class fundamental_base: public B
1583 {
1584 public:
1589
1594 : facet_table_ (0), x_ ()
1595 {
1596 }
1597
1604 : facet_table_ (0), x_ (x)
1605 {
1606 }
1607
1608 public:
1619 flags f = 0,
1620 container* c = 0)
1621 : B (x, f, c), facet_table_ (0), x_ (x.x_)
1622 {
1623 }
1624
1625#ifdef XSD_CXX11
1627 operator= (const fundamental_base&) = default;
1628#endif
1629
1641 virtual fundamental_base*
1642 _clone (flags f = 0, container* c = 0) const;
1643
1644 public:
1654 template <typename S>
1655 fundamental_base (istream<S>& s, flags f = 0, container* c = 0);
1656
1665 fundamental_base (const xercesc::DOMElement& e,
1666 flags f = 0,
1667 container* c = 0);
1668
1677 fundamental_base (const xercesc::DOMAttr& a,
1678 flags f = 0,
1679 container* c = 0);
1680
1690 fundamental_base (const std::basic_string<C>& s,
1691 const xercesc::DOMElement* e,
1692 flags f = 0,
1693 container* c = 0);
1695
1696 public:
1704 operator= (const T& x)
1705 {
1706 if (&x_ != &x)
1707 x_ = x;
1708
1709 return *this;
1710 }
1711
1712 public:
1719 operator const T& () const
1720 {
1721 return x_;
1722 }
1723
1730 operator T& ()
1731 {
1732 return x_;
1733 }
1734
1735 // The following extra conversion operators causes problems on
1736 // some compilers (notably VC 9.0) and are disabled by default.
1737 //
1738#ifdef XSD_TREE_EXTRA_FUND_CONV
1745 template <typename T2>
1746 operator T2 () const
1747 {
1748 return x_;
1749 }
1750
1756 template <typename T2>
1757 operator T2 ()
1758 {
1759 return x_;
1760 }
1761#endif // XSD_TREE_EXTRA_FUND_CONV
1762
1763 public:
1769 const facet*
1771 {
1772 return facet_table_;
1773 }
1774
1775 protected:
1781 void
1782 _facet_table (const facet* ft)
1783 {
1784 facet_table_ = ft;
1785 }
1786
1787 private:
1788 const facet* facet_table_;
1789 T x_;
1790 };
1791
1792 // While thse operators are not normally necessary, they
1793 // help resolve ambiguities between implicit conversion and
1794 // construction.
1795 //
1796
1802 template <typename T, typename C, typename B, schema_type::value ST>
1803 inline bool
1806 {
1807 T x_ (x);
1808 T y_ (y);
1809 return x_ == y_;
1810 }
1811
1817 template <typename T, typename C, typename B, schema_type::value ST>
1818 inline bool
1821 {
1822 T x_ (x);
1823 T y_ (y);
1824 return x_ != y_;
1825 }
1826
1827
1828 //@cond
1829
1830 // Comparator for enum tables.
1831 //
1832 template <typename C>
1833 struct enum_comparator
1834 {
1835 enum_comparator (const C* const* table)
1836 : table_ (table)
1837 {
1838 }
1839
1840 bool
1841 operator() (std::size_t i, const std::basic_string<C>& s) const
1842 {
1843 return table_[i] < s;
1844 }
1845
1846 bool
1847 operator() (const std::basic_string<C>& s, std::size_t i) const
1848 {
1849 return s < table_[i];
1850 }
1851
1852 // This overload shouldn't be necessary according to the standard
1853 // and removing it doesn't appear to trip any old compilers that
1854 // we still support. But let's keeps preprocessed-out until we
1855 // go C++11-only.
1856 //
1857#if 0
1858 bool
1859 operator() (std::size_t i, std::size_t j) const
1860 {
1861 return std::basic_string<C> (table_[i]) < table_[j];
1862 }
1863#endif
1864
1865 private:
1866 const C* const* table_;
1867 };
1868
1869 //@endcond
1870 }
1871 }
1872}
1873
1874#include <xsd/cxx/tree/elements.ixx>
1875#include <xsd/cxx/tree/elements.txx>
1876
1877#endif // XSD_CXX_TREE_ELEMENTS_HXX
Exception indicating that a DOM node cannot be associated with an object model node.
Definition elements.hxx:759
virtual const char * what() const
Get exception description.
Definition elements.hxx:767
Class corresponding to the XML Schema anyType built-in type.
Definition elements.hxx:318
container * _container()
Get a pointer to container, an object model node that contains this instance.
Definition elements.hxx:613
void _node(xercesc::DOMNode *n)
Manually set a DOM node associated with this object model node.
Definition elements.hxx:786
friend bool operator!=(const type &x, const type &y)
Comparison operator. It uses DOM (anyType) or text (anySimpleType) content if present....
Definition elements.hxx:587
virtual type * _clone(flags f=0, container *c=0) const
Copy the instance polymorphically.
Definition elements.hxx:377
xercesc::DOMDocument & dom_content_document()
Return a read-write reference to the DOM document associated with this anyType instance.
const xercesc::DOMDocument & dom_content_document() const
Return a read-only (constant) reference to the DOM document associated with this anyType instance.
void dom_content(xercesc::DOMElement *e)
Set the anyType DOM content.
void dom_content(const xercesc::DOMElement &e)
Set the anyType DOM content.
_type(const xercesc::DOMAttr &a, flags f=0, container *c=0)
Create an instance from a DOM Attribute.
container * _root()
Get a pointer to object model's root node.
Definition elements.hxx:717
_type(const type &x, flags f=0, container *c=0)
Copy constructor.
const container * _container() const
Get a constant pointer to container, an object model node that contains this instance.
Definition elements.hxx:600
type & operator=(const type &x)
Copy assignment operator.
Definition elements.hxx:441
void dom_content(const dom_content_optional &d)
Set the anyType DOM content.
_type(istream< S > &s, flags f=0, container *c=0)
Create an instance from a data representation stream.
bool null_content() const
Check for absence of DOM (anyType) and text (anySimpleType) content.
const xercesc::DOMNode * _node() const
Get a constant pointer to a DOM node associated with this object model node.
Definition elements.hxx:737
_type(const xercesc::DOMElement &e, flags f=flags::extract_content, container *c=0)
Create an instance from a DOM element.
xercesc::DOMNode * _node()
Get a pointer to a DOM node associated with this object model node.
Definition elements.hxx:749
_type()
Default constructor.
const container * _root() const
Get a constant pointer to object model's root node.
Definition elements.hxx:700
_type(const C *s)
Create an instance from a C string.
friend bool operator==(const type &x, const type &y)
Comparison operator. It uses DOM (anyType) or text (anySimpleType) content if present....
Definition elements.hxx:573
_type(const std::basic_string< C > &s, const xercesc::DOMElement *e, flags f=0, container *c=0)
Create an instance from a string fragment.
const dom_content_optional & dom_content() const
Return a read-only (constant) reference to the anyType DOM content.
virtual void _container(container *c)
Set this instance's new container, an object model node that contains this instance.
Definition elements.hxx:625
dom_content_optional & dom_content()
Return a read-write reference to the anyType DOM content.
Base class for element types.
Definition elements.hxx:1412
virtual T * _value()=0
Return the element value.
virtual element_type * _clone(flags f=0) const =0
Copy the instance polymorphically.
virtual const std::basic_string< C > & _namespace() const =0
Return the element namespace.
virtual const std::basic_string< C > & _name() const =0
Return the element name.
virtual const T * _value() const =0
Return the element value.
Parsing and serialization flags.
Definition elements.hxx:76
static const unsigned long dont_validate
Turn off XML Schema validation in the underlying XML parser.
Definition elements.hxx:102
static const unsigned long extract_content
Extract XML content for anyType or anySimpleType. Normally you don't need to specify this flag explic...
Definition elements.hxx:108
static const unsigned long dont_pretty_print
Do not add extra spaces or new lines that make the resulting XML easier to read.
Definition elements.hxx:124
friend flags operator|(const flags &a, const flags &b)
Combine two flags.
Definition elements.hxx:170
flags(unsigned long x=0)
Initialize an instance with an integer value.
Definition elements.hxx:149
static const unsigned long dont_initialize
Do not initialize the Xerces-C++ runtime.
Definition elements.hxx:113
static const unsigned long own_dom
Assume ownership of the DOM document.
Definition elements.hxx:96
static const unsigned long keep_dom
Keep DOM association in the resulting tree.
Definition elements.hxx:86
static const unsigned long no_xml_declaration
Do not write XML declaration during serialization.
Definition elements.hxx:118
Class template that emulates inheritance from a fundamental C++ type.
Definition elements.hxx:1583
fundamental_base(istream< S > &s, flags f=0, container *c=0)
Create an instance from a data representation stream.
fundamental_base & operator=(const T &x)
Assign an underlying type value to the instance.
Definition elements.hxx:1704
fundamental_base(T x)
Initialize an instance with an underlying type value.
Definition elements.hxx:1603
void _facet_table(const facet *ft)
Set the facet table associated with this type.
Definition elements.hxx:1782
virtual fundamental_base * _clone(flags f=0, container *c=0) const
Copy the instance polymorphically.
fundamental_base(const std::basic_string< C > &s, const xercesc::DOMElement *e, flags f=0, container *c=0)
Create an instance from a string fragment.
const facet * _facet_table() const
Get the facet table associated with this type.
Definition elements.hxx:1770
fundamental_base()
Default constructor.
Definition elements.hxx:1593
fundamental_base(const xercesc::DOMAttr &a, flags f=0, container *c=0)
Create an instance from a DOM Attribute.
fundamental_base(const xercesc::DOMElement &e, flags f=0, container *c=0)
Create an instance from a DOM element.
fundamental_base(const fundamental_base &x, flags f=0, container *c=0)
Copy constructor.
Definition elements.hxx:1618
Class corresponding to the XML Schema ID built-in type.
Definition types.hxx:1931
Definition elements.hxx:206
Class corresponding to the XML Schema anySimpleType built-in type.
Definition elements.hxx:1219
const std::basic_string< C > & text_content() const
Return a read-only (constant) reference to the anySimpleType text content.
simple_type(istream< S > &s, flags f=flags::extract_content, container *c=0)
Create an instance from a data representation stream.
void text_content(const std::basic_string< C > &t)
Set the anySimpleType text content.
simple_type(const xercesc::DOMElement &e, flags f=flags::extract_content, container *c=0)
Create an instance from a DOM element.
simple_type(const std::basic_string< C > &s)
Create an instance from a string.
virtual simple_type * _clone(flags f=0, container *c=0) const
Copy the instance polymorphically.
simple_type(const xercesc::DOMAttr &a, flags f=flags::extract_content, container *c=0)
Create an instance from a DOM Attribute.
simple_type(const simple_type &x, flags f=0, container *c=0)
Copy constructor.
std::basic_string< C > & text_content()
Return a read-write reference to the anySimpleType text content.
simple_type()
Default constructor.
simple_type(const std::basic_string< C > &s, const xercesc::DOMElement *e, flags f=flags::extract_content, container *c=0)
Create an instance from a string fragment.
simple_type(const C *s)
Create an instance from a C string.
Contains exception definitions for the C++/Tree mapping.
_type type
Class corresponding to the XML Schema anyType built-in type.
Definition elements.hxx:301
bool operator==(const buffer< C > &a, const buffer< C > &b)
buffer comparison operator.
Definition buffer.hxx:311
bool operator!=(const buffer< C > &a, const buffer< C > &b)
buffer comparison operator.
Definition buffer.hxx:325
_type container
Container type.
Definition elements.hxx:307
Content order sequence entry.
Definition elements.hxx:215
std::size_t id
Content id.
Definition elements.hxx:230
std::size_t index
Content index.
Definition elements.hxx:235
content_order(std::size_t id, std::size_t index=0)
Initialize an instance with passed id and index.
Definition elements.hxx:222

Copyright © 2005-2023 Code Synthesis.