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


livox_ros_driver
Author(s): Livox Dev Team
autogenerated on Mon Mar 15 2021 02:40:46