SimulationCraft
SimulationCraft is a tool to explore combat mechanics in the popular MMO RPG World of Warcraft (tm).
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
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 $
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 
21  // Printing flags
22 
23  const int print_no_indenting = 0x1;
24 
26  // Internal
27 
29  namespace internal
30  {
31 
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 
103  // Internal printing operations
104 
105  // =====================================
106  // fix for clang for this bug in gcc and others: http://sourceforge.net/p/rapidxml/bugs/16/
107 
108  template<class OutIt, class Ch> inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent);
109  template<class OutIt, class Ch> inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
110  template<class OutIt, class Ch> inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
111  template<class OutIt, class Ch> inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
112  template<class OutIt, class Ch> inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
113  template<class OutIt, class Ch> inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
114  template<class OutIt, class Ch> inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
115  template<class OutIt, class Ch> inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent);
116 
117  // =====================================
118 
119  // Print node
120  template<class OutIt, class Ch>
121  inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
122  {
123  // Print proper node type
124  switch (node->type())
125  {
126 
127  // Document
128  case node_document:
129  out = print_children(out, node, flags, indent);
130  break;
131 
132  // Element
133  case node_element:
134  out = print_element_node(out, node, flags, indent);
135  break;
136 
137  // Data
138  case node_data:
139  out = print_data_node(out, node, flags, indent);
140  break;
141 
142  // CDATA
143  case node_cdata:
144  out = print_cdata_node(out, node, flags, indent);
145  break;
146 
147  // Declaration
148  case node_declaration:
149  out = print_declaration_node(out, node, flags, indent);
150  break;
151 
152  // Comment
153  case node_comment:
154  out = print_comment_node(out, node, flags, indent);
155  break;
156 
157  // Doctype
158  case node_doctype:
159  out = print_doctype_node(out, node, flags, indent);
160  break;
161 
162  // Pi
163  case node_pi:
164  out = print_pi_node(out, node, flags, indent);
165  break;
166 
167  // Unknown
168  default:
169  assert(0);
170  break;
171  }
172 
173  // If indenting not disabled, add line break after node
174  if (!(flags & print_no_indenting))
175  *out = Ch('\n'), ++out;
176 
177  // Return modified iterator
178  return out;
179  }
180 
181  // Print children of the node
182  template<class OutIt, class Ch>
183  inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent)
184  {
185  for (xml_node<Ch> *child = node->first_node(); child; child = child->next_sibling())
186  out = print_node(out, child, flags, indent);
187  return out;
188  }
189 
190  // Print attributes of the node
191  template<class OutIt, class Ch>
192  inline OutIt print_attributes(OutIt out, const xml_node<Ch> *node, int /*flags*/)
193  {
194  for (xml_attribute<Ch> *attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute())
195  {
196  if (attribute->name() && attribute->value())
197  {
198  // Print attribute name
199  *out = Ch(' '), ++out;
200  out = copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out);
201  *out = Ch('='), ++out;
202  // Print attribute value using appropriate quote type
203  if (find_char<Ch, Ch('"')>(attribute->value(), attribute->value() + attribute->value_size()))
204  {
205  *out = Ch('\''), ++out;
206  out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('"'), out);
207  *out = Ch('\''), ++out;
208  }
209  else
210  {
211  *out = Ch('"'), ++out;
212  out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('\''), out);
213  *out = Ch('"'), ++out;
214  }
215  }
216  }
217  return out;
218  }
219 
220  // Print data node
221  template<class OutIt, class Ch>
222  inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
223  {
224  assert(node->type() == node_data);
225  if (!(flags & print_no_indenting))
226  out = fill_chars(out, indent, Ch('\t'));
227  out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
228  return out;
229  }
230 
231  // Print data node
232  template<class OutIt, class Ch>
233  inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
234  {
235  assert(node->type() == node_cdata);
236  if (!(flags & print_no_indenting))
237  out = fill_chars(out, indent, Ch('\t'));
238  *out = Ch('<'); ++out;
239  *out = Ch('!'); ++out;
240  *out = Ch('['); ++out;
241  *out = Ch('C'); ++out;
242  *out = Ch('D'); ++out;
243  *out = Ch('A'); ++out;
244  *out = Ch('T'); ++out;
245  *out = Ch('A'); ++out;
246  *out = Ch('['); ++out;
247  out = copy_chars(node->value(), node->value() + node->value_size(), out);
248  *out = Ch(']'); ++out;
249  *out = Ch(']'); ++out;
250  *out = Ch('>'); ++out;
251  return out;
252  }
253 
254  // Print element node
255  template<class OutIt, class Ch>
256  inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
257  {
258  assert(node->type() == node_element);
259 
260  // Print element name and attributes, if any
261  if (!(flags & print_no_indenting))
262  out = fill_chars(out, indent, Ch('\t'));
263  *out = Ch('<'), ++out;
264  out = copy_chars(node->name(), node->name() + node->name_size(), out);
265  out = print_attributes(out, node, flags);
266 
267  // If node is childless
268  if (node->value_size() == 0 && !node->first_node())
269  {
270  // Print childless node tag ending
271  *out = Ch('/'), ++out;
272  *out = Ch('>'), ++out;
273  }
274  else
275  {
276  // Print normal node tag ending
277  *out = Ch('>'), ++out;
278 
279  // Test if node contains a single data node only (and no other nodes)
280  xml_node<Ch> *child = node->first_node();
281  if (!child)
282  {
283  // If node has no children, only print its value without indenting
284  out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
285  }
286  else if (child->next_sibling() == 0 && child->type() == node_data)
287  {
288  // If node has a sole data child, only print its value without indenting
289  out = copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out);
290  }
291  else
292  {
293  // Print all children with full indenting
294  if (!(flags & print_no_indenting))
295  *out = Ch('\n'), ++out;
296  out = print_children(out, node, flags, indent + 1);
297  if (!(flags & print_no_indenting))
298  out = fill_chars(out, indent, Ch('\t'));
299  }
300 
301  // Print node end
302  *out = Ch('<'), ++out;
303  *out = Ch('/'), ++out;
304  out = copy_chars(node->name(), node->name() + node->name_size(), out);
305  *out = Ch('>'), ++out;
306  }
307  return out;
308  }
309 
310  // Print declaration node
311  template<class OutIt, class Ch>
312  inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
313  {
314  // Print declaration start
315  if (!(flags & print_no_indenting))
316  out = fill_chars(out, indent, Ch('\t'));
317  *out = Ch('<'), ++out;
318  *out = Ch('?'), ++out;
319  *out = Ch('x'), ++out;
320  *out = Ch('m'), ++out;
321  *out = Ch('l'), ++out;
322 
323  // Print attributes
324  out = print_attributes(out, node, flags);
325 
326  // Print declaration end
327  *out = Ch('?'), ++out;
328  *out = Ch('>'), ++out;
329 
330  return out;
331  }
332 
333  // Print comment node
334  template<class OutIt, class Ch>
335  inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
336  {
337  assert(node->type() == node_comment);
338  if (!(flags & print_no_indenting))
339  out = fill_chars(out, indent, Ch('\t'));
340  *out = Ch('<'), ++out;
341  *out = Ch('!'), ++out;
342  *out = Ch('-'), ++out;
343  *out = Ch('-'), ++out;
344  out = copy_chars(node->value(), node->value() + node->value_size(), out);
345  *out = Ch('-'), ++out;
346  *out = Ch('-'), ++out;
347  *out = Ch('>'), ++out;
348  return out;
349  }
350 
351  // Print doctype node
352  template<class OutIt, class Ch>
353  inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
354  {
355  assert(node->type() == node_doctype);
356  if (!(flags & print_no_indenting))
357  out = fill_chars(out, indent, Ch('\t'));
358  *out = Ch('<'), ++out;
359  *out = Ch('!'), ++out;
360  *out = Ch('D'), ++out;
361  *out = Ch('O'), ++out;
362  *out = Ch('C'), ++out;
363  *out = Ch('T'), ++out;
364  *out = Ch('Y'), ++out;
365  *out = Ch('P'), ++out;
366  *out = Ch('E'), ++out;
367  *out = Ch(' '), ++out;
368  out = copy_chars(node->value(), node->value() + node->value_size(), out);
369  *out = Ch('>'), ++out;
370  return out;
371  }
372 
373  // Print pi node
374  template<class OutIt, class Ch>
375  inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
376  {
377  assert(node->type() == node_pi);
378  if (!(flags & print_no_indenting))
379  out = fill_chars(out, indent, Ch('\t'));
380  *out = Ch('<'), ++out;
381  *out = Ch('?'), ++out;
382  out = copy_chars(node->name(), node->name() + node->name_size(), out);
383  *out = Ch(' '), ++out;
384  out = copy_chars(node->value(), node->value() + node->value_size(), out);
385  *out = Ch('?'), ++out;
386  *out = Ch('>'), ++out;
387  return out;
388  }
389 
390  }
392 
394  // Printing
395 
401  template<class OutIt, class Ch>
402  inline OutIt print(OutIt out, const xml_node<Ch> &node, int flags = 0)
403  {
404  return internal::print_node(out, &node, flags, 0);
405  }
406 
407 #ifndef RAPIDXML_NO_STREAMS
408 
414  template<class Ch>
415  inline std::basic_ostream<Ch> &print(std::basic_ostream<Ch> &out, const xml_node<Ch> &node, int flags = 0)
416  {
417  print(std::ostream_iterator<Ch>(out), node, flags);
418  return out;
419  }
420 
425  template<class Ch>
426  inline std::basic_ostream<Ch> &operator <<(std::basic_ostream<Ch> &out, const xml_node<Ch> &node)
427  {
428  return print(out, node);
429  }
430 
431 #endif
432 
433 }
434 
435 #endif
Definition: allocators.h:422
Definition: rapidxml.hpp:57