]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/doc/src/docutils/tools/doxygen_xml2qbk/contrib/rapidxml-1.13/rapidxml_print.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / geometry / doc / src / docutils / tools / doxygen_xml2qbk / contrib / rapidxml-1.13 / rapidxml_print.hpp
1 #ifndef RAPIDXML_PRINT_HPP_INCLUDED
2 #define RAPIDXML_PRINT_HPP_INCLUDED
3
4 // Copyright (C) 2006, 2009 Marcin Kalicinski
5 // Version 1.13
6 // Revision $DateTime: 2009/05/13 01:46:17 $
7 //! \file rapidxml_print.hpp This file contains rapidxml printer implementation
8
9 #include "rapidxml.hpp"
10
11 // Only include streams if not disabled
12 #ifndef RAPIDXML_NO_STREAMS
13 #include <ostream>
14 #include <iterator>
15 #endif
16
17 namespace rapidxml
18 {
19
20 ///////////////////////////////////////////////////////////////////////
21 // Printing flags
22
23 const int print_no_indenting = 0x1; //!< Printer flag instructing the printer to suppress indenting of XML. See print() function.
24
25 ///////////////////////////////////////////////////////////////////////
26 // Internal
27
28 //! \cond internal
29 namespace internal
30 {
31
32 ///////////////////////////////////////////////////////////////////////////
33 // Internal character operations
34
35 // Copy characters from given range to given output iterator
36 template<class OutIt, class Ch>
37 inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out)
38 {
39 while (begin != end)
40 *out++ = *begin++;
41 return out;
42 }
43
44 // Copy characters from given range to given output iterator and expand
45 // characters into references (&lt; &gt; &apos; &quot; &amp;)
46 template<class OutIt, class Ch>
47 inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, OutIt out)
48 {
49 while (begin != end)
50 {
51 if (*begin == noexpand)
52 {
53 *out++ = *begin; // No expansion, copy character
54 }
55 else
56 {
57 switch (*begin)
58 {
59 case Ch('<'):
60 *out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';');
61 break;
62 case Ch('>'):
63 *out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';');
64 break;
65 case Ch('\''):
66 *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); *out++ = Ch(';');
67 break;
68 case Ch('"'):
69 *out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); *out++ = Ch(';');
70 break;
71 case Ch('&'):
72 *out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';');
73 break;
74 default:
75 *out++ = *begin; // No expansion, copy character
76 }
77 }
78 ++begin; // Step to next character
79 }
80 return out;
81 }
82
83 // Fill given output iterator with repetitions of the same character
84 template<class OutIt, class Ch>
85 inline OutIt fill_chars(OutIt out, int n, Ch ch)
86 {
87 for (int i = 0; i < n; ++i)
88 *out++ = ch;
89 return out;
90 }
91
92 // Find character
93 template<class Ch, Ch ch>
94 inline bool find_char(const Ch *begin, const Ch *end)
95 {
96 while (begin != end)
97 if (*begin++ == ch)
98 return true;
99 return false;
100 }
101
102 ///////////////////////////////////////////////////////////////////////////
103 // Internal printing operations
104
105 // Print node
106 template<class OutIt, class Ch>
107 inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
108 {
109 // Print proper node type
110 switch (node->type())
111 {
112
113 // Document
114 case node_document:
115 out = print_children(out, node, flags, indent);
116 break;
117
118 // Element
119 case node_element:
120 out = print_element_node(out, node, flags, indent);
121 break;
122
123 // Data
124 case node_data:
125 out = print_data_node(out, node, flags, indent);
126 break;
127
128 // CDATA
129 case node_cdata:
130 out = print_cdata_node(out, node, flags, indent);
131 break;
132
133 // Declaration
134 case node_declaration:
135 out = print_declaration_node(out, node, flags, indent);
136 break;
137
138 // Comment
139 case node_comment:
140 out = print_comment_node(out, node, flags, indent);
141 break;
142
143 // Doctype
144 case node_doctype:
145 out = print_doctype_node(out, node, flags, indent);
146 break;
147
148 // Pi
149 case node_pi:
150 out = print_pi_node(out, node, flags, indent);
151 break;
152
153 // Unknown
154 default:
155 assert(0);
156 break;
157 }
158
159 // If indenting not disabled, add line break after node
160 if (!(flags & print_no_indenting))
161 *out = Ch('\n'), ++out;
162
163 // Return modified iterator
164 return out;
165 }
166
167 // Print children of the node
168 template<class OutIt, class Ch>
169 inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent)
170 {
171 for (xml_node<Ch> *child = node->first_node(); child; child = child->next_sibling())
172 out = print_node(out, child, flags, indent);
173 return out;
174 }
175
176 // Print attributes of the node
177 template<class OutIt, class Ch>
178 inline OutIt print_attributes(OutIt out, const xml_node<Ch> *node, int flags)
179 {
180 for (xml_attribute<Ch> *attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute())
181 {
182 if (attribute->name() && attribute->value())
183 {
184 // Print attribute name
185 *out = Ch(' '), ++out;
186 out = copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out);
187 *out = Ch('='), ++out;
188 // Print attribute value using appropriate quote type
189 if (find_char<Ch, Ch('"')>(attribute->value(), attribute->value() + attribute->value_size()))
190 {
191 *out = Ch('\''), ++out;
192 out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('"'), out);
193 *out = Ch('\''), ++out;
194 }
195 else
196 {
197 *out = Ch('"'), ++out;
198 out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('\''), out);
199 *out = Ch('"'), ++out;
200 }
201 }
202 }
203 return out;
204 }
205
206 // Print data node
207 template<class OutIt, class Ch>
208 inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
209 {
210 assert(node->type() == node_data);
211 if (!(flags & print_no_indenting))
212 out = fill_chars(out, indent, Ch('\t'));
213 out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
214 return out;
215 }
216
217 // Print data node
218 template<class OutIt, class Ch>
219 inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
220 {
221 assert(node->type() == node_cdata);
222 if (!(flags & print_no_indenting))
223 out = fill_chars(out, indent, Ch('\t'));
224 *out = Ch('<'); ++out;
225 *out = Ch('!'); ++out;
226 *out = Ch('['); ++out;
227 *out = Ch('C'); ++out;
228 *out = Ch('D'); ++out;
229 *out = Ch('A'); ++out;
230 *out = Ch('T'); ++out;
231 *out = Ch('A'); ++out;
232 *out = Ch('['); ++out;
233 out = copy_chars(node->value(), node->value() + node->value_size(), out);
234 *out = Ch(']'); ++out;
235 *out = Ch(']'); ++out;
236 *out = Ch('>'); ++out;
237 return out;
238 }
239
240 // Print element node
241 template<class OutIt, class Ch>
242 inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
243 {
244 assert(node->type() == node_element);
245
246 // Print element name and attributes, if any
247 if (!(flags & print_no_indenting))
248 out = fill_chars(out, indent, Ch('\t'));
249 *out = Ch('<'), ++out;
250 out = copy_chars(node->name(), node->name() + node->name_size(), out);
251 out = print_attributes(out, node, flags);
252
253 // If node is childless
254 if (node->value_size() == 0 && !node->first_node())
255 {
256 // Print childless node tag ending
257 *out = Ch('/'), ++out;
258 *out = Ch('>'), ++out;
259 }
260 else
261 {
262 // Print normal node tag ending
263 *out = Ch('>'), ++out;
264
265 // Test if node contains a single data node only (and no other nodes)
266 xml_node<Ch> *child = node->first_node();
267 if (!child)
268 {
269 // If node has no children, only print its value without indenting
270 out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
271 }
272 else if (child->next_sibling() == 0 && child->type() == node_data)
273 {
274 // If node has a sole data child, only print its value without indenting
275 out = copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out);
276 }
277 else
278 {
279 // Print all children with full indenting
280 if (!(flags & print_no_indenting))
281 *out = Ch('\n'), ++out;
282 out = print_children(out, node, flags, indent + 1);
283 if (!(flags & print_no_indenting))
284 out = fill_chars(out, indent, Ch('\t'));
285 }
286
287 // Print node end
288 *out = Ch('<'), ++out;
289 *out = Ch('/'), ++out;
290 out = copy_chars(node->name(), node->name() + node->name_size(), out);
291 *out = Ch('>'), ++out;
292 }
293 return out;
294 }
295
296 // Print declaration node
297 template<class OutIt, class Ch>
298 inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
299 {
300 // Print declaration start
301 if (!(flags & print_no_indenting))
302 out = fill_chars(out, indent, Ch('\t'));
303 *out = Ch('<'), ++out;
304 *out = Ch('?'), ++out;
305 *out = Ch('x'), ++out;
306 *out = Ch('m'), ++out;
307 *out = Ch('l'), ++out;
308
309 // Print attributes
310 out = print_attributes(out, node, flags);
311
312 // Print declaration end
313 *out = Ch('?'), ++out;
314 *out = Ch('>'), ++out;
315
316 return out;
317 }
318
319 // Print comment node
320 template<class OutIt, class Ch>
321 inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
322 {
323 assert(node->type() == node_comment);
324 if (!(flags & print_no_indenting))
325 out = fill_chars(out, indent, Ch('\t'));
326 *out = Ch('<'), ++out;
327 *out = Ch('!'), ++out;
328 *out = Ch('-'), ++out;
329 *out = Ch('-'), ++out;
330 out = copy_chars(node->value(), node->value() + node->value_size(), out);
331 *out = Ch('-'), ++out;
332 *out = Ch('-'), ++out;
333 *out = Ch('>'), ++out;
334 return out;
335 }
336
337 // Print doctype node
338 template<class OutIt, class Ch>
339 inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
340 {
341 assert(node->type() == node_doctype);
342 if (!(flags & print_no_indenting))
343 out = fill_chars(out, indent, Ch('\t'));
344 *out = Ch('<'), ++out;
345 *out = Ch('!'), ++out;
346 *out = Ch('D'), ++out;
347 *out = Ch('O'), ++out;
348 *out = Ch('C'), ++out;
349 *out = Ch('T'), ++out;
350 *out = Ch('Y'), ++out;
351 *out = Ch('P'), ++out;
352 *out = Ch('E'), ++out;
353 *out = Ch(' '), ++out;
354 out = copy_chars(node->value(), node->value() + node->value_size(), out);
355 *out = Ch('>'), ++out;
356 return out;
357 }
358
359 // Print pi node
360 template<class OutIt, class Ch>
361 inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
362 {
363 assert(node->type() == node_pi);
364 if (!(flags & print_no_indenting))
365 out = fill_chars(out, indent, Ch('\t'));
366 *out = Ch('<'), ++out;
367 *out = Ch('?'), ++out;
368 out = copy_chars(node->name(), node->name() + node->name_size(), out);
369 *out = Ch(' '), ++out;
370 out = copy_chars(node->value(), node->value() + node->value_size(), out);
371 *out = Ch('?'), ++out;
372 *out = Ch('>'), ++out;
373 return out;
374 }
375
376 }
377 //! \endcond
378
379 ///////////////////////////////////////////////////////////////////////////
380 // Printing
381
382 //! Prints XML to given output iterator.
383 //! \param out Output iterator to print to.
384 //! \param node Node to be printed. Pass xml_document to print entire document.
385 //! \param flags Flags controlling how XML is printed.
386 //! \return Output iterator pointing to position immediately after last character of printed text.
387 template<class OutIt, class Ch>
388 inline OutIt print(OutIt out, const xml_node<Ch> &node, int flags = 0)
389 {
390 return internal::print_node(out, &node, flags, 0);
391 }
392
393 #ifndef RAPIDXML_NO_STREAMS
394
395 //! Prints XML to given output stream.
396 //! \param out Output stream to print to.
397 //! \param node Node to be printed. Pass xml_document to print entire document.
398 //! \param flags Flags controlling how XML is printed.
399 //! \return Output stream.
400 template<class Ch>
401 inline std::basic_ostream<Ch> &print(std::basic_ostream<Ch> &out, const xml_node<Ch> &node, int flags = 0)
402 {
403 print(std::ostream_iterator<Ch>(out), node, flags);
404 return out;
405 }
406
407 //! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process.
408 //! \param out Output stream to print to.
409 //! \param node Node to be printed.
410 //! \return Output stream.
411 template<class Ch>
412 inline std::basic_ostream<Ch> &operator <<(std::basic_ostream<Ch> &out, const xml_node<Ch> &node)
413 {
414 return print(out, node);
415 }
416
417 #endif
418
419 }
420
421 #endif