Line data Source code
1 : // file : xsd/cxx/tree/serialization.txx
2 : // copyright : Copyright (c) 2005-2017 Code Synthesis Tools CC
3 : // license : GNU GPL v2 + exceptions; see accompanying LICENSE file
4 :
5 : #include <string>
6 : #include <sstream>
7 :
8 : #include <xercesc/dom/DOMAttr.hpp>
9 : #include <xercesc/dom/DOMElement.hpp>
10 :
11 : #include <xsd/cxx/xml/string.hxx> // xml::{string, transcode}
12 : #include <xsd/cxx/xml/dom/serialization-header.hxx> // dom::{prefix, clear}
13 :
14 : #include <xsd/cxx/tree/elements.hxx>
15 : #include <xsd/cxx/tree/types.hxx>
16 : #include <xsd/cxx/tree/list.hxx>
17 :
18 : // The only way to make the following serialization operators
19 : // for fundamental types work is to defined them in the xercesc
20 : // namespace so that they can be found by ADL. Placing them into
21 : // the global namespace does not work.
22 : //
23 :
24 : namespace XERCES_CPP_NAMESPACE
25 : {
26 : // Serialization of std::basic_string and C string. Used in other
27 : // serializers. Also used to serialize enumerators.
28 : //
29 : template <typename C>
30 : void
31 : operator<< (xercesc::DOMElement& e, const C* s)
32 : {
33 : xsd::cxx::xml::dom::clear<char> (e);
34 :
35 : if (*s != C (0))
36 : e.setTextContent (xsd::cxx::xml::string (s).c_str ());
37 : }
38 :
39 : template <typename C>
40 : void
41 : operator<< (xercesc::DOMAttr& a, const C* s)
42 : {
43 : a.setValue (xsd::cxx::xml::string (s).c_str ());
44 : }
45 :
46 : // We duplicate the code above instead of delegating in order to
47 : // allow the xml::string type to take advantage of cached string
48 : // sizes.
49 : //
50 : template <typename C>
51 : void
52 0 : operator<< (xercesc::DOMElement& e, const std::basic_string<C>& s)
53 : {
54 0 : xsd::cxx::xml::dom::clear<char> (e);
55 :
56 0 : if (!s.empty ())
57 0 : e.setTextContent (xsd::cxx::xml::string (s).c_str ());
58 0 : }
59 :
60 : template <typename C>
61 : void
62 0 : operator<< (xercesc::DOMAttr& a, const std::basic_string<C>& s)
63 : {
64 0 : a.setValue (xsd::cxx::xml::string (s).c_str ());
65 0 : }
66 : }
67 :
68 : namespace xsd
69 : {
70 : namespace cxx
71 : {
72 : namespace tree
73 : {
74 : // List serialization operators for std::basic_string and C string.
75 : //
76 :
77 : template <typename C>
78 : void
79 : operator<< (list_stream<C>& ls, const C* s)
80 : {
81 : ls.os_ << s;
82 : }
83 :
84 : template <typename C>
85 : void
86 : operator<< (list_stream<C>& ls, const std::basic_string<C>& s)
87 : {
88 : ls.os_ << s;
89 : }
90 :
91 : // Insertion operators for type.
92 : //
93 : inline void
94 0 : operator<< (xercesc::DOMElement& e, const type& x)
95 : {
96 0 : xml::dom::clear<char> (e);
97 :
98 0 : if (!x.null_content () && x.dom_content ().present ())
99 : {
100 : // Cannot use 'using namespace' because of MSXML conflict.
101 : //
102 : using xercesc::DOMAttr;
103 : using xercesc::DOMNode;
104 : using xercesc::DOMElement;
105 : using xercesc::DOMDocument;
106 : using xercesc::DOMNamedNodeMap;
107 :
108 : // Clone the contents of the element.
109 : //
110 0 : DOMDocument& doc (*e.getOwnerDocument ());
111 0 : const DOMElement& se (x.dom_content ().get ());
112 0 : DOMNamedNodeMap& sa (*se.getAttributes ());
113 :
114 0 : for (XMLSize_t i (0), n (sa.getLength ()); i != n; ++i)
115 0 : e.setAttributeNode (
116 0 : static_cast<DOMAttr*> (doc.importNode (sa.item (i), true)));
117 :
118 0 : for (DOMNode* sn (se.getFirstChild ());
119 0 : sn != 0;
120 0 : sn = sn->getNextSibling ())
121 0 : e.appendChild (doc.importNode (sn, true));
122 : }
123 0 : }
124 :
125 : inline void
126 : operator<< (xercesc::DOMAttr&, const type&)
127 : {
128 : }
129 :
130 : template <typename C>
131 : inline void
132 : operator<< (list_stream<C>&, const type&)
133 : {
134 : }
135 :
136 : // Insertion operators for simple_type.
137 : //
138 : template <typename C, typename B>
139 : inline void
140 : operator<< (xercesc::DOMElement& e, const simple_type<C, B>& x)
141 : {
142 : if (x.null_content ())
143 : xml::dom::clear<char> (e);
144 : else
145 : e << x.text_content ();
146 : }
147 :
148 : template <typename C, typename B>
149 : inline void
150 : operator<< (xercesc::DOMAttr& a, const simple_type<C, B>& x)
151 : {
152 : if (!x.null_content ())
153 : a << x.text_content ();
154 : }
155 :
156 : template <typename C, typename B>
157 : inline void
158 : operator<< (list_stream<C>& ls, const simple_type<C, B>& x)
159 : {
160 : if (!x.null_content ())
161 : ls << x.text_content ();
162 : }
163 :
164 : // Insertion operators for list.
165 : //
166 : template <typename C, typename T, schema_type::value ST, bool fund>
167 : void
168 : operator<< (xercesc::DOMElement& e, const list<T, C, ST, fund>& v)
169 : {
170 : std::basic_ostringstream<C> os;
171 : list_stream<C> ls (os, e);
172 :
173 : ls << v;
174 :
175 : e << os.str ();
176 : }
177 :
178 : template <typename C, typename T, schema_type::value ST, bool fund>
179 : void
180 : operator<< (xercesc::DOMAttr& a, const list<T, C, ST, fund>& v)
181 : {
182 : std::basic_ostringstream<C> os;
183 : list_stream<C> ls (os, *a.getOwnerElement ());
184 :
185 : ls << v;
186 :
187 : a << os.str ();
188 : }
189 :
190 : template <typename C, typename T, schema_type::value ST, bool fund>
191 : void
192 : operator<< (list_stream<C>& ls, const list<T, C, ST, fund>& v)
193 : {
194 : for (typename list<T, C, ST, fund>::const_iterator
195 : b (v.begin ()), e (v.end ()), i (b); i != e; ++i)
196 : {
197 : if (i != b)
198 : ls.os_ << C (' ');
199 :
200 : ls << *i;
201 : }
202 : }
203 :
204 : // Specializations for double and decimal.
205 : //
206 : template <typename C, typename T, bool fund>
207 : void
208 : operator<< (list_stream<C>& ls,
209 : const list<T, C, schema_type::double_, fund>& v)
210 : {
211 : for (typename list<T, C, schema_type::double_, fund>::const_iterator
212 : b (v.begin ()), e (v.end ()), i (b); i != e; ++i)
213 : {
214 : if (i != b)
215 : ls.os_ << C (' ');
216 :
217 : ls << as_double<T> (*i);
218 : }
219 : }
220 :
221 : template <typename C, typename T, bool fund>
222 : void
223 : operator<< (list_stream<C>& ls,
224 : const list<T, C, schema_type::decimal, fund>& v)
225 : {
226 : for (typename list<T, C, schema_type::decimal, fund>::const_iterator
227 : b (v.begin ()), e (v.end ()), i (b); i != e; ++i)
228 : {
229 : if (i != b)
230 : ls.os_ << C (' ');
231 :
232 : ls << as_decimal<T> (*i);
233 : }
234 : }
235 :
236 :
237 : // Insertion operators for fundamental_base.
238 : //
239 : template <typename T, typename C, typename B, schema_type::value ST>
240 : void
241 : operator<< (xercesc::DOMElement& e,
242 : const fundamental_base<T, C, B, ST>& x)
243 : {
244 : const T& r (x);
245 : e << r;
246 : }
247 :
248 : template <typename T, typename C, typename B, schema_type::value ST>
249 : void
250 : operator<< (xercesc::DOMAttr& a, const fundamental_base<T, C, B, ST>& x)
251 : {
252 : const T& r (x);
253 : a << r;
254 : }
255 :
256 : template <typename T, typename C, typename B, schema_type::value ST>
257 : void
258 : operator<< (list_stream<C>& ls, const fundamental_base<T, C, B, ST>& x)
259 : {
260 : const T& r (x);
261 : ls << r;
262 : }
263 :
264 : // Specializations for double.
265 : //
266 : template <typename T, typename C, typename B>
267 : void
268 : operator<< (
269 : xercesc::DOMElement& e,
270 : const fundamental_base<T, C, B, schema_type::double_>& x)
271 : {
272 : e << as_double<T> (x);
273 : }
274 :
275 : template <typename T, typename C, typename B>
276 : void
277 : operator<< (
278 : xercesc::DOMAttr& a,
279 : const fundamental_base<T, C, B, schema_type::double_>& x)
280 : {
281 : a << as_double<T> (x);
282 : }
283 :
284 : template <typename T, typename C, typename B>
285 : void
286 : operator<< (
287 : list_stream<C>& ls,
288 : const fundamental_base<T, C, B, schema_type::double_>& x)
289 : {
290 : ls << as_double<T> (x);
291 : }
292 :
293 : // Specializations for decimal.
294 : //
295 : template <typename T, typename C, typename B>
296 : void
297 : operator<< (
298 : xercesc::DOMElement& e,
299 : const fundamental_base<T, C, B, schema_type::decimal>& x)
300 : {
301 : e << as_decimal<T> (x, x._facet_table ());
302 : }
303 :
304 : template <typename T, typename C, typename B>
305 : void
306 : operator<< (
307 : xercesc::DOMAttr& a,
308 : const fundamental_base<T, C, B, schema_type::decimal>& x)
309 : {
310 : a << as_decimal<T> (x, x._facet_table ());
311 : }
312 :
313 : template <typename T, typename C, typename B>
314 : void
315 : operator<< (
316 : list_stream<C>& ls,
317 : const fundamental_base<T, C, B, schema_type::decimal>& x)
318 : {
319 : ls << as_decimal<T> (x, x._facet_table ());
320 : }
321 :
322 : // Insertion operators for built-in types.
323 : //
324 :
325 : namespace bits
326 : {
327 : template <typename C, typename T>
328 : void
329 0 : insert (xercesc::DOMElement& e, const T& x)
330 : {
331 0 : std::basic_ostringstream<C> os;
332 0 : os << x;
333 0 : e << os.str ();
334 0 : }
335 :
336 : template <typename C, typename T>
337 : void
338 0 : insert (xercesc::DOMAttr& a, const T& x)
339 : {
340 0 : std::basic_ostringstream<C> os;
341 0 : os << x;
342 0 : a << os.str ();
343 0 : }
344 : }
345 :
346 :
347 : // string
348 : //
349 : template <typename C, typename B>
350 : inline void
351 0 : operator<< (xercesc::DOMElement& e, const string<C, B>& x)
352 : {
353 0 : bits::insert<C> (e, x);
354 0 : }
355 :
356 : template <typename C, typename B>
357 : inline void
358 0 : operator<< (xercesc::DOMAttr& a, const string<C, B>& x)
359 : {
360 0 : bits::insert<C> (a, x);
361 0 : }
362 :
363 : template <typename C, typename B>
364 : inline void
365 : operator<< (list_stream<C>& ls, const string<C, B>& x)
366 : {
367 : ls.os_ << x;
368 : }
369 :
370 :
371 : // normalized_string
372 : //
373 : template <typename C, typename B>
374 : inline void
375 : operator<< (xercesc::DOMElement& e, const normalized_string<C, B>& x)
376 : {
377 : bits::insert<C> (e, x);
378 : }
379 :
380 : template <typename C, typename B>
381 : inline void
382 : operator<< (xercesc::DOMAttr& a, const normalized_string<C, B>& x)
383 : {
384 : bits::insert<C> (a, x);
385 : }
386 :
387 : template <typename C, typename B>
388 : inline void
389 : operator<< (list_stream<C>& ls, const normalized_string<C, B>& x)
390 : {
391 : ls.os_ << x;
392 : }
393 :
394 :
395 : // token
396 : //
397 : template <typename C, typename B>
398 : inline void
399 : operator<< (xercesc::DOMElement& e, const token<C, B>& x)
400 : {
401 : bits::insert<C> (e, x);
402 : }
403 :
404 : template <typename C, typename B>
405 : inline void
406 : operator<< (xercesc::DOMAttr& a, const token<C, B>& x)
407 : {
408 : bits::insert<C> (a, x);
409 : }
410 :
411 : template <typename C, typename B>
412 : inline void
413 : operator<< (list_stream<C>& ls, const token<C, B>& x)
414 : {
415 : ls.os_ << x;
416 : }
417 :
418 :
419 : // nmtoken
420 : //
421 : template <typename C, typename B>
422 : inline void
423 : operator<< (xercesc::DOMElement& e, const nmtoken<C, B>& x)
424 : {
425 : bits::insert<C> (e, x);
426 : }
427 :
428 : template <typename C, typename B>
429 : inline void
430 : operator<< (xercesc::DOMAttr& a, const nmtoken<C, B>& x)
431 : {
432 : bits::insert<C> (a, x);
433 : }
434 :
435 : template <typename C, typename B>
436 : inline void
437 : operator<< (list_stream<C>& ls, const nmtoken<C, B>& x)
438 : {
439 : ls.os_ << x;
440 : }
441 :
442 :
443 : // nmtokens
444 : //
445 : template <typename C, typename B, typename nmtoken>
446 : inline void
447 : operator<< (xercesc::DOMElement& e, const nmtokens<C, B, nmtoken>& v)
448 : {
449 : const list<nmtoken, C>& r (v);
450 : e << r;
451 : }
452 :
453 : template <typename C, typename B, typename nmtoken>
454 : inline void
455 : operator<< (xercesc::DOMAttr& a, const nmtokens<C, B, nmtoken>& v)
456 : {
457 : const list<nmtoken, C>& r (v);
458 : a << r;
459 : }
460 :
461 : template <typename C, typename B, typename nmtoken>
462 : inline void
463 : operator<< (list_stream<C>& ls, const nmtokens<C, B, nmtoken>& v)
464 : {
465 : const list<nmtoken, C>& r (v);
466 : ls << r;
467 : }
468 :
469 :
470 : // name
471 : //
472 : template <typename C, typename B>
473 : inline void
474 : operator<< (xercesc::DOMElement& e, const name<C, B>& x)
475 : {
476 : bits::insert<C> (e, x);
477 : }
478 :
479 : template <typename C, typename B>
480 : inline void
481 : operator<< (xercesc::DOMAttr& a, const name<C, B>& x)
482 : {
483 : bits::insert<C> (a, x);
484 : }
485 :
486 : template <typename C, typename B>
487 : inline void
488 : operator<< (list_stream<C>& ls, const name<C, B>& x)
489 : {
490 : ls.os_ << x;
491 : }
492 :
493 :
494 : // ncname
495 : //
496 : template <typename C, typename B>
497 : inline void
498 : operator<< (xercesc::DOMElement& e, const ncname<C, B>& x)
499 : {
500 : bits::insert<C> (e, x);
501 : }
502 :
503 : template <typename C, typename B>
504 : inline void
505 : operator<< (xercesc::DOMAttr& a, const ncname<C, B>& x)
506 : {
507 : bits::insert<C> (a, x);
508 : }
509 :
510 : template <typename C, typename B>
511 : inline void
512 : operator<< (list_stream<C>& ls, const ncname<C, B>& x)
513 : {
514 : ls.os_ << x;
515 : }
516 :
517 :
518 : // language
519 : //
520 : template <typename C, typename B>
521 : inline void
522 : operator<< (xercesc::DOMElement& e, const language<C, B>& x)
523 : {
524 : bits::insert<C> (e, x);
525 : }
526 :
527 : template <typename C, typename B>
528 : inline void
529 : operator<< (xercesc::DOMAttr& a, const language<C, B>& x)
530 : {
531 : bits::insert<C> (a, x);
532 : }
533 :
534 : template <typename C, typename B>
535 : inline void
536 : operator<< (list_stream<C>& ls, const language<C, B>& x)
537 : {
538 : ls.os_ << x;
539 : }
540 :
541 :
542 : // id
543 : //
544 : template <typename C, typename B>
545 : inline void
546 : operator<< (xercesc::DOMElement& e, const id<C, B>& x)
547 : {
548 : bits::insert<C> (e, x);
549 : }
550 :
551 : template <typename C, typename B>
552 : inline void
553 : operator<< (xercesc::DOMAttr& a, const id<C, B>& x)
554 : {
555 : bits::insert<C> (a, x);
556 : }
557 :
558 : template <typename C, typename B>
559 : inline void
560 : operator<< (list_stream<C>& ls, const id<C, B>& x)
561 : {
562 : ls.os_ << x;
563 : }
564 :
565 :
566 : // idref
567 : //
568 : template <typename C, typename B, typename T>
569 : inline void
570 : operator<< (xercesc::DOMElement& e, const idref<C, B, T>& x)
571 : {
572 : bits::insert<C> (e, x);
573 : }
574 :
575 : template <typename C, typename B, typename T>
576 : inline void
577 : operator<< (xercesc::DOMAttr& a, const idref<C, B, T>& x)
578 : {
579 : bits::insert<C> (a, x);
580 : }
581 :
582 : template <typename C, typename B, typename T>
583 : inline void
584 : operator<< (list_stream<C>& ls, const idref<C, B, T>& x)
585 : {
586 : ls.os_ << x;
587 : }
588 :
589 :
590 : // idrefs
591 : //
592 : template <typename C, typename B, typename idref>
593 : inline void
594 : operator<< (xercesc::DOMElement& e, const idrefs<C, B, idref>& v)
595 : {
596 : const list<idref, C>& r (v);
597 : e << r;
598 : }
599 :
600 : template <typename C, typename B, typename idref>
601 : inline void
602 : operator<< (xercesc::DOMAttr& a, const idrefs<C, B, idref>& v)
603 : {
604 : const list<idref, C>& r (v);
605 : a << r;
606 : }
607 :
608 : template <typename C, typename B, typename idref>
609 : inline void
610 : operator<< (list_stream<C>& ls, const idrefs<C, B, idref>& v)
611 : {
612 : const list<idref, C>& r (v);
613 : ls << r;
614 : }
615 :
616 :
617 : // uri
618 : //
619 : template <typename C, typename B>
620 : inline void
621 : operator<< (xercesc::DOMElement& e, const uri<C, B>& x)
622 : {
623 : bits::insert<C> (e, x);
624 : }
625 :
626 : template <typename C, typename B>
627 : inline void
628 : operator<< (xercesc::DOMAttr& a, const uri<C, B>& x)
629 : {
630 : bits::insert<C> (a, x);
631 : }
632 :
633 : template <typename C, typename B>
634 : inline void
635 : operator<< (list_stream<C>& ls, const uri<C, B>& x)
636 : {
637 : ls.os_ << x;
638 : }
639 :
640 :
641 : // qname
642 : //
643 : template <typename C, typename B, typename uri, typename ncname>
644 : void
645 : operator<< (xercesc::DOMElement& e, const qname<C, B, uri, ncname>& x)
646 : {
647 : std::basic_ostringstream<C> os;
648 :
649 : if (x.qualified ())
650 : {
651 : // Note: prefix<C> in case uri doesn't derive from basic_string.
652 : //
653 : std::basic_string<C> p (xml::dom::prefix<C> (x.namespace_ (), e));
654 :
655 : if (!p.empty ())
656 : os << p << C (':');
657 : }
658 :
659 : os << x.name ();
660 : e << os.str ();
661 : }
662 :
663 : template <typename C, typename B, typename uri, typename ncname>
664 : void
665 : operator<< (xercesc::DOMAttr& a, const qname<C, B, uri, ncname>& x)
666 : {
667 : std::basic_ostringstream<C> os;
668 :
669 : if (x.qualified ())
670 : {
671 : // Note: prefix<C> in case uri doesn't derive from basic_string.
672 : //
673 : std::basic_string<C> p (
674 : xml::dom::prefix<C> (x.namespace_ (), *a.getOwnerElement ()));
675 :
676 : if (!p.empty ())
677 : os << p << C (':');
678 : }
679 :
680 : os << x.name ();
681 : a << os.str ();
682 : }
683 :
684 : template <typename C, typename B, typename uri, typename ncname>
685 : void
686 : operator<< (list_stream<C>& ls, const qname<C, B, uri, ncname>& x)
687 : {
688 : if (x.qualified ())
689 : {
690 : // Note: prefix<C> in case uri doesn't derive from basic_string.
691 : //
692 : std::basic_string<C> p (
693 : xml::dom::prefix<C> (x.namespace_ (), ls.parent_));
694 :
695 : if (!p.empty ())
696 : ls.os_ << p << C (':');
697 : }
698 :
699 : ls.os_ << x.name ();
700 : }
701 :
702 :
703 : // base64_binary
704 : //
705 : template <typename C, typename B>
706 : inline void
707 0 : operator<< (xercesc::DOMElement& e, const base64_binary<C, B>& x)
708 : {
709 0 : e << x.encode ();
710 0 : }
711 :
712 : template <typename C, typename B>
713 : inline void
714 : operator<< (xercesc::DOMAttr& a, const base64_binary<C, B>& x)
715 : {
716 : a << x.encode ();
717 : }
718 :
719 : template <typename C, typename B>
720 : inline void
721 : operator<< (list_stream<C>& ls, const base64_binary<C, B>& x)
722 : {
723 : ls.os_ << x.encode ();
724 : }
725 :
726 :
727 : // hex_binary
728 : //
729 : template <typename C, typename B>
730 : inline void
731 : operator<< (xercesc::DOMElement& e, const hex_binary<C, B>& x)
732 : {
733 : e << x.encode ();
734 : }
735 :
736 : template <typename C, typename B>
737 : inline void
738 : operator<< (xercesc::DOMAttr& a, const hex_binary<C, B>& x)
739 : {
740 : a << x.encode ();
741 : }
742 :
743 : template <typename C, typename B>
744 : inline void
745 : operator<< (list_stream<C>& ls, const hex_binary<C, B>& x)
746 : {
747 : ls.os_ << x.encode ();
748 : }
749 :
750 :
751 : // entity
752 : //
753 : template <typename C, typename B>
754 : inline void
755 : operator<< (xercesc::DOMElement& e, const entity<C, B>& x)
756 : {
757 : bits::insert<C> (e, x);
758 : }
759 :
760 : template <typename C, typename B>
761 : inline void
762 : operator<< (xercesc::DOMAttr& a, const entity<C, B>& x)
763 : {
764 : bits::insert<C> (a, x);
765 : }
766 :
767 : template <typename C, typename B>
768 : inline void
769 : operator<< (list_stream<C>& ls, const entity<C, B>& x)
770 : {
771 : ls.os_ << x;
772 : }
773 :
774 :
775 : // entities
776 : //
777 : template <typename C, typename B, typename entity>
778 : inline void
779 : operator<< (xercesc::DOMElement& e, const entities<C, B, entity>& v)
780 : {
781 : const list<entity, C>& r (v);
782 : e << r;
783 : }
784 :
785 : template <typename C, typename B, typename entity>
786 : inline void
787 : operator<< (xercesc::DOMAttr& a, const entities<C, B, entity>& v)
788 : {
789 : const list<entity, C>& r (v);
790 : a << r;
791 : }
792 :
793 : template <typename C, typename B, typename entity>
794 : inline void
795 : operator<< (list_stream<C>& ls, const entities<C, B, entity>& v)
796 : {
797 : const list<entity, C>& r (v);
798 : ls << r;
799 : }
800 : }
801 : }
802 : }
|