rapidxml.hpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2006, 2009 Marcin Kalicinski
3 //
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // For more information, see www.boost.org
9 // ----------------------------------------------------------------------------
10 #ifndef BOOST_PROPERTY_TREE_RAPIDXML_HPP_INCLUDED
11 #define BOOST_PROPERTY_TREE_RAPIDXML_HPP_INCLUDED
12 
14 
15 #include <boost/assert.hpp>
16 #include <cstdlib> // For std::size_t
17 #include <new> // For placement new
18 
19 // On MSVC, disable "conditional expression is constant" warning (level 4).
20 // This warning is almost impossible to avoid with certain types of templated code
21 #ifdef _MSC_VER
22  #pragma warning(push)
23  #pragma warning(disable:4127) // Conditional expression is constant
24 #endif
25 
27 // BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR
28 
29 #include <exception> // For std::exception
30 
31 #define BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where)
32 
33 namespace boost { namespace property_tree { namespace detail {namespace rapidxml
34 {
35 
47  class parse_error: public std::exception
48  {
49 
50  public:
51 
53  parse_error(const char *wa, void *we)
54  : m_what(wa)
55  , m_where(we)
56  {
57  }
58 
61  virtual const char *what() const throw()
62  {
63  return m_what;
64  }
65 
69  template<class Ch>
70  Ch *where() const
71  {
72  return reinterpret_cast<Ch *>(m_where);
73  }
74 
75  private:
76 
77  const char *m_what;
78  void *m_where;
79 
80  };
81 }}}}
82 
84 // Pool sizes
85 
86 #ifndef BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE
87  // Size of static memory block of memory_pool.
88  // Define BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.
89  // No dynamic memory allocations are performed by memory_pool until static memory is exhausted.
90  #define BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE (64 * 1024)
91 #endif
92 
93 #ifndef BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE
94  // Size of dynamic memory block of memory_pool.
95  // Define BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.
96  // After the static block is exhausted, dynamic blocks with approximately this size are allocated by memory_pool.
97  #define BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024)
98 #endif
99 
100 #ifndef BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT
101  // Memory allocation alignment.
102  // Define BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer.
103  // All memory allocations for nodes, attributes and strings will be aligned to this value.
104  // This must be a power of 2 and at least 1, otherwise memory_pool will not work.
105  #define BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT sizeof(void *)
106 #endif
107 
108 namespace boost { namespace property_tree { namespace detail {namespace rapidxml
109 {
110  // Forward declarations
111  template<class Ch> class xml_node;
112  template<class Ch> class xml_attribute;
113  template<class Ch> class xml_document;
114 
118  {
127  };
128 
130  // Parsing flags
131 
137  const int parse_no_data_nodes = 0x1;
138 
146  const int parse_no_element_values = 0x2;
147 
154 
161 
167  const int parse_no_utf8 = 0x10;
168 
174  const int parse_declaration_node = 0x20;
175 
181  const int parse_comment_nodes = 0x40;
182 
189  const int parse_doctype_node = 0x80;
190 
196  const int parse_pi_nodes = 0x100;
197 
204  const int parse_validate_closing_tags = 0x200;
205 
212  const int parse_trim_whitespace = 0x400;
213 
221  const int parse_normalize_whitespace = 0x800;
222 
223  // Compound flags
224 
233  const int parse_default = 0;
234 
244 
249 
255 
257  // Internals
258 
260  namespace internal
261  {
262 
263  // Struct that contains lookup tables for the parser
264  // It must be a template to allow correct linking (because it has static data members, which are defined in a header file).
265  template<int Dummy>
266  struct lookup_tables
267  {
268  static const unsigned char lookup_whitespace[256]; // Whitespace table
269  static const unsigned char lookup_node_name[256]; // Node name table
270  static const unsigned char lookup_text[256]; // Text table
271  static const unsigned char lookup_text_pure_no_ws[256]; // Text table
272  static const unsigned char lookup_text_pure_with_ws[256]; // Text table
273  static const unsigned char lookup_attribute_name[256]; // Attribute name table
274  static const unsigned char lookup_attribute_data_1[256]; // Attribute data table with single quote
275  static const unsigned char lookup_attribute_data_1_pure[256]; // Attribute data table with single quote
276  static const unsigned char lookup_attribute_data_2[256]; // Attribute data table with double quotes
277  static const unsigned char lookup_attribute_data_2_pure[256]; // Attribute data table with double quotes
278  static const unsigned char lookup_digits[256]; // Digits
279  static const unsigned char lookup_upcase[256]; // To uppercase conversion table for ASCII characters
280  };
281 
282  // Find length of the string
283  template<class Ch>
284  inline std::size_t measure(const Ch *p)
285  {
286  const Ch *tmp = p;
287  while (*tmp)
288  ++tmp;
289  return tmp - p;
290  }
291 
292  // Compare strings for equality
293  template<class Ch>
294  inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2, std::size_t size2, bool case_sensitive)
295  {
296  if (size1 != size2)
297  return false;
298  if (case_sensitive)
299  {
300  for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
301  if (*p1 != *p2)
302  return false;
303  }
304  else
305  {
306  for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
307  if (lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p1)] != lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p2)])
308  return false;
309  }
310  return true;
311  }
312 
313  template<class Ch>
314  inline size_t get_index(const Ch c)
315  {
316  // If not ASCII char, its semantic is same as plain 'z'.
317  // char could be signed, so first stretch and make unsigned.
318  unsigned n = c;
319  if (n > 127)
320  {
321  return 'z';
322  }
323  return c;
324  }
325  }
327 
329  // Memory pool
330 
365  template<class Ch = char>
367  {
368 
369  public:
370 
372  // Prefixed names to work around weird MSVC lookup bug.
373  typedef void *(boost_ptree_raw_alloc_func)(std::size_t); // Type of user-defined function used to allocate memory
374  typedef void (boost_ptree_raw_free_func)(void *); // Type of user-defined function used to free memory
376 
379  : m_alloc_func(0)
380  , m_free_func(0)
381  {
382  init();
383  }
384 
389  {
390  clear();
391  }
392 
404  const Ch *name = 0, const Ch *value = 0,
405  std::size_t name_size = 0, std::size_t value_size = 0)
406  {
407  void *memory = allocate_aligned(sizeof(xml_node<Ch>));
408  xml_node<Ch> *node = new(memory) xml_node<Ch>(type);
409  if (name)
410  {
411  if (name_size > 0)
412  node->name(name, name_size);
413  else
414  node->name(name);
415  }
416  if (value)
417  {
418  if (value_size > 0)
419  node->value(value, value_size);
420  else
421  node->value(value);
422  }
423  return node;
424  }
425 
435  xml_attribute<Ch> *allocate_attribute(const Ch *name = 0, const Ch *value = 0,
436  std::size_t name_size = 0, std::size_t value_size = 0)
437  {
438  void *memory = allocate_aligned(sizeof(xml_attribute<Ch>));
439  xml_attribute<Ch> *attribute = new(memory) xml_attribute<Ch>;
440  if (name)
441  {
442  if (name_size > 0)
443  attribute->name(name, name_size);
444  else
445  attribute->name(name);
446  }
447  if (value)
448  {
449  if (value_size > 0)
450  attribute->value(value, value_size);
451  else
452  attribute->value(value);
453  }
454  return attribute;
455  }
456 
464  Ch *allocate_string(const Ch *source = 0, std::size_t size = 0)
465  {
466  BOOST_ASSERT(source || size); // Either source or size (or both) must be specified
467  if (size == 0)
468  size = internal::measure(source) + 1;
469  Ch *result = static_cast<Ch *>(allocate_aligned(size * sizeof(Ch)));
470  if (source)
471  for (std::size_t i = 0; i < size; ++i)
472  result[i] = source[i];
473  return result;
474  }
475 
485  xml_node<Ch> *clone_node(const xml_node<Ch> *source, xml_node<Ch> *result = 0)
486  {
487  // Prepare result node
488  if (result)
489  {
490  result->remove_all_attributes();
491  result->remove_all_nodes();
492  result->type(source->type());
493  }
494  else
495  result = allocate_node(source->type());
496 
497  // Clone name and value
498  result->name(source->name(), source->name_size());
499  result->value(source->value(), source->value_size());
500 
501  // Clone child nodes and attributes
502  for (xml_node<Ch> *child = source->first_node(); child; child = child->next_sibling())
503  result->append_node(clone_node(child));
504  for (xml_attribute<Ch> *attr = source->first_attribute(); attr; attr = attr->next_attribute())
505  result->append_attribute(allocate_attribute(attr->name(), attr->value(), attr->name_size(), attr->value_size()));
506 
507  return result;
508  }
509 
513  void clear()
514  {
515  while (m_begin != m_static_memory)
516  {
517  char *previous_begin = reinterpret_cast<header *>(align(m_begin))->previous_begin;
518  if (m_free_func)
520  else
521  delete[] m_begin;
522  m_begin = previous_begin;
523  }
524  init();
525  }
526 
540  void set_allocator(boost_ptree_raw_alloc_func *af, boost_ptree_raw_free_func *ff)
541  {
542  BOOST_ASSERT(m_begin == m_static_memory && m_ptr == align(m_begin)); // Verify that no memory is allocated yet
543  m_alloc_func = af;
544  m_free_func = ff;
545  }
546 
547  private:
548 
549  struct header
550  {
552  };
553 
554  void init()
555  {
557  m_ptr = align(m_begin);
559  }
560 
561  char *align(char *ptr)
562  {
564  return ptr + alignment;
565  }
566 
567  char *allocate_raw(std::size_t size)
568  {
569  // Allocate
570  void *memory;
571  if (m_alloc_func) // Allocate memory using either user-specified allocation function or global operator new[]
572  {
573  memory = m_alloc_func(size);
574  BOOST_ASSERT(memory); // Allocator is not allowed to return 0, on failure it must either throw, stop the program or use longjmp
575  }
576  else
577  {
578  memory = new char[size];
579  }
580  return static_cast<char *>(memory);
581  }
582 
583  void *allocate_aligned(std::size_t size)
584  {
585  // Calculate aligned pointer
586  char *result = align(m_ptr);
587 
588  // If not enough memory left in current pool, allocate a new pool
589  if (result + size > m_end)
590  {
591  // Calculate required pool size (may be bigger than BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE)
592  std::size_t pool_size = BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE;
593  if (pool_size < size)
594  pool_size = size;
595 
596  // Allocate
597  std::size_t alloc_size = sizeof(header) + (2 * BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - 2) + pool_size; // 2 alignments required in worst case: one for header, one for actual allocation
598  char *raw_memory = allocate_raw(alloc_size);
599 
600  // Setup new pool in allocated memory
601  char *pool = align(raw_memory);
602  header *new_header = reinterpret_cast<header *>(pool);
603  new_header->previous_begin = m_begin;
604  m_begin = raw_memory;
605  m_ptr = pool + sizeof(header);
606  m_end = raw_memory + alloc_size;
607 
608  // Calculate aligned pointer again using new pool
609  result = align(m_ptr);
610  }
611 
612  // Update pool and return aligned pointer
613  m_ptr = result + size;
614  return result;
615  }
616 
617  char *m_begin; // Start of raw memory making up current pool
618  char *m_ptr; // First free byte in current pool
619  char *m_end; // One past last available byte in current pool
621  boost_ptree_raw_alloc_func *m_alloc_func; // Allocator function, or 0 if default is to be used
622  boost_ptree_raw_free_func *m_free_func; // Free function, or 0 if default is to be used
623  };
624 
626  // XML base
627 
631  template<class Ch = char>
632  class xml_base
633  {
634 
635  public:
636 
638  // Construction & destruction
639 
640  // Construct a base with empty name, value and parent
642  : m_name(0)
643  , m_value(0)
644  , m_parent(0)
645  {
646  }
647 
649  // Node data access
650 
657  Ch *name() const
658  {
659  return m_name ? m_name : nullstr();
660  }
661 
665  std::size_t name_size() const
666  {
667  return m_name ? m_name_size : 0;
668  }
669 
676  Ch *value() const
677  {
678  return m_value ? m_value : nullstr();
679  }
680 
684  std::size_t value_size() const
685  {
686  return m_value ? m_value_size : 0;
687  }
688 
690  // Node modification
691 
705  void name(const Ch *n, std::size_t size)
706  {
707  m_name = const_cast<Ch *>(n);
708  m_name_size = size;
709  }
710 
714  void name(const Ch *n)
715  {
716  name(n, internal::measure(n));
717  }
718 
735  void value(const Ch *val, std::size_t size)
736  {
737  m_value = const_cast<Ch *>(val);
738  m_value_size = size;
739  }
740 
744  void value(const Ch *val)
745  {
746  this->value(val, internal::measure(val));
747  }
748 
750  // Related nodes access
751 
755  {
756  return m_parent;
757  }
758 
759  protected:
760 
761  // Return empty string
762  static Ch *nullstr()
763  {
764  static Ch zero = Ch('\0');
765  return &zero;
766  }
767 
768  Ch *m_name; // Name of node, or 0 if no name
769  Ch *m_value; // Value of node, or 0 if no value
770  std::size_t m_name_size; // Length of node name, or undefined of no name
771  std::size_t m_value_size; // Length of node value, or undefined if no value
772  xml_node<Ch> *m_parent; // Pointer to parent node, or 0 if none
773 
774  };
775 
781  template<class Ch = char>
782  class xml_attribute: public xml_base<Ch>
783  {
784 
785  friend class xml_node<Ch>;
786 
787  public:
788 
790  // Construction & destruction
791 
795  {
796  }
797 
799  // Related nodes access
800 
804  {
805  if (xml_node<Ch> *node = this->parent())
806  {
807  while (node->parent())
808  node = node->parent();
809  return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0;
810  }
811  else
812  return 0;
813  }
814 
820  xml_attribute<Ch> *previous_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
821  {
822  if (n)
823  {
824  if (nsize == 0)
825  nsize = internal::measure(n);
826  for (xml_attribute<Ch> *attribute = m_prev_attribute; attribute; attribute = attribute->m_prev_attribute)
827  if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive))
828  return attribute;
829  return 0;
830  }
831  else
832  return this->m_parent ? m_prev_attribute : 0;
833  }
834 
840  xml_attribute<Ch> *next_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
841  {
842  if (n)
843  {
844  if (nsize == 0)
845  nsize = internal::measure(n);
846  for (xml_attribute<Ch> *attribute = m_next_attribute; attribute; attribute = attribute->m_next_attribute)
847  if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive))
848  return attribute;
849  return 0;
850  }
851  else
852  return this->m_parent ? m_next_attribute : 0;
853  }
854 
855  private:
856 
857  xml_attribute<Ch> *m_prev_attribute; // Pointer to previous sibling of attribute, or 0 if none; only valid if parent is non-zero
858  xml_attribute<Ch> *m_next_attribute; // Pointer to next sibling of attribute, or 0 if none; only valid if parent is non-zero
859 
860  };
861 
863  // XML node
864 
873  template<class Ch = char>
874  class xml_node: public xml_base<Ch>
875  {
876 
877  public:
878 
880  // Construction & destruction
881 
886  : m_type(t)
887  , m_first_node(0)
888  , m_first_attribute(0)
889  {
890  }
891 
893  // Node data access
894 
897  node_type type() const
898  {
899  return m_type;
900  }
901 
903  // Related nodes access
904 
908  {
909  xml_node<Ch> *node = const_cast<xml_node<Ch> *>(this);
910  while (node->parent())
911  node = node->parent();
912  return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0;
913  }
914 
920  xml_node<Ch> *first_node(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
921  {
922  if (n)
923  {
924  if (nsize == 0)
925  nsize = internal::measure(n);
926  for (xml_node<Ch> *child = m_first_node; child; child = child->next_sibling())
927  if (internal::compare(child->name(), child->name_size(), n, nsize, case_sensitive))
928  return child;
929  return 0;
930  }
931  else
932  return m_first_node;
933  }
934 
942  xml_node<Ch> *last_node(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
943  {
944  BOOST_ASSERT(m_first_node); // Cannot query for last child if node has no children
945  if (n)
946  {
947  if (nsize == 0)
948  nsize = internal::measure(n);
949  for (xml_node<Ch> *child = m_last_node; child; child = child->previous_sibling())
950  if (internal::compare(child->name(), child->name_size(), n, nsize, case_sensitive))
951  return child;
952  return 0;
953  }
954  else
955  return m_last_node;
956  }
957 
965  xml_node<Ch> *previous_sibling(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
966  {
967  BOOST_ASSERT(this->m_parent); // Cannot query for siblings if node has no parent
968  if (n)
969  {
970  if (nsize == 0)
971  nsize = internal::measure(n);
972  for (xml_node<Ch> *sibling = m_prev_sibling; sibling; sibling = sibling->m_prev_sibling)
973  if (internal::compare(sibling->name(), sibling->name_size(), n, nsize, case_sensitive))
974  return sibling;
975  return 0;
976  }
977  else
978  return m_prev_sibling;
979  }
980 
988  xml_node<Ch> *next_sibling(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
989  {
990  BOOST_ASSERT(this->m_parent); // Cannot query for siblings if node has no parent
991  if (n)
992  {
993  if (nsize == 0)
994  nsize = internal::measure(n);
995  for (xml_node<Ch> *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling)
996  if (internal::compare(sibling->name(), sibling->name_size(), n, nsize, case_sensitive))
997  return sibling;
998  return 0;
999  }
1000  else
1001  return m_next_sibling;
1002  }
1003 
1009  xml_attribute<Ch> *first_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
1010  {
1011  if (n)
1012  {
1013  if (nsize == 0)
1014  nsize = internal::measure(n);
1015  for (xml_attribute<Ch> *attribute = m_first_attribute; attribute; attribute = attribute->m_next_attribute)
1016  if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive))
1017  return attribute;
1018  return 0;
1019  }
1020  else
1021  return m_first_attribute;
1022  }
1023 
1029  xml_attribute<Ch> *last_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
1030  {
1031  if (n)
1032  {
1033  if (nsize == 0)
1034  nsize = internal::measure(n);
1035  for (xml_attribute<Ch> *attribute = m_last_attribute; attribute; attribute = attribute->m_prev_attribute)
1036  if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive))
1037  return attribute;
1038  return 0;
1039  }
1040  else
1041  return m_first_attribute ? m_last_attribute : 0;
1042  }
1043 
1045  // Node modification
1046 
1049  void type(node_type t)
1050  {
1051  m_type = t;
1052  }
1053 
1055  // Node manipulation
1056 
1061  {
1062  BOOST_ASSERT(child && !child->parent() && child->type() != node_document);
1063  if (first_node())
1064  {
1065  child->m_next_sibling = m_first_node;
1066  m_first_node->m_prev_sibling = child;
1067  }
1068  else
1069  {
1070  child->m_next_sibling = 0;
1071  m_last_node = child;
1072  }
1073  m_first_node = child;
1074  child->m_parent = this;
1075  child->m_prev_sibling = 0;
1076  }
1077 
1082  {
1083  BOOST_ASSERT(child && !child->parent() && child->type() != node_document);
1084  if (first_node())
1085  {
1086  child->m_prev_sibling = m_last_node;
1087  m_last_node->m_next_sibling = child;
1088  }
1089  else
1090  {
1091  child->m_prev_sibling = 0;
1092  m_first_node = child;
1093  }
1094  m_last_node = child;
1095  child->m_parent = this;
1096  child->m_next_sibling = 0;
1097  }
1098 
1104  {
1105  BOOST_ASSERT(!where || where->parent() == this);
1106  BOOST_ASSERT(child && !child->parent() && child->type() != node_document);
1107  if (where == m_first_node)
1108  prepend_node(child);
1109  else if (where == 0)
1110  append_node(child);
1111  else
1112  {
1113  child->m_prev_sibling = where->m_prev_sibling;
1114  child->m_next_sibling = where;
1115  where->m_prev_sibling->m_next_sibling = child;
1116  where->m_prev_sibling = child;
1117  child->m_parent = this;
1118  }
1119  }
1120 
1125  {
1127  xml_node<Ch> *child = m_first_node;
1128  m_first_node = child->m_next_sibling;
1129  if (child->m_next_sibling)
1130  child->m_next_sibling->m_prev_sibling = 0;
1131  else
1132  m_last_node = 0;
1133  child->m_parent = 0;
1134  }
1135 
1140  {
1142  xml_node<Ch> *child = m_last_node;
1143  if (child->m_prev_sibling)
1144  {
1145  m_last_node = child->m_prev_sibling;
1146  child->m_prev_sibling->m_next_sibling = 0;
1147  }
1148  else
1149  m_first_node = 0;
1150  child->m_parent = 0;
1151  }
1152 
1154  // \param where Pointer to child to be removed.
1156  {
1157  BOOST_ASSERT(where && where->parent() == this);
1159  if (where == m_first_node)
1161  else if (where == m_last_node)
1162  remove_last_node();
1163  else
1164  {
1165  where->m_prev_sibling->m_next_sibling = where->m_next_sibling;
1166  where->m_next_sibling->m_prev_sibling = where->m_prev_sibling;
1167  where->m_parent = 0;
1168  }
1169  }
1170 
1173  {
1174  for (xml_node<Ch> *node = first_node(); node; node = node->m_next_sibling)
1175  node->m_parent = 0;
1176  m_first_node = 0;
1177  }
1178 
1182  {
1183  BOOST_ASSERT(attribute && !attribute->parent());
1184  if (first_attribute())
1185  {
1186  attribute->m_next_attribute = m_first_attribute;
1187  m_first_attribute->m_prev_attribute = attribute;
1188  }
1189  else
1190  {
1191  attribute->m_next_attribute = 0;
1192  m_last_attribute = attribute;
1193  }
1194  m_first_attribute = attribute;
1195  attribute->m_parent = this;
1196  attribute->m_prev_attribute = 0;
1197  }
1198 
1202  {
1203  BOOST_ASSERT(attribute && !attribute->parent());
1204  if (first_attribute())
1205  {
1206  attribute->m_prev_attribute = m_last_attribute;
1207  m_last_attribute->m_next_attribute = attribute;
1208  }
1209  else
1210  {
1211  attribute->m_prev_attribute = 0;
1212  m_first_attribute = attribute;
1213  }
1214  m_last_attribute = attribute;
1215  attribute->m_parent = this;
1216  attribute->m_next_attribute = 0;
1217  }
1218 
1224  {
1225  BOOST_ASSERT(!where || where->parent() == this);
1226  BOOST_ASSERT(attribute && !attribute->parent());
1227  if (where == m_first_attribute)
1228  prepend_attribute(attribute);
1229  else if (where == 0)
1230  append_attribute(attribute);
1231  else
1232  {
1233  attribute->m_prev_attribute = where->m_prev_attribute;
1234  attribute->m_next_attribute = where;
1235  where->m_prev_attribute->m_next_attribute = attribute;
1236  where->m_prev_attribute = attribute;
1237  attribute->m_parent = this;
1238  }
1239  }
1240 
1245  {
1247  xml_attribute<Ch> *attribute = m_first_attribute;
1248  if (attribute->m_next_attribute)
1249  {
1250  attribute->m_next_attribute->m_prev_attribute = 0;
1251  }
1252  else
1253  m_last_attribute = 0;
1254  attribute->m_parent = 0;
1255  m_first_attribute = attribute->m_next_attribute;
1256  }
1257 
1262  {
1264  xml_attribute<Ch> *attribute = m_last_attribute;
1265  if (attribute->m_prev_attribute)
1266  {
1267  attribute->m_prev_attribute->m_next_attribute = 0;
1268  m_last_attribute = attribute->m_prev_attribute;
1269  }
1270  else
1271  m_first_attribute = 0;
1272  attribute->m_parent = 0;
1273  }
1274 
1278  {
1279  BOOST_ASSERT(first_attribute() && where->parent() == this);
1280  if (where == m_first_attribute)
1282  else if (where == m_last_attribute)
1284  else
1285  {
1286  where->m_prev_attribute->m_next_attribute = where->m_next_attribute;
1287  where->m_next_attribute->m_prev_attribute = where->m_prev_attribute;
1288  where->m_parent = 0;
1289  }
1290  }
1291 
1294  {
1295  for (xml_attribute<Ch> *attribute = first_attribute(); attribute; attribute = attribute->m_next_attribute)
1296  attribute->m_parent = 0;
1297  m_first_attribute = 0;
1298  }
1299 
1300  private:
1301 
1303  // Restrictions
1304 
1305  // No copying
1306  xml_node(const xml_node &);
1307  void operator =(const xml_node &);
1308 
1310  // Data members
1311 
1312  // Note that some of the pointers below have UNDEFINED values if certain other pointers are 0.
1313  // This is required for maximum performance, as it allows the parser to omit initialization of
1314  // unneded/redundant values.
1315  //
1316  // The rules are as follows:
1317  // 1. first_node and first_attribute contain valid pointers, or 0 if node has no children/attributes respectively
1318  // 2. last_node and last_attribute are valid only if node has at least one child/attribute respectively, otherwise they contain garbage
1319  // 3. prev_sibling and next_sibling are valid only if node has a parent, otherwise they contain garbage
1320 
1321  node_type m_type; // Type of node; always valid
1322  xml_node<Ch> *m_first_node; // Pointer to first child node, or 0 if none; always valid
1323  xml_node<Ch> *m_last_node; // Pointer to last child node, or 0 if none; this value is only valid if m_first_node is non-zero
1324  xml_attribute<Ch> *m_first_attribute; // Pointer to first attribute of node, or 0 if none; always valid
1325  xml_attribute<Ch> *m_last_attribute; // Pointer to last attribute of node, or 0 if none; this value is only valid if m_first_attribute is non-zero
1326  xml_node<Ch> *m_prev_sibling; // Pointer to previous sibling of node, or 0 if none; this value is only valid if m_parent is non-zero
1327  xml_node<Ch> *m_next_sibling; // Pointer to next sibling of node, or 0 if none; this value is only valid if m_parent is non-zero
1328 
1329  };
1330 
1332  // XML document
1333 
1341  template<class Ch = char>
1342  class xml_document: public xml_node<Ch>, public memory_pool<Ch>
1343  {
1344 
1345  public:
1346 
1350  {
1351  }
1352 
1364  template<int Flags>
1365  void parse(Ch *text)
1366  {
1367  BOOST_ASSERT(text);
1368 
1369  // Remove current contents
1370  this->remove_all_nodes();
1371  this->remove_all_attributes();
1372 
1373  // Parse BOM, if any
1374  parse_bom<Flags>(text);
1375 
1376  // Parse children
1377  while (1)
1378  {
1379  // Skip whitespace before node
1380  skip<whitespace_pred, Flags>(text);
1381  if (*text == 0)
1382  break;
1383 
1384  // Parse and append new child
1385  if (*text == Ch('<'))
1386  {
1387  ++text; // Skip '<'
1388  if (xml_node<Ch> *node = parse_node<Flags>(text))
1389  this->append_node(node);
1390  }
1391  else
1392  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected <", text);
1393  }
1394 
1395  }
1396 
1399  void clear()
1400  {
1401  this->remove_all_nodes();
1402  this->remove_all_attributes();
1404  }
1405 
1406  private:
1407 
1409  // Internal character utility functions
1410 
1411  // Detect whitespace character
1413  {
1414  static unsigned char test(Ch ch)
1415  {
1416  return internal::lookup_tables<0>::lookup_whitespace[internal::get_index(ch)];
1417  }
1418  };
1419 
1420  // Detect node name character
1422  {
1423  static unsigned char test(Ch ch)
1424  {
1425  return internal::lookup_tables<0>::lookup_node_name[internal::get_index(ch)];
1426  }
1427  };
1428 
1429  // Detect attribute name character
1431  {
1432  static unsigned char test(Ch ch)
1433  {
1434  return internal::lookup_tables<0>::lookup_attribute_name[internal::get_index(ch)];
1435  }
1436  };
1437 
1438  // Detect text character (PCDATA)
1439  struct text_pred
1440  {
1441  static unsigned char test(Ch ch)
1442  {
1443  return internal::lookup_tables<0>::lookup_text[internal::get_index(ch)];
1444  }
1445  };
1446 
1447  // Detect text character (PCDATA) that does not require processing
1449  {
1450  static unsigned char test(Ch ch)
1451  {
1452  return internal::lookup_tables<0>::lookup_text_pure_no_ws[internal::get_index(ch)];
1453  }
1454  };
1455 
1456  // Detect text character (PCDATA) that does not require processing
1458  {
1459  static unsigned char test(Ch ch)
1460  {
1461  return internal::lookup_tables<0>::lookup_text_pure_with_ws[internal::get_index(ch)];
1462  }
1463  };
1464 
1465  // Detect attribute value character
1466  template<Ch Quote>
1468  {
1469  static unsigned char test(Ch ch)
1470  {
1471  if (Quote == Ch('\''))
1472  return internal::lookup_tables<0>::lookup_attribute_data_1[internal::get_index(ch)];
1473  if (Quote == Ch('\"'))
1474  return internal::lookup_tables<0>::lookup_attribute_data_2[internal::get_index(ch)];
1475  return 0; // Should never be executed, to avoid warnings on Comeau
1476  }
1477  };
1478 
1479  // Detect attribute value character
1480  template<Ch Quote>
1482  {
1483  static unsigned char test(Ch ch)
1484  {
1485  if (Quote == Ch('\''))
1486  return internal::lookup_tables<0>::lookup_attribute_data_1_pure[internal::get_index(ch)];
1487  if (Quote == Ch('\"'))
1488  return internal::lookup_tables<0>::lookup_attribute_data_2_pure[internal::get_index(ch)];
1489  return 0; // Should never be executed, to avoid warnings on Comeau
1490  }
1491  };
1492 
1493  // Insert coded character, using UTF8 or 8-bit ASCII
1494  template<int Flags>
1495  static void insert_coded_character(Ch *&text, unsigned long code)
1496  {
1497  if (Flags & parse_no_utf8)
1498  {
1499  // Insert 8-bit ASCII character
1500  // Todo: possibly verify that code is less than 256 and use replacement char otherwise?
1501  text[0] = static_cast<unsigned char>(code);
1502  text += 1;
1503  }
1504  else
1505  {
1506  // Insert UTF8 sequence
1507  if (code < 0x80) // 1 byte sequence
1508  {
1509  text[0] = static_cast<unsigned char>(code);
1510  text += 1;
1511  }
1512  else if (code < 0x800) // 2 byte sequence
1513  {
1514  text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1515  text[0] = static_cast<unsigned char>(code | 0xC0);
1516  text += 2;
1517  }
1518  else if (code < 0x10000) // 3 byte sequence
1519  {
1520  text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1521  text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1522  text[0] = static_cast<unsigned char>(code | 0xE0);
1523  text += 3;
1524  }
1525  else if (code < 0x110000) // 4 byte sequence
1526  {
1527  text[3] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1528  text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1529  text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1530  text[0] = static_cast<unsigned char>(code | 0xF0);
1531  text += 4;
1532  }
1533  else // Invalid, only codes up to 0x10FFFF are allowed in Unicode
1534  {
1535  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("invalid numeric character entity", text);
1536  }
1537  }
1538  }
1539 
1540  // Skip characters until predicate evaluates to true
1541  template<class StopPred, int Flags>
1542  static void skip(Ch *&text)
1543  {
1544  Ch *tmp = text;
1545  while (StopPred::test(*tmp))
1546  ++tmp;
1547  text = tmp;
1548  }
1549 
1550  // Skip characters until predicate evaluates to true while doing the following:
1551  // - replacing XML character entity references with proper characters (&apos; &amp; &quot; &lt; &gt; &#...;)
1552  // - condensing whitespace sequences to single space character
1553  template<class StopPred, class StopPredPure, int Flags>
1555  {
1556  // If entity translation, whitespace condense and whitespace trimming is disabled, use plain skip
1557  if (Flags & parse_no_entity_translation &&
1558  !(Flags & parse_normalize_whitespace) &&
1559  !(Flags & parse_trim_whitespace))
1560  {
1561  skip<StopPred, Flags>(text);
1562  return text;
1563  }
1564 
1565  // Use simple skip until first modification is detected
1566  skip<StopPredPure, Flags>(text);
1567 
1568  // Use translation skip
1569  Ch *src = text;
1570  Ch *dest = src;
1571  while (StopPred::test(*src))
1572  {
1573  // If entity translation is enabled
1574  if (!(Flags & parse_no_entity_translation))
1575  {
1576  // Test if replacement is needed
1577  if (src[0] == Ch('&'))
1578  {
1579  switch (src[1])
1580  {
1581 
1582  // &amp; &apos;
1583  case Ch('a'):
1584  if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';'))
1585  {
1586  *dest = Ch('&');
1587  ++dest;
1588  src += 5;
1589  continue;
1590  }
1591  if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s') && src[5] == Ch(';'))
1592  {
1593  *dest = Ch('\'');
1594  ++dest;
1595  src += 6;
1596  continue;
1597  }
1598  break;
1599 
1600  // &quot;
1601  case Ch('q'):
1602  if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t') && src[5] == Ch(';'))
1603  {
1604  *dest = Ch('"');
1605  ++dest;
1606  src += 6;
1607  continue;
1608  }
1609  break;
1610 
1611  // &gt;
1612  case Ch('g'):
1613  if (src[2] == Ch('t') && src[3] == Ch(';'))
1614  {
1615  *dest = Ch('>');
1616  ++dest;
1617  src += 4;
1618  continue;
1619  }
1620  break;
1621 
1622  // &lt;
1623  case Ch('l'):
1624  if (src[2] == Ch('t') && src[3] == Ch(';'))
1625  {
1626  *dest = Ch('<');
1627  ++dest;
1628  src += 4;
1629  continue;
1630  }
1631  break;
1632 
1633  // &#...; - assumes ASCII
1634  case Ch('#'):
1635  if (src[2] == Ch('x'))
1636  {
1637  unsigned long code = 0;
1638  src += 3; // Skip &#x
1639  while (1)
1640  {
1641  unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
1642  if (digit == 0xFF)
1643  break;
1644  code = code * 16 + digit;
1645  ++src;
1646  }
1647  insert_coded_character<Flags>(dest, code); // Put character in output
1648  }
1649  else
1650  {
1651  unsigned long code = 0;
1652  src += 2; // Skip &#
1653  while (1)
1654  {
1655  unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
1656  if (digit == 0xFF)
1657  break;
1658  code = code * 10 + digit;
1659  ++src;
1660  }
1661  insert_coded_character<Flags>(dest, code); // Put character in output
1662  }
1663  if (*src == Ch(';'))
1664  ++src;
1665  else
1666  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ;", src);
1667  continue;
1668 
1669  // Something else
1670  default:
1671  // Ignore, just copy '&' verbatim
1672  break;
1673 
1674  }
1675  }
1676  }
1677 
1678  // If whitespace condensing is enabled
1679  if (Flags & parse_normalize_whitespace)
1680  {
1681  // Test if condensing is needed
1682  if (whitespace_pred::test(*src))
1683  {
1684  *dest = Ch(' '); ++dest; // Put single space in dest
1685  ++src; // Skip first whitespace char
1686  // Skip remaining whitespace chars
1687  while (whitespace_pred::test(*src))
1688  ++src;
1689  continue;
1690  }
1691  }
1692 
1693  // No replacement, only copy character
1694  *dest++ = *src++;
1695 
1696  }
1697 
1698  // Return new end
1699  text = src;
1700  return dest;
1701 
1702  }
1703 
1705  // Internal parsing functions
1706 
1707  // Parse UTF-8 BOM, if any
1708  template<int Flags>
1709  void parse_bom(char *&text)
1710  {
1711  if (static_cast<unsigned char>(text[0]) == 0xEF &&
1712  static_cast<unsigned char>(text[1]) == 0xBB &&
1713  static_cast<unsigned char>(text[2]) == 0xBF)
1714  {
1715  text += 3;
1716  }
1717  }
1718 
1719  // Parse UTF-16/32 BOM, if any
1720  template<int Flags>
1721  void parse_bom(wchar_t *&text)
1722  {
1723  const wchar_t bom = 0xFEFF;
1724  if (text[0] == bom)
1725  {
1726  ++text;
1727  }
1728  }
1729 
1730  // Parse XML declaration (<?xml...)
1731  template<int Flags>
1733  {
1734  // If parsing of declaration is disabled
1735  if (!(Flags & parse_declaration_node))
1736  {
1737  // Skip until end of declaration
1738  while (text[0] != Ch('?') || text[1] != Ch('>'))
1739  {
1740  if (!text[0])
1741  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1742  ++text;
1743  }
1744  text += 2; // Skip '?>'
1745  return 0;
1746  }
1747 
1748  // Create declaration
1749  xml_node<Ch> *declaration = this->allocate_node(node_declaration);
1750 
1751  // Skip whitespace before attributes or ?>
1752  skip<whitespace_pred, Flags>(text);
1753 
1754  // Parse declaration attributes
1755  parse_node_attributes<Flags>(text, declaration);
1756 
1757  // Skip ?>
1758  if (text[0] != Ch('?') || text[1] != Ch('>'))
1759  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ?>", text);
1760  text += 2;
1761 
1762  return declaration;
1763  }
1764 
1765  // Parse XML comment (<!--...)
1766  template<int Flags>
1768  {
1769  // If parsing of comments is disabled
1770  if (!(Flags & parse_comment_nodes))
1771  {
1772  // Skip until end of comment
1773  while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>'))
1774  {
1775  if (!text[0])
1776  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1777  ++text;
1778  }
1779  text += 3; // Skip '-->'
1780  return 0; // Do not produce comment node
1781  }
1782 
1783  // Remember value start
1784  Ch *val = text;
1785 
1786  // Skip until end of comment
1787  while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>'))
1788  {
1789  if (!text[0])
1790  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1791  ++text;
1792  }
1793 
1794  // Create comment node
1795  xml_node<Ch> *comment = this->allocate_node(node_comment);
1796  comment->value(val, text - val);
1797 
1798  // Place zero terminator after comment value
1799  if (!(Flags & parse_no_string_terminators))
1800  *text = Ch('\0');
1801 
1802  text += 3; // Skip '-->'
1803  return comment;
1804  }
1805 
1806  // Parse DOCTYPE
1807  template<int Flags>
1809  {
1810  // Remember value start
1811  Ch *val = text;
1812 
1813  // Skip to >
1814  while (*text != Ch('>'))
1815  {
1816  // Determine character type
1817  switch (*text)
1818  {
1819 
1820  // If '[' encountered, scan for matching ending ']' using naive algorithm with depth
1821  // This works for all W3C test files except for 2 most wicked
1822  case Ch('['):
1823  {
1824  ++text; // Skip '['
1825  int depth = 1;
1826  while (depth > 0)
1827  {
1828  switch (*text)
1829  {
1830  case Ch('['): ++depth; break;
1831  case Ch(']'): --depth; break;
1832  case 0: BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1833  default: break;
1834  }
1835  ++text;
1836  }
1837  break;
1838  }
1839 
1840  // Error on end of text
1841  case Ch('\0'):
1842  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1843 
1844  // Other character, skip it
1845  default:
1846  ++text;
1847 
1848  }
1849  }
1850 
1851  // If DOCTYPE nodes enabled
1852  if (Flags & parse_doctype_node)
1853  {
1854  // Create a new doctype node
1855  xml_node<Ch> *doctype = this->allocate_node(node_doctype);
1856  doctype->value(val, text - val);
1857 
1858  // Place zero terminator after value
1859  if (!(Flags & parse_no_string_terminators))
1860  *text = Ch('\0');
1861 
1862  text += 1; // skip '>'
1863  return doctype;
1864  }
1865  else
1866  {
1867  text += 1; // skip '>'
1868  return 0;
1869  }
1870 
1871  }
1872 
1873  // Parse PI
1874  template<int Flags>
1876  {
1877  // If creation of PI nodes is enabled
1878  if (Flags & parse_pi_nodes)
1879  {
1880  // Create pi node
1881  xml_node<Ch> *pi = this->allocate_node(node_pi);
1882 
1883  // Extract PI target name
1884  Ch *n = text;
1885  skip<node_name_pred, Flags>(text);
1886  if (text == n)
1887  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected PI target", text);
1888  pi->name(n, text - n);
1889 
1890  // Skip whitespace between pi target and pi
1891  skip<whitespace_pred, Flags>(text);
1892 
1893  // Remember start of pi
1894  Ch *val = text;
1895 
1896  // Skip to '?>'
1897  while (text[0] != Ch('?') || text[1] != Ch('>'))
1898  {
1899  if (*text == Ch('\0'))
1900  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1901  ++text;
1902  }
1903 
1904  // Set pi value (verbatim, no entity expansion or whitespace normalization)
1905  pi->value(val, text - val);
1906 
1907  // Place zero terminator after name and value
1908  if (!(Flags & parse_no_string_terminators))
1909  {
1910  pi->name()[pi->name_size()] = Ch('\0');
1911  pi->value()[pi->value_size()] = Ch('\0');
1912  }
1913 
1914  text += 2; // Skip '?>'
1915  return pi;
1916  }
1917  else
1918  {
1919  // Skip to '?>'
1920  while (text[0] != Ch('?') || text[1] != Ch('>'))
1921  {
1922  if (*text == Ch('\0'))
1923  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1924  ++text;
1925  }
1926  text += 2; // Skip '?>'
1927  return 0;
1928  }
1929  }
1930 
1931  // Parse and append data
1932  // Return character that ends data.
1933  // This is necessary because this character might have been overwritten by a terminating 0
1934  template<int Flags>
1935  Ch parse_and_append_data(xml_node<Ch> *node, Ch *&text, Ch *contents_start)
1936  {
1937  // Backup to contents start if whitespace trimming is disabled
1938  if (!(Flags & parse_trim_whitespace))
1939  text = contents_start;
1940 
1941  // Skip until end of data
1942  Ch *val = text, *end;
1943  if (Flags & parse_normalize_whitespace)
1944  end = skip_and_expand_character_refs<text_pred, text_pure_with_ws_pred, Flags>(text);
1945  else
1946  end = skip_and_expand_character_refs<text_pred, text_pure_no_ws_pred, Flags>(text);
1947 
1948  // Trim trailing whitespace if flag is set; leading was already trimmed by whitespace skip after >
1949  if (Flags & parse_trim_whitespace)
1950  {
1951  if (Flags & parse_normalize_whitespace)
1952  {
1953  // Whitespace is already condensed to single space characters by skipping function, so just trim 1 char off the end
1954  if (*(end - 1) == Ch(' '))
1955  --end;
1956  }
1957  else
1958  {
1959  // Backup until non-whitespace character is found
1960  while (whitespace_pred::test(*(end - 1)))
1961  --end;
1962  }
1963  }
1964 
1965  // If characters are still left between end and value (this test is only necessary if normalization is enabled)
1966  // Create new data node
1967  if (!(Flags & parse_no_data_nodes))
1968  {
1969  xml_node<Ch> *data = this->allocate_node(node_data);
1970  data->value(val, end - val);
1971  node->append_node(data);
1972  }
1973 
1974  // Add data to parent node if no data exists yet
1975  if (!(Flags & parse_no_element_values))
1976  if (*node->value() == Ch('\0'))
1977  node->value(val, end - val);
1978 
1979  // Place zero terminator after value
1980  if (!(Flags & parse_no_string_terminators))
1981  {
1982  Ch ch = *text;
1983  *end = Ch('\0');
1984  return ch; // Return character that ends data; this is required because zero terminator overwritten it
1985  }
1986 
1987  // Return character that ends data
1988  return *text;
1989  }
1990 
1991  // Parse CDATA
1992  template<int Flags>
1994  {
1995  // If CDATA is disabled
1996  if (Flags & parse_no_data_nodes)
1997  {
1998  // Skip until end of cdata
1999  while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>'))
2000  {
2001  if (!text[0])
2002  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
2003  ++text;
2004  }
2005  text += 3; // Skip ]]>
2006  return 0; // Do not produce CDATA node
2007  }
2008 
2009  // Skip until end of cdata
2010  Ch *val = text;
2011  while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>'))
2012  {
2013  if (!text[0])
2014  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
2015  ++text;
2016  }
2017 
2018  // Create new cdata node
2019  xml_node<Ch> *cdata = this->allocate_node(node_cdata);
2020  cdata->value(val, text - val);
2021 
2022  // Place zero terminator after value
2023  if (!(Flags & parse_no_string_terminators))
2024  *text = Ch('\0');
2025 
2026  text += 3; // Skip ]]>
2027  return cdata;
2028  }
2029 
2030  // Parse element node
2031  template<int Flags>
2033  {
2034  // Create element node
2035  xml_node<Ch> *element = this->allocate_node(node_element);
2036 
2037  // Extract element name
2038  Ch *n = text;
2039  skip<node_name_pred, Flags>(text);
2040  if (text == n)
2041  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected element name", text);
2042  element->name(n, text - n);
2043 
2044  // Skip whitespace between element name and attributes or >
2045  skip<whitespace_pred, Flags>(text);
2046 
2047  // Parse attributes, if any
2048  parse_node_attributes<Flags>(text, element);
2049 
2050  // Determine ending type
2051  if (*text == Ch('>'))
2052  {
2053  ++text;
2054  parse_node_contents<Flags>(text, element);
2055  }
2056  else if (*text == Ch('/'))
2057  {
2058  ++text;
2059  if (*text != Ch('>'))
2060  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text);
2061  ++text;
2062  }
2063  else
2064  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text);
2065 
2066  // Place zero terminator after name
2067  if (!(Flags & parse_no_string_terminators))
2068  element->name()[element->name_size()] = Ch('\0');
2069 
2070  // Return parsed element
2071  return element;
2072  }
2073 
2074  // Determine node type, and parse it
2075  template<int Flags>
2077  {
2078  // Parse proper node type
2079  switch (text[0])
2080  {
2081 
2082  // <...
2083  default:
2084  // Parse and append element node
2085  return parse_element<Flags>(text);
2086 
2087  // <?...
2088  case Ch('?'):
2089  ++text; // Skip ?
2090  if ((text[0] == Ch('x') || text[0] == Ch('X')) &&
2091  (text[1] == Ch('m') || text[1] == Ch('M')) &&
2092  (text[2] == Ch('l') || text[2] == Ch('L')) &&
2093  whitespace_pred::test(text[3]))
2094  {
2095  // '<?xml ' - xml declaration
2096  text += 4; // Skip 'xml '
2097  return parse_xml_declaration<Flags>(text);
2098  }
2099  else
2100  {
2101  // Parse PI
2102  return parse_pi<Flags>(text);
2103  }
2104 
2105  // <!...
2106  case Ch('!'):
2107 
2108  // Parse proper subset of <! node
2109  switch (text[1])
2110  {
2111 
2112  // <!-
2113  case Ch('-'):
2114  if (text[2] == Ch('-'))
2115  {
2116  // '<!--' - xml comment
2117  text += 3; // Skip '!--'
2118  return parse_comment<Flags>(text);
2119  }
2120  break;
2121 
2122  // <![
2123  case Ch('['):
2124  if (text[2] == Ch('C') && text[3] == Ch('D') && text[4] == Ch('A') &&
2125  text[5] == Ch('T') && text[6] == Ch('A') && text[7] == Ch('['))
2126  {
2127  // '<![CDATA[' - cdata
2128  text += 8; // Skip '![CDATA['
2129  return parse_cdata<Flags>(text);
2130  }
2131  break;
2132 
2133  // <!D
2134  case Ch('D'):
2135  if (text[2] == Ch('O') && text[3] == Ch('C') && text[4] == Ch('T') &&
2136  text[5] == Ch('Y') && text[6] == Ch('P') && text[7] == Ch('E') &&
2137  whitespace_pred::test(text[8]))
2138  {
2139  // '<!DOCTYPE ' - doctype
2140  text += 9; // skip '!DOCTYPE '
2141  return parse_doctype<Flags>(text);
2142  }
2143  break;
2144 
2145  default: break;
2146 
2147  } // switch
2148 
2149  // Attempt to skip other, unrecognized node types starting with <!
2150  ++text; // Skip !
2151  while (*text != Ch('>'))
2152  {
2153  if (*text == 0)
2154  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
2155  ++text;
2156  }
2157  ++text; // Skip '>'
2158  return 0; // No node recognized
2159 
2160  }
2161  }
2162 
2163  // Parse contents of the node - children, data etc.
2164  template<int Flags>
2166  {
2167  // For all children and text
2168  while (1)
2169  {
2170  // Skip whitespace between > and node contents
2171  Ch *contents_start = text; // Store start of node contents before whitespace is skipped
2172  if (Flags & parse_trim_whitespace)
2173  skip<whitespace_pred, Flags>(text);
2174  Ch next_char = *text;
2175 
2176  // After data nodes, instead of continuing the loop, control jumps here.
2177  // This is because zero termination inside parse_and_append_data() function
2178  // would wreak havoc with the above code.
2179  // Also, skipping whitespace after data nodes is unnecessary.
2180  after_data_node:
2181 
2182  // Determine what comes next: node closing, child node, data node, or 0?
2183  switch (next_char)
2184  {
2185 
2186  // Node closing or child node
2187  case Ch('<'):
2188  if (text[1] == Ch('/'))
2189  {
2190  // Node closing
2191  text += 2; // Skip '</'
2192  if (Flags & parse_validate_closing_tags)
2193  {
2194  // Skip and validate closing tag name
2195  Ch *closing_name = text;
2196  skip<node_name_pred, Flags>(text);
2197  if (!internal::compare(node->name(), node->name_size(), closing_name, text - closing_name, true))
2198  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("invalid closing tag name", text);
2199  }
2200  else
2201  {
2202  // No validation, just skip name
2203  skip<node_name_pred, Flags>(text);
2204  }
2205  // Skip remaining whitespace after node name
2206  skip<whitespace_pred, Flags>(text);
2207  if (*text != Ch('>'))
2208  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text);
2209  ++text; // Skip '>'
2210  return; // Node closed, finished parsing contents
2211  }
2212  else
2213  {
2214  // Child node
2215  ++text; // Skip '<'
2216  if (xml_node<Ch> *child = parse_node<Flags>(text))
2217  node->append_node(child);
2218  }
2219  break;
2220 
2221  // End of data - error
2222  case Ch('\0'):
2223  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
2224 
2225  // Data node
2226  default:
2227  next_char = parse_and_append_data<Flags>(node, text, contents_start);
2228  goto after_data_node; // Bypass regular processing after data nodes
2229 
2230  }
2231  }
2232  }
2233 
2234  // Parse XML attributes of the node
2235  template<int Flags>
2237  {
2238  // For all attributes
2239  while (attribute_name_pred::test(*text))
2240  {
2241  // Extract attribute name
2242  Ch *n = text;
2243  ++text; // Skip first character of attribute name
2244  skip<attribute_name_pred, Flags>(text);
2245  if (text == n)
2246  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected attribute name", n);
2247 
2248  // Create new attribute
2249  xml_attribute<Ch> *attribute = this->allocate_attribute();
2250  attribute->name(n, text - n);
2251  node->append_attribute(attribute);
2252 
2253  // Skip whitespace after attribute name
2254  skip<whitespace_pred, Flags>(text);
2255 
2256  // Skip =
2257  if (*text != Ch('='))
2258  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected =", text);
2259  ++text;
2260 
2261  // Add terminating zero after name
2262  if (!(Flags & parse_no_string_terminators))
2263  attribute->name()[attribute->name_size()] = 0;
2264 
2265  // Skip whitespace after =
2266  skip<whitespace_pred, Flags>(text);
2267 
2268  // Skip quote and remember if it was ' or "
2269  Ch quote = *text;
2270  if (quote != Ch('\'') && quote != Ch('"'))
2271  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ' or \"", text);
2272  ++text;
2273 
2274  // Extract attribute value and expand char refs in it
2275  Ch *val = text, *end;
2276  const int AttFlags = Flags & ~parse_normalize_whitespace; // No whitespace normalization in attributes
2277  if (quote == Ch('\''))
2279  else
2281 
2282  // Set attribute value
2283  attribute->value(val, end - val);
2284 
2285  // Make sure that end quote is present
2286  if (*text != quote)
2287  BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ' or \"", text);
2288  ++text; // Skip quote
2289 
2290  // Add terminating zero after value
2291  if (!(Flags & parse_no_string_terminators))
2292  attribute->value()[attribute->value_size()] = 0;
2293 
2294  // Skip whitespace after attribute value
2295  skip<whitespace_pred, Flags>(text);
2296  }
2297  }
2298 
2299  };
2300 
2302  namespace internal
2303  {
2304 
2305  // Whitespace (space \n \r \t)
2306  template<int Dummy>
2307  const unsigned char lookup_tables<Dummy>::lookup_whitespace[256] =
2308  {
2309  // 0 1 2 3 4 5 6 7 8 9 A B C D E F
2310  0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, // 0
2311  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
2312  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2
2313  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3
2314  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4
2315  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
2316  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
2317  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
2318  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
2319  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
2320  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A
2321  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B
2322  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C
2323  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D
2324  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E
2325  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // F
2326  };
2327 
2328  // Node name (anything but space \n \r \t / > ? \0)
2329  template<int Dummy>
2330  const unsigned char lookup_tables<Dummy>::lookup_node_name[256] =
2331  {
2332  // 0 1 2 3 4 5 6 7 8 9 A B C D E F
2333  0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0
2334  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
2335  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2
2336  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, // 3
2337  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
2338  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
2339  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
2340  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
2341  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
2342  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
2343  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
2344  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
2345  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
2346  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
2347  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
2348  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
2349  };
2350 
2351  // Text (i.e. PCDATA) (anything but < \0)
2352  template<int Dummy>
2353  const unsigned char lookup_tables<Dummy>::lookup_text[256] =
2354  {
2355  // 0 1 2 3 4 5 6 7 8 9 A B C D E F
2356  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
2357  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
2358  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
2359  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3
2360  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
2361  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
2362  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
2363  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
2364  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
2365  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
2366  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
2367  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
2368  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
2369  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
2370  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
2371  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
2372  };
2373 
2374  // Text (i.e. PCDATA) that does not require processing when ws normalization is disabled
2375  // (anything but < \0 &)
2376  template<int Dummy>
2377  const unsigned char lookup_tables<Dummy>::lookup_text_pure_no_ws[256] =
2378  {
2379  // 0 1 2 3 4 5 6 7 8 9 A B C D E F
2380  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
2381  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
2382  1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
2383  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3
2384  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
2385  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
2386  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
2387  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
2388  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
2389  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
2390  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
2391  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
2392  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
2393  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
2394  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
2395  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
2396  };
2397 
2398  // Text (i.e. PCDATA) that does not require processing when ws normalizationis is enabled
2399  // (anything but < \0 & space \n \r \t)
2400  template<int Dummy>
2401  const unsigned char lookup_tables<Dummy>::lookup_text_pure_with_ws[256] =
2402  {
2403  // 0 1 2 3 4 5 6 7 8 9 A B C D E F
2404  0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0
2405  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
2406  0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
2407  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3
2408  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
2409  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
2410  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
2411  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
2412  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
2413  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
2414  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
2415  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
2416  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
2417  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
2418  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
2419  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
2420  };
2421 
2422  // Attribute name (anything but space \n \r \t / < > = ? ! \0)
2423  template<int Dummy>
2424  const unsigned char lookup_tables<Dummy>::lookup_attribute_name[256] =
2425  {
2426  // 0 1 2 3 4 5 6 7 8 9 A B C D E F
2427  0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0
2428  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
2429  0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2
2430  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, // 3
2431  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
2432  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
2433  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
2434  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
2435  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
2436  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
2437  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
2438  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
2439  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
2440  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
2441  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
2442  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
2443  };
2444 
2445  // Attribute data with single quote (anything but ' \0)
2446  template<int Dummy>
2447  const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1[256] =
2448  {
2449  // 0 1 2 3 4 5 6 7 8 9 A B C D E F
2450  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
2451  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
2452  1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2
2453  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3
2454  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
2455  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
2456  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
2457  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
2458  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
2459  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
2460  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
2461  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
2462  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
2463  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
2464  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
2465  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
2466  };
2467 
2468  // Attribute data with single quote that does not require processing (anything but ' \0 &)
2469  template<int Dummy>
2470  const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1_pure[256] =
2471  {
2472  // 0 1 2 3 4 5 6 7 8 9 A B C D E F
2473  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
2474  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
2475  1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2
2476  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3
2477  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
2478  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
2479  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
2480  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
2481  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
2482  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
2483  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
2484  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
2485  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
2486  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
2487  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
2488  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
2489  };
2490 
2491  // Attribute data with double quote (anything but " \0)
2492  template<int Dummy>
2493  const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2[256] =
2494  {
2495  // 0 1 2 3 4 5 6 7 8 9 A B C D E F
2496  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
2497  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
2498  1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
2499  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3
2500  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
2501  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
2502  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
2503  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
2504  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
2505  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
2506  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
2507  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
2508  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
2509  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
2510  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
2511  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
2512  };
2513 
2514  // Attribute data with double quote that does not require processing (anything but " \0 &)
2515  template<int Dummy>
2516  const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2_pure[256] =
2517  {
2518  // 0 1 2 3 4 5 6 7 8 9 A B C D E F
2519  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
2520  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
2521  1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
2522  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3
2523  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
2524  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
2525  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
2526  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
2527  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
2528  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
2529  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
2530  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
2531  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
2532  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
2533  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
2534  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
2535  };
2536 
2537  // Digits (dec and hex, 255 denotes end of numeric character reference)
2538  template<int Dummy>
2539  const unsigned char lookup_tables<Dummy>::lookup_digits[256] =
2540  {
2541  // 0 1 2 3 4 5 6 7 8 9 A B C D E F
2542  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 0
2543  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 1
2544  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 2
2545  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,255,255,255,255,255,255, // 3
2546  255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 4
2547  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 5
2548  255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 6
2549  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 7
2550  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 8
2551  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 9
2552  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // A
2553  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // B
2554  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // C
2555  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // D
2556  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // E
2557  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 // F
2558  };
2559 
2560  // Upper case conversion
2561  template<int Dummy>
2562  const unsigned char lookup_tables<Dummy>::lookup_upcase[256] =
2563  {
2564  // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A B C D E F
2565  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0
2566  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1
2567  32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2
2568  48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3
2569  64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4
2570  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5
2571  96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 6
2572  80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123,124,125,126,127, // 7
2573  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 8
2574  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 9
2575  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // A
2576  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // B
2577  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // C
2578  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // D
2579  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // E
2580  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // F
2581  };
2582  }
2584 
2585 }}}}
2586 
2587 // Undefine internal macros
2588 #undef BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR
2589 
2590 // On MSVC, restore warnings state
2591 #ifdef _MSC_VER
2592  #pragma warning(pop)
2593 #endif
2594 
2595 #endif
boost::property_tree::detail::rapidxml::xml_attribute::xml_attribute
xml_attribute()
Definition: rapidxml.hpp:794
boost::property_tree::detail::rapidxml::parse_declaration_node
const int parse_declaration_node
Definition: rapidxml.hpp:174
boost::property_tree::detail::rapidxml::xml_document::parse_node_attributes
void parse_node_attributes(Ch *&text, xml_node< Ch > *node)
Definition: rapidxml.hpp:2236
boost::property_tree::detail::rapidxml::parse_no_utf8
const int parse_no_utf8
Definition: rapidxml.hpp:167
boost::property_tree::detail::rapidxml::xml_node::append_node
void append_node(xml_node< Ch > *child)
Definition: rapidxml.hpp:1081
boost::property_tree::detail::rapidxml::xml_node::prepend_node
void prepend_node(xml_node< Ch > *child)
Definition: rapidxml.hpp:1060
boost::property_tree::detail::rapidxml::xml_node
Definition: rapidxml.hpp:111
boost::property_tree::detail::rapidxml::node_cdata
@ node_cdata
A CDATA node. Name is empty. Value contains data text.
Definition: rapidxml.hpp:122
boost::property_tree::detail::rapidxml::xml_node::operator=
void operator=(const xml_node &)
boost::property_tree::detail::rapidxml::xml_document::text_pred
Definition: rapidxml.hpp:1439
boost::property_tree::detail::rapidxml::memory_pool::m_begin
char * m_begin
Definition: rapidxml.hpp:617
boost::property_tree::detail::rapidxml::xml_node::remove_all_attributes
void remove_all_attributes()
Removes all attributes of node.
Definition: rapidxml.hpp:1293
boost::property_tree::detail::rapidxml::memory_pool::clear
void clear()
Definition: rapidxml.hpp:513
boost::property_tree::detail::rapidxml::xml_document::text_pure_with_ws_pred
Definition: rapidxml.hpp:1457
boost::property_tree::detail::rapidxml::memory_pool::m_end
char * m_end
Definition: rapidxml.hpp:619
boost::property_tree::detail::rapidxml::parse_trim_whitespace
const int parse_trim_whitespace
Definition: rapidxml.hpp:212
boost::property_tree::detail::rapidxml::xml_base::name_size
std::size_t name_size() const
Definition: rapidxml.hpp:665
boost::property_tree::detail::rapidxml::xml_document::attribute_value_pure_pred
Definition: rapidxml.hpp:1481
boost::property_tree::detail::rapidxml::xml_node::first_node
xml_node< Ch > * first_node(const Ch *n=0, std::size_t nsize=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:920
boost::property_tree::detail::rapidxml::memory_pool
Definition: rapidxml.hpp:366
boost::property_tree::detail::rapidxml::parse_no_string_terminators
const int parse_no_string_terminators
Definition: rapidxml.hpp:153
boost::property_tree::detail::rapidxml::memory_pool::m_static_memory
char m_static_memory[BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE]
Definition: rapidxml.hpp:620
boost::property_tree::detail::rapidxml::xml_base::name
Ch * name() const
Definition: rapidxml.hpp:657
boost::property_tree::detail::rapidxml::xml_document::parse_cdata
xml_node< Ch > * parse_cdata(Ch *&text)
Definition: rapidxml.hpp:1993
boost::property_tree::detail::rapidxml::xml_node::m_prev_sibling
xml_node< Ch > * m_prev_sibling
Definition: rapidxml.hpp:1326
boost::property_tree::detail::rapidxml::xml_node::remove_attribute
void remove_attribute(xml_attribute< Ch > *where)
Definition: rapidxml.hpp:1277
BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE
#define BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE
Definition: rapidxml.hpp:90
boost::property_tree::detail::rapidxml::xml_document::parse
void parse(Ch *text)
Definition: rapidxml.hpp:1365
boost::property_tree::detail::rapidxml::memory_pool::header::previous_begin
char * previous_begin
Definition: rapidxml.hpp:551
boost::property_tree::detail::rapidxml::memory_pool::allocate_raw
char * allocate_raw(std::size_t size)
Definition: rapidxml.hpp:567
boost::property_tree::detail::rapidxml::node_declaration
@ node_declaration
A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalon...
Definition: rapidxml.hpp:124
boost::property_tree::detail::rapidxml::parse_error::m_what
const char * m_what
Definition: rapidxml.hpp:77
boost::property_tree::detail::rapidxml::xml_document::attribute_value_pure_pred::test
static unsigned char test(Ch ch)
Definition: rapidxml.hpp:1483
boost::property_tree::detail::rapidxml::xml_document::attribute_name_pred::test
static unsigned char test(Ch ch)
Definition: rapidxml.hpp:1432
boost::property_tree::detail::rapidxml::xml_base::m_name_size
std::size_t m_name_size
Definition: rapidxml.hpp:770
boost::property_tree::detail::rapidxml::xml_document::parse_pi
xml_node< Ch > * parse_pi(Ch *&text)
Definition: rapidxml.hpp:1875
BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT
#define BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT
Definition: rapidxml.hpp:105
boost::property_tree::detail::rapidxml::xml_attribute::m_next_attribute
xml_attribute< Ch > * m_next_attribute
Definition: rapidxml.hpp:858
boost::type
Definition: type.hpp:14
boost::property_tree::detail::rapidxml::xml_document::text_pure_no_ws_pred
Definition: rapidxml.hpp:1448
boost::property_tree::detail::rapidxml::xml_node::m_first_node
xml_node< Ch > * m_first_node
Definition: rapidxml.hpp:1322
boost::property_tree::detail::rapidxml::xml_document::parse_node_contents
void parse_node_contents(Ch *&text, xml_node< Ch > *node)
Definition: rapidxml.hpp:2165
boost::property_tree::detail::rapidxml::xml_base::m_value
Ch * m_value
Definition: rapidxml.hpp:769
boost::property_tree::detail::rapidxml::xml_node::xml_node
xml_node(node_type t)
Definition: rapidxml.hpp:885
boost::property_tree::detail::rapidxml::memory_pool::set_allocator
void set_allocator(boost_ptree_raw_alloc_func *af, boost_ptree_raw_free_func *ff)
Definition: rapidxml.hpp:540
boost::property_tree::detail::rapidxml::xml_node::m_last_node
xml_node< Ch > * m_last_node
Definition: rapidxml.hpp:1323
boost::property_tree::detail::rapidxml::memory_pool::align
char * align(char *ptr)
Definition: rapidxml.hpp:561
boost
BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE.
boost::property_tree::detail::rapidxml::xml_node::type
void type(node_type t)
Definition: rapidxml.hpp:1049
boost::property_tree::detail::rapidxml::node_document
@ node_document
A document node. Name and value are empty.
Definition: rapidxml.hpp:119
boost::property_tree::detail::rapidxml::xml_document::insert_coded_character
static void insert_coded_character(Ch *&text, unsigned long code)
Definition: rapidxml.hpp:1495
boost::property_tree::detail::rapidxml::xml_document::attribute_value_pred
Definition: rapidxml.hpp:1467
boost::property_tree::detail::rapidxml::xml_attribute::document
xml_document< Ch > * document() const
Definition: rapidxml.hpp:803
boost::property_tree::detail::rapidxml::memory_pool::header
Definition: rapidxml.hpp:549
boost::property_tree::detail::rapidxml::xml_document::text_pure_no_ws_pred::test
static unsigned char test(Ch ch)
Definition: rapidxml.hpp:1450
boost::property_tree::detail::rapidxml::node_data
@ node_data
A data node. Name is empty. Value contains data text.
Definition: rapidxml.hpp:121
boost::property_tree::detail::rapidxml::xml_document::clear
void clear()
Definition: rapidxml.hpp:1399
BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE
#define BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE
Definition: rapidxml.hpp:97
boost::property_tree::detail::rapidxml::xml_node::m_first_attribute
xml_attribute< Ch > * m_first_attribute
Definition: rapidxml.hpp:1324
boost::property_tree::detail::rapidxml::parse_error::m_where
void * m_where
Definition: rapidxml.hpp:78
boost::property_tree::detail::rapidxml::xml_document::parse_xml_declaration
xml_node< Ch > * parse_xml_declaration(Ch *&text)
Definition: rapidxml.hpp:1732
data
data
boost::property_tree::detail::rapidxml::memory_pool::m_free_func
boost_ptree_raw_free_func * m_free_func
Definition: rapidxml.hpp:622
boost::property_tree::detail::rapidxml::xml_node::previous_sibling
xml_node< Ch > * previous_sibling(const Ch *n=0, std::size_t nsize=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:965
boost::property_tree::detail::rapidxml::xml_node::insert_attribute
void insert_attribute(xml_attribute< Ch > *where, xml_attribute< Ch > *attribute)
Definition: rapidxml.hpp:1223
boost::property_tree::detail::rapidxml::xml_document::xml_document
xml_document()
Constructs empty XML document.
Definition: rapidxml.hpp:1348
boost::property_tree::detail::rapidxml::parse_comment_nodes
const int parse_comment_nodes
Definition: rapidxml.hpp:181
boost::property_tree::detail::rapidxml::parse_error::what
virtual const char * what() const
Definition: rapidxml.hpp:61
boost::property_tree::detail::rapidxml::xml_node::m_type
node_type m_type
Definition: rapidxml.hpp:1321
boost::property_tree::detail::rapidxml::parse_error::where
Ch * where() const
Definition: rapidxml.hpp:70
boost::property_tree::detail::rapidxml::xml_document::parse_node
xml_node< Ch > * parse_node(Ch *&text)
Definition: rapidxml.hpp:2076
boost::property_tree::detail::rapidxml::xml_document::skip
static void skip(Ch *&text)
Definition: rapidxml.hpp:1542
boost::property_tree::detail::rapidxml::xml_attribute::previous_attribute
xml_attribute< Ch > * previous_attribute(const Ch *n=0, std::size_t nsize=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:820
boost::property_tree::detail::rapidxml::xml_document::attribute_value_pred::test
static unsigned char test(Ch ch)
Definition: rapidxml.hpp:1469
boost::property_tree::detail::rapidxml::parse_non_destructive
const int parse_non_destructive
Definition: rapidxml.hpp:243
boost::property_tree::detail::rapidxml::parse_default
const int parse_default
Definition: rapidxml.hpp:233
boost::property_tree::detail::rapidxml::xml_document::attribute_name_pred
Definition: rapidxml.hpp:1430
boost::property_tree::detail::rapidxml::xml_document::parse_and_append_data
Ch parse_and_append_data(xml_node< Ch > *node, Ch *&text, Ch *contents_start)
Definition: rapidxml.hpp:1935
boost::property_tree::detail::rapidxml::xml_node::document
xml_document< Ch > * document() const
Definition: rapidxml.hpp:907
boost::property_tree::detail::rapidxml::xml_attribute::m_prev_attribute
xml_attribute< Ch > * m_prev_attribute
Definition: rapidxml.hpp:857
boost::foreach_detail_::end
auto_any< BOOST_DEDUCED_TYPENAME foreach_iterator< T, C >::type > end(auto_any_t col, type2type< T, C > *, boost::mpl::true_ *)
Definition: foreach.hpp:700
boost::property_tree::detail::rapidxml::xml_node::remove_last_attribute
void remove_last_attribute()
Definition: rapidxml.hpp:1261
boost::property_tree::detail::rapidxml::xml_base::value
Ch * value() const
Definition: rapidxml.hpp:676
BOOST_ASSERT
#define BOOST_ASSERT(expr)
Definition: assert.hpp:60
boost::property_tree::detail::rapidxml::memory_pool::m_alloc_func
boost_ptree_raw_alloc_func * m_alloc_func
Definition: rapidxml.hpp:621
boost::property_tree::detail::rapidxml::xml_document::node_name_pred
Definition: rapidxml.hpp:1421
boost::property_tree::detail::rapidxml::xml_document
Definition: rapidxml.hpp:113
boost::property_tree::detail::rapidxml::xml_document::text_pred::test
static unsigned char test(Ch ch)
Definition: rapidxml.hpp:1441
boost::property_tree::detail::rapidxml::memory_pool::memory_pool
memory_pool()
Constructs empty pool with default allocator functions.
Definition: rapidxml.hpp:378
boost::property_tree::detail::rapidxml::node_pi
@ node_pi
A PI node. Name contains target. Value contains instructions.
Definition: rapidxml.hpp:126
boost::property_tree::detail::rapidxml::memory_pool::m_ptr
char * m_ptr
Definition: rapidxml.hpp:618
boost::property_tree::detail::rapidxml::parse_error
Definition: rapidxml.hpp:47
boost::property_tree::detail::rapidxml::xml_node::first_attribute
xml_attribute< Ch > * first_attribute(const Ch *n=0, std::size_t nsize=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:1009
boost::property_tree::detail::rapidxml::xml_attribute
Definition: rapidxml.hpp:112
boost::property_tree::detail::rapidxml::xml_node::m_last_attribute
xml_attribute< Ch > * m_last_attribute
Definition: rapidxml.hpp:1325
boost::property_tree::detail::rapidxml::xml_node::remove_all_nodes
void remove_all_nodes()
Removes all child nodes (but not attributes).
Definition: rapidxml.hpp:1172
boost::property_tree::detail::rapidxml::xml_base::name
void name(const Ch *n)
Definition: rapidxml.hpp:714
boost::property_tree::detail::rapidxml::parse_doctype_node
const int parse_doctype_node
Definition: rapidxml.hpp:189
assert.hpp
boost::property_tree::detail::rapidxml::node_doctype
@ node_doctype
A DOCTYPE node. Name is empty. Value contains DOCTYPE text.
Definition: rapidxml.hpp:125
boost::property_tree::detail::rapidxml::parse_normalize_whitespace
const int parse_normalize_whitespace
Definition: rapidxml.hpp:221
boost::property_tree::detail::rapidxml::xml_base::xml_base
xml_base()
Definition: rapidxml.hpp:641
boost::property_tree::detail::rapidxml::xml_node::remove_first_attribute
void remove_first_attribute()
Definition: rapidxml.hpp:1244
boost::property_tree::detail::rapidxml::xml_base::m_name
Ch * m_name
Definition: rapidxml.hpp:768
boost::property_tree::detail::rapidxml::node_type
node_type
Definition: rapidxml.hpp:117
boost::property_tree::detail::rapidxml::memory_pool::allocate_aligned
void * allocate_aligned(std::size_t size)
Definition: rapidxml.hpp:583
boost::property_tree::detail::rapidxml::xml_node::append_attribute
void append_attribute(xml_attribute< Ch > *attribute)
Definition: rapidxml.hpp:1201
boost::property_tree::detail::rapidxml::xml_node::remove_last_node
void remove_last_node()
Definition: rapidxml.hpp:1139
boost::property_tree::detail::rapidxml::memory_pool::allocate_attribute
xml_attribute< Ch > * allocate_attribute(const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0)
Definition: rapidxml.hpp:435
boost::property_tree::detail::rapidxml::xml_document::text_pure_with_ws_pred::test
static unsigned char test(Ch ch)
Definition: rapidxml.hpp:1459
boost::property_tree::detail::rapidxml::xml_node::prepend_attribute
void prepend_attribute(xml_attribute< Ch > *attribute)
Definition: rapidxml.hpp:1181
boost::property_tree::detail::rapidxml::xml_attribute::next_attribute
xml_attribute< Ch > * next_attribute(const Ch *n=0, std::size_t nsize=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:840
boost::property_tree::detail::rapidxml::xml_document::parse_bom
void parse_bom(char *&text)
Definition: rapidxml.hpp:1709
boost::property_tree::detail::rapidxml::xml_document::node_name_pred::test
static unsigned char test(Ch ch)
Definition: rapidxml.hpp:1423
boost::property_tree::detail::rapidxml::parse_no_entity_translation
const int parse_no_entity_translation
Definition: rapidxml.hpp:160
boost::property_tree::detail::rapidxml::node_element
@ node_element
An element node. Name contains element name. Value contains text of first data node.
Definition: rapidxml.hpp:120
boost::iterators::i
D const & i
Definition: iterator_facade.hpp:956
boost::property_tree::detail::rapidxml::memory_pool::allocate_node
xml_node< Ch > * allocate_node(node_type type, const Ch *name=0, const Ch *value=0, std::size_t name_size=0, std::size_t value_size=0)
Definition: rapidxml.hpp:403
boost::property_tree::detail::rapidxml::parse_full
const int parse_full
Definition: rapidxml.hpp:254
Ch
#define Ch(x, y, z)
Definition: SHA256.cpp:47
boost::property_tree::detail::rapidxml::xml_base::value
void value(const Ch *val)
Definition: rapidxml.hpp:744
boost::property_tree::detail::rapidxml::parse_no_element_values
const int parse_no_element_values
Definition: rapidxml.hpp:146
boost::property_tree::detail::rapidxml::parse_no_data_nodes
const int parse_no_data_nodes
Definition: rapidxml.hpp:137
boost::property_tree::detail::rapidxml::xml_base::name
void name(const Ch *n, std::size_t size)
Definition: rapidxml.hpp:705
boost::property_tree::detail::rapidxml::xml_base::value_size
std::size_t value_size() const
Definition: rapidxml.hpp:684
boost::property_tree::detail::rapidxml::xml_document::whitespace_pred::test
static unsigned char test(Ch ch)
Definition: rapidxml.hpp:1414
boost::property_tree::detail::rapidxml::xml_node::next_sibling
xml_node< Ch > * next_sibling(const Ch *n=0, std::size_t nsize=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:988
boost::property_tree::detail::rapidxml::xml_node::remove_node
void remove_node(xml_node< Ch > *where)
Removes specified child from the node.
Definition: rapidxml.hpp:1155
boost::property_tree::detail::rapidxml::xml_node::remove_first_node
void remove_first_node()
Definition: rapidxml.hpp:1124
boost::property_tree::detail::rapidxml::xml_document::parse_doctype
xml_node< Ch > * parse_doctype(Ch *&text)
Definition: rapidxml.hpp:1808
boost::property_tree::detail::rapidxml::memory_pool::init
void init()
Definition: rapidxml.hpp:554
BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR
#define BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR(what, where)
Definition: rapidxml.hpp:31
boost::property_tree::detail::rapidxml::xml_node::last_attribute
xml_attribute< Ch > * last_attribute(const Ch *n=0, std::size_t nsize=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:1029
boost::property_tree::detail::rapidxml::xml_node::last_node
xml_node< Ch > * last_node(const Ch *n=0, std::size_t nsize=0, bool case_sensitive=true) const
Definition: rapidxml.hpp:942
boost::property_tree::detail::rapidxml::memory_pool::allocate_string
Ch * allocate_string(const Ch *source=0, std::size_t size=0)
Definition: rapidxml.hpp:464
compare
bool compare(this_type const &rhs) const
Definition: bind_template.hpp:337
boost::property_tree::detail::rapidxml::xml_base
Definition: rapidxml.hpp:632
boost::property_tree::detail::rapidxml::xml_node::insert_node
void insert_node(xml_node< Ch > *where, xml_node< Ch > *child)
Definition: rapidxml.hpp:1103
boost::property_tree::detail::rapidxml::parse_validate_closing_tags
const int parse_validate_closing_tags
Definition: rapidxml.hpp:204
boost::property_tree::detail::rapidxml::xml_base::parent
xml_node< Ch > * parent() const
Definition: rapidxml.hpp:754
boost::property_tree::detail::rapidxml::memory_pool::~memory_pool
~memory_pool()
Definition: rapidxml.hpp:388
boost::property_tree::detail::rapidxml::parse_fastest
const int parse_fastest
Definition: rapidxml.hpp:248
boost::property_tree::detail::rapidxml::parse_error::parse_error
parse_error(const char *wa, void *we)
Constructs parse error.
Definition: rapidxml.hpp:53
boost::property_tree::detail::rapidxml::xml_base::value
void value(const Ch *val, std::size_t size)
Definition: rapidxml.hpp:735
boost::property_tree::detail::rapidxml::memory_pool::clone_node
xml_node< Ch > * clone_node(const xml_node< Ch > *source, xml_node< Ch > *result=0)
Definition: rapidxml.hpp:485
boost::property_tree::detail::rapidxml::xml_node::type
node_type type() const
Definition: rapidxml.hpp:897
boost::property_tree::detail::rapidxml::node_comment
@ node_comment
A comment node. Name is empty. Value contains comment text.
Definition: rapidxml.hpp:123
boost::property_tree::detail::rapidxml::xml_document::parse_bom
void parse_bom(wchar_t *&text)
Definition: rapidxml.hpp:1721
boost::property_tree::detail::rapidxml::parse_pi_nodes
const int parse_pi_nodes
Definition: rapidxml.hpp:196
boost::property_tree::detail::rapidxml::xml_base::m_value_size
std::size_t m_value_size
Definition: rapidxml.hpp:771
boost::property_tree::detail::rapidxml::xml_base::m_parent
xml_node< Ch > * m_parent
Definition: rapidxml.hpp:772
boost::property_tree::detail::rapidxml::xml_base::nullstr
static Ch * nullstr()
Definition: rapidxml.hpp:762
boost::property_tree::detail::rapidxml::xml_document::parse_comment
xml_node< Ch > * parse_comment(Ch *&text)
Definition: rapidxml.hpp:1767
boost::property_tree::detail::rapidxml::xml_document::skip_and_expand_character_refs
static Ch * skip_and_expand_character_refs(Ch *&text)
Definition: rapidxml.hpp:1554
boost::property_tree::detail::rapidxml::xml_document::parse_element
xml_node< Ch > * parse_element(Ch *&text)
Definition: rapidxml.hpp:2032
boost::property_tree::detail::rapidxml::xml_document::whitespace_pred
Definition: rapidxml.hpp:1412
boost::property_tree::detail::rapidxml::xml_node::m_next_sibling
xml_node< Ch > * m_next_sibling
Definition: rapidxml.hpp:1327


sick_visionary_ros
Author(s): SICK AG TechSupport 3D Snapshot
autogenerated on Thu Feb 8 2024 03:45:49