Fixed build issue with SECURED=0 option
[platform/upstream/iotivity.git] / extlibs / rapidxml / rapidxml.hpp
1 #ifndef RAPIDXML_HPP_INCLUDED
2 #define RAPIDXML_HPP_INCLUDED
3
4 // Copyright (C) 2006, 2009 Marcin Kalicinski
5 // Version 1.13
6 // Revision $DateTime: 2009/05/13 01:46:17 $
7 //! \file rapidxml.hpp This file contains rapidxml parser and DOM implementation
8
9 // If standard library is disabled, user must provide implementations of required functions and typedefs
10 #if !defined(RAPIDXML_NO_STDLIB)
11 #include <cstdlib>      // For std::size_t
12 #include <cassert>      // For assert
13 #include <new>          // For placement new
14 #endif
15
16 // On MSVC, disable "conditional expression is constant" warning (level 4).
17 // This warning is almost impossible to avoid with certain types of templated code
18 #ifdef _MSC_VER
19 #pragma warning(push)
20 #pragma warning(disable:4127)   // Conditional expression is constant
21 #endif
22
23 ///////////////////////////////////////////////////////////////////////////
24 // RAPIDXML_PARSE_ERROR
25
26 #if defined(RAPIDXML_NO_EXCEPTIONS)
27
28 #define RAPIDXML_PARSE_ERROR(what, where) { parse_error_handler(what, where); assert(0); }
29
30 namespace rapidxml
31 {
32     //! When exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS,
33     //! this function is called to notify user about the error.
34     //! It must be defined by the user.
35     //! <br><br>
36     //! This function cannot return. If it does, the results are undefined.
37     //! <br><br>
38     //! A very simple definition might look like that:
39     //! <pre>
40     //! void %rapidxml::%parse_error_handler(const char *what, void *where)
41     //! {
42     //!     std::cout << "Parse error: " << what << "\n";
43     //!     std::abort();
44     //! }
45     //! </pre>
46     //! \param what Human readable description of the error.
47     //! \param where Pointer to character data where error was detected.
48     void parse_error_handler(const char *what, void *where);
49 }
50
51 #else
52
53 #include <exception>    // For std::exception
54
55 #define RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where)
56
57 namespace rapidxml
58 {
59
60     //! Parse error exception.
61     //! This exception is thrown by the parser when an error occurs.
62     //! Use what() function to get human-readable error message.
63     //! Use where() function to get a pointer to position within source text where error was detected.
64     //! <br><br>
65     //! If throwing exceptions by the parser is undesirable,
66     //! it can be disabled by defining RAPIDXML_NO_EXCEPTIONS macro before rapidxml.hpp is included.
67     //! This will cause the parser to call rapidxml::parse_error_handler() function instead of throwing an exception.
68     //! This function must be defined by the user.
69     //! <br><br>
70     //! This class derives from <code>std::exception</code> class.
71     class parse_error: public std::exception
72     {
73
74         public:
75
76             //! Constructs parse error
77             parse_error(const char *what, void *where)
78                 : m_what(what)
79                 , m_where(where)
80             {
81             }
82
83             //! Gets human readable description of error.
84             //! \return Pointer to null terminated description of the error.
85             virtual const char *what() const throw()
86             {
87                 return m_what;
88             }
89
90             //! Gets pointer to character data where error happened.
91             //! Ch should be the same as char type of xml_document that produced the error.
92             //! \return Pointer to location within the parsed string where error occured.
93             template<class Ch>
94             Ch *where() const
95             {
96                 return reinterpret_cast<Ch *>(m_where);
97             }
98
99         private:
100
101             const char *m_what;
102             void *m_where;
103
104     };
105 }
106
107 #endif
108
109 ///////////////////////////////////////////////////////////////////////////
110 // Pool sizes
111
112 #ifndef RAPIDXML_STATIC_POOL_SIZE
113 // Size of static memory block of memory_pool.
114 // Define RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.
115 // No dynamic memory allocations are performed by memory_pool until static memory is exhausted.
116 #define RAPIDXML_STATIC_POOL_SIZE (64 * 1024)
117 #endif
118
119 #ifndef RAPIDXML_DYNAMIC_POOL_SIZE
120 // Size of dynamic memory block of memory_pool.
121 // Define RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.
122 // After the static block is exhausted, dynamic blocks with approximately this size are allocated by memory_pool.
123 #define RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024)
124 #endif
125
126 #ifndef RAPIDXML_ALIGNMENT
127 // Memory allocation alignment.
128 // Define RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer.
129 // All memory allocations for nodes, attributes and strings will be aligned to this value.
130 // This must be a power of 2 and at least 1, otherwise memory_pool will not work.
131 #define RAPIDXML_ALIGNMENT sizeof(void *)
132 #endif
133
134 namespace rapidxml
135 {
136     // Forward declarations
137     template<class Ch> class xml_node;
138     template<class Ch> class xml_attribute;
139     template<class Ch> class xml_document;
140
141     //! Enumeration listing all node types produced by the parser.
142     //! Use xml_node::type() function to query node type.
143     enum node_type
144     {
145         node_document,      //!< A document node. Name and value are empty.
146         node_element,       //!< An element node. Name contains element name. Value contains text of first data node.
147         node_data,          //!< A data node. Name is empty. Value contains data text.
148         node_cdata,         //!< A CDATA node. Name is empty. Value contains data text.
149         node_comment,       //!< A comment node. Name is empty. Value contains comment text.
150         node_declaration,   //!< A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalone) are in node attributes.
151         node_doctype,       //!< A DOCTYPE node. Name is empty. Value contains DOCTYPE text.
152         node_pi             //!< A PI node. Name contains target. Value contains instructions.
153     };
154
155     ///////////////////////////////////////////////////////////////////////
156     // Parsing flags
157
158     //! Parse flag instructing the parser to not create data nodes.
159     //! Text of first data node will still be placed in value of parent element, unless rapidxml::parse_no_element_values flag is also specified.
160     //! Can be combined with other flags by use of | operator.
161     //! <br><br>
162     //! See xml_document::parse() function.
163     const int parse_no_data_nodes = 0x1;
164
165     //! Parse flag instructing the parser to not use text of first data node as a value of parent element.
166     //! Can be combined with other flags by use of | operator.
167     //! Note that child data nodes of element node take precendence over its value when printing.
168     //! That is, if element has one or more child data nodes <em>and</em> a value, the value will be ignored.
169     //! Use rapidxml::parse_no_data_nodes flag to prevent creation of data nodes if you want to manipulate data using values of elements.
170     //! <br><br>
171     //! See xml_document::parse() function.
172     const int parse_no_element_values = 0x2;
173
174     //! Parse flag instructing the parser to not place zero terminators after strings in the source text.
175     //! By default zero terminators are placed, modifying source text.
176     //! Can be combined with other flags by use of | operator.
177     //! <br><br>
178     //! See xml_document::parse() function.
179     const int parse_no_string_terminators = 0x4;
180
181     //! Parse flag instructing the parser to not translate entities in the source text.
182     //! By default entities are translated, modifying source text.
183     //! Can be combined with other flags by use of | operator.
184     //! <br><br>
185     //! See xml_document::parse() function.
186     const int parse_no_entity_translation = 0x8;
187
188     //! Parse flag instructing the parser to disable UTF-8 handling and assume plain 8 bit characters.
189     //! By default, UTF-8 handling is enabled.
190     //! Can be combined with other flags by use of | operator.
191     //! <br><br>
192     //! See xml_document::parse() function.
193     const int parse_no_utf8 = 0x10;
194
195     //! Parse flag instructing the parser to create XML declaration node.
196     //! By default, declaration node is not created.
197     //! Can be combined with other flags by use of | operator.
198     //! <br><br>
199     //! See xml_document::parse() function.
200     const int parse_declaration_node = 0x20;
201
202     //! Parse flag instructing the parser to create comments nodes.
203     //! By default, comment nodes are not created.
204     //! Can be combined with other flags by use of | operator.
205     //! <br><br>
206     //! See xml_document::parse() function.
207     const int parse_comment_nodes = 0x40;
208
209     //! Parse flag instructing the parser to create DOCTYPE node.
210     //! By default, doctype node is not created.
211     //! Although W3C specification allows at most one DOCTYPE node, RapidXml will silently accept documents with more than one.
212     //! Can be combined with other flags by use of | operator.
213     //! <br><br>
214     //! See xml_document::parse() function.
215     const int parse_doctype_node = 0x80;
216
217     //! Parse flag instructing the parser to create PI nodes.
218     //! By default, PI nodes are not created.
219     //! Can be combined with other flags by use of | operator.
220     //! <br><br>
221     //! See xml_document::parse() function.
222     const int parse_pi_nodes = 0x100;
223
224     //! Parse flag instructing the parser to validate closing tag names.
225     //! If not set, name inside closing tag is irrelevant to the parser.
226     //! By default, closing tags are not validated.
227     //! Can be combined with other flags by use of | operator.
228     //! <br><br>
229     //! See xml_document::parse() function.
230     const int parse_validate_closing_tags = 0x200;
231
232     //! Parse flag instructing the parser to trim all leading and trailing whitespace of data nodes.
233     //! By default, whitespace is not trimmed.
234     //! This flag does not cause the parser to modify source text.
235     //! Can be combined with other flags by use of | operator.
236     //! <br><br>
237     //! See xml_document::parse() function.
238     const int parse_trim_whitespace = 0x400;
239
240     //! Parse flag instructing the parser to condense all whitespace runs of data nodes to a single space character.
241     //! Trimming of leading and trailing whitespace of data is controlled by rapidxml::parse_trim_whitespace flag.
242     //! By default, whitespace is not normalized.
243     //! If this flag is specified, source text will be modified.
244     //! Can be combined with other flags by use of | operator.
245     //! <br><br>
246     //! See xml_document::parse() function.
247     const int parse_normalize_whitespace = 0x800;
248
249     // Compound flags
250
251     //! Parse flags which represent default behaviour of the parser.
252     //! This is always equal to 0, so that all other flags can be simply ored together.
253     //! Normally there is no need to inconveniently disable flags by anding with their negated (~) values.
254     //! This also means that meaning of each flag is a <i>negation</i> of the default setting.
255     //! For example, if flag name is rapidxml::parse_no_utf8, it means that utf-8 is <i>enabled</i> by default,
256     //! and using the flag will disable it.
257     //! <br><br>
258     //! See xml_document::parse() function.
259     const int parse_default = 0;
260
261     //! A combination of parse flags that forbids any modifications of the source text.
262     //! This also results in faster parsing. However, note that the following will occur:
263     //! <ul>
264     //! <li>names and values of nodes will not be zero terminated, you have to use xml_base::name_size() and xml_base::value_size() functions to determine where name and value ends</li>
265     //! <li>entities will not be translated</li>
266     //! <li>whitespace will not be normalized</li>
267     //! </ul>
268     //! See xml_document::parse() function.
269     const int parse_non_destructive = parse_no_string_terminators | parse_no_entity_translation;
270
271     //! A combination of parse flags resulting in fastest possible parsing, without sacrificing important data.
272     //! <br><br>
273     //! See xml_document::parse() function.
274     const int parse_fastest = parse_non_destructive | parse_no_data_nodes;
275
276     //! A combination of parse flags resulting in largest amount of data being extracted.
277     //! This usually results in slowest parsing.
278     //! <br><br>
279     //! See xml_document::parse() function.
280     const int parse_full = parse_declaration_node | parse_comment_nodes | parse_doctype_node |
281                            parse_pi_nodes | parse_validate_closing_tags;
282
283     ///////////////////////////////////////////////////////////////////////
284     // Internals
285
286     //! \cond internal
287     namespace internal
288     {
289
290         // Struct that contains lookup tables for the parser
291         // It must be a template to allow correct linking (because it has static data members, which are defined in a header file).
292         template<int Dummy>
293         struct lookup_tables
294         {
295             static const unsigned char lookup_whitespace[256];              // Whitespace table
296             static const unsigned char lookup_node_name[256];               // Node name table
297             static const unsigned char lookup_text[256];                    // Text table
298             static const unsigned char lookup_text_pure_no_ws[256];         // Text table
299             static const unsigned char lookup_text_pure_with_ws[256];       // Text table
300             static const unsigned char lookup_attribute_name[256];          // Attribute name table
301             static const unsigned char
302             lookup_attribute_data_1[256];        // Attribute data table with single quote
303             static const unsigned char
304             lookup_attribute_data_1_pure[256];   // Attribute data table with single quote
305             static const unsigned char
306             lookup_attribute_data_2[256];        // Attribute data table with double quotes
307             static const unsigned char
308             lookup_attribute_data_2_pure[256];   // Attribute data table with double quotes
309             static const unsigned char lookup_digits[256];                  // Digits
310             static const unsigned char
311             lookup_upcase[256];                  // To uppercase conversion table for ASCII characters
312         };
313
314         // Find length of the string
315         template<class Ch>
316         inline std::size_t measure(const Ch *p)
317         {
318             const Ch *tmp = p;
319             while (*tmp)
320                 ++tmp;
321             return tmp - p;
322         }
323
324         // Compare strings for equality
325         template<class Ch>
326         inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2, std::size_t size2,
327                             bool case_sensitive)
328         {
329             if (size1 != size2)
330                 return false;
331             if (case_sensitive)
332             {
333                 for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
334                     if (*p1 != *p2)
335                         return false;
336             }
337             else
338             {
339                 for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
340                     if (lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p1)] !=
341                         lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p2)])
342                         return false;
343             }
344             return true;
345         }
346     }
347     //! \endcond
348
349     ///////////////////////////////////////////////////////////////////////
350     // Memory pool
351
352     //! This class is used by the parser to create new nodes and attributes, without overheads of dynamic memory allocation.
353     //! In most cases, you will not need to use this class directly.
354     //! However, if you need to create nodes manually or modify names/values of nodes,
355     //! you are encouraged to use memory_pool of relevant xml_document to allocate the memory.
356     //! Not only is this faster than allocating them by using <code>new</code> operator,
357     //! but also their lifetime will be tied to the lifetime of document,
358     //! possibly simplyfing memory management.
359     //! <br><br>
360     //! Call allocate_node() or allocate_attribute() functions to obtain new nodes or attributes from the pool.
361     //! You can also call allocate_string() function to allocate strings.
362     //! Such strings can then be used as names or values of nodes without worrying about their lifetime.
363     //! Note that there is no <code>free()</code> function -- all allocations are freed at once when clear() function is called,
364     //! or when the pool is destroyed.
365     //! <br><br>
366     //! It is also possible to create a standalone memory_pool, and use it
367     //! to allocate nodes, whose lifetime will not be tied to any document.
368     //! <br><br>
369     //! Pool maintains <code>RAPIDXML_STATIC_POOL_SIZE</code> bytes of statically allocated memory.
370     //! Until static memory is exhausted, no dynamic memory allocations are done.
371     //! When static memory is exhausted, pool allocates additional blocks of memory of size <code>RAPIDXML_DYNAMIC_POOL_SIZE</code> each,
372     //! by using global <code>new[]</code> and <code>delete[]</code> operators.
373     //! This behaviour can be changed by setting custom allocation routines.
374     //! Use set_allocator() function to set them.
375     //! <br><br>
376     //! Allocations for nodes, attributes and strings are aligned at <code>RAPIDXML_ALIGNMENT</code> bytes.
377     //! This value defaults to the size of pointer on target architecture.
378     //! <br><br>
379     //! To obtain absolutely top performance from the parser,
380     //! it is important that all nodes are allocated from a single, contiguous block of memory.
381     //! Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably.
382     //! If required, you can tweak <code>RAPIDXML_STATIC_POOL_SIZE</code>, <code>RAPIDXML_DYNAMIC_POOL_SIZE</code> and <code>RAPIDXML_ALIGNMENT</code>
383     //! to obtain best wasted memory to performance compromise.
384     //! To do it, define their values before rapidxml.hpp file is included.
385     //! \param Ch Character type of created nodes.
386     template<class Ch = char>
387     class memory_pool
388     {
389
390         public:
391
392             //! \cond internal
393             typedef void *(alloc_func)(
394                 std::size_t);       // Type of user-defined function used to allocate memory
395             typedef void (free_func)(void *);              // Type of user-defined function used to free memory
396             //! \endcond
397
398             //! Constructs empty pool with default allocator functions.
399             memory_pool()
400                 : m_alloc_func(0)
401                 , m_free_func(0)
402             {
403                 init();
404             }
405
406             //! Destroys pool and frees all the memory.
407             //! This causes memory occupied by nodes allocated by the pool to be freed.
408             //! Nodes allocated from the pool are no longer valid.
409             ~memory_pool()
410             {
411                 clear();
412             }
413
414             //! Allocates a new node from the pool, and optionally assigns name and value to it.
415             //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
416             //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
417             //! will call rapidxml::parse_error_handler() function.
418             //! \param type Type of node to create.
419             //! \param name Name to assign to the node, or 0 to assign no name.
420             //! \param value Value to assign to the node, or 0 to assign no value.
421             //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string.
422             //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string.
423             //! \return Pointer to allocated node. This pointer will never be NULL.
424             xml_node<Ch> *allocate_node(node_type type,
425                                         const Ch *name = 0, const Ch *value = 0,
426                                         std::size_t name_size = 0, std::size_t value_size = 0)
427             {
428                 void *memory = allocate_aligned(sizeof(xml_node<Ch>));
429                 xml_node<Ch> *node = new(memory) xml_node<Ch>(type);
430                 if (name)
431                 {
432                     if (name_size > 0)
433                         node->name(name, name_size);
434                     else
435                         node->name(name);
436                 }
437                 if (value)
438                 {
439                     if (value_size > 0)
440                         node->value(value, value_size);
441                     else
442                         node->value(value);
443                 }
444                 return node;
445             }
446
447             //! Allocates a new attribute from the pool, and optionally assigns name and value to it.
448             //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
449             //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
450             //! will call rapidxml::parse_error_handler() function.
451             //! \param name Name to assign to the attribute, or 0 to assign no name.
452             //! \param value Value to assign to the attribute, or 0 to assign no value.
453             //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string.
454             //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string.
455             //! \return Pointer to allocated attribute. This pointer will never be NULL.
456             xml_attribute<Ch> *allocate_attribute(const Ch *name = 0, const Ch *value = 0,
457                                                   std::size_t name_size = 0, std::size_t value_size = 0)
458             {
459                 void *memory = allocate_aligned(sizeof(xml_attribute<Ch>));
460                 xml_attribute<Ch> *attribute = new(memory) xml_attribute<Ch>;
461                 if (name)
462                 {
463                     if (name_size > 0)
464                         attribute->name(name, name_size);
465                     else
466                         attribute->name(name);
467                 }
468                 if (value)
469                 {
470                     if (value_size > 0)
471                         attribute->value(value, value_size);
472                     else
473                         attribute->value(value);
474                 }
475                 return attribute;
476             }
477
478             //! Allocates a char array of given size from the pool, and optionally copies a given string to it.
479             //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
480             //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
481             //! will call rapidxml::parse_error_handler() function.
482             //! \param source String to initialize the allocated memory with, or 0 to not initialize it.
483             //! \param size Number of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated.
484             //! \return Pointer to allocated char array. This pointer will never be NULL.
485             Ch *allocate_string(const Ch *source = 0, std::size_t size = 0)
486             {
487                 assert(source || size);     // Either source or size (or both) must be specified
488                 if (size == 0)
489                     size = internal::measure(source) + 1;
490                 Ch *result = static_cast<Ch *>(allocate_aligned(size * sizeof(Ch)));
491                 if (source)
492                     for (std::size_t i = 0; i < size; ++i)
493                         result[i] = source[i];
494                 return result;
495             }
496
497             //! Clones an xml_node and its hierarchy of child nodes and attributes.
498             //! Nodes and attributes are allocated from this memory pool.
499             //! Names and values are not cloned, they are shared between the clone and the source.
500             //! Result node can be optionally specified as a second parameter,
501             //! in which case its contents will be replaced with cloned source node.
502             //! This is useful when you want to clone entire document.
503             //! \param source Node to clone.
504             //! \param result Node to put results in, or 0 to automatically allocate result node
505             //! \return Pointer to cloned node. This pointer will never be NULL.
506             xml_node<Ch> *clone_node(const xml_node<Ch> *source, xml_node<Ch> *result = 0)
507             {
508                 // Prepare result node
509                 if (result)
510                 {
511                     result->remove_all_attributes();
512                     result->remove_all_nodes();
513                     result->type(source->type());
514                 }
515                 else
516                     result = allocate_node(source->type());
517
518                 // Clone name and value
519                 result->name(source->name(), source->name_size());
520                 result->value(source->value(), source->value_size());
521
522                 // Clone child nodes and attributes
523                 for (xml_node<Ch> *child = source->first_node(); child; child = child->next_sibling())
524                     result->append_node(clone_node(child));
525                 for (xml_attribute<Ch> *attr = source->first_attribute(); attr; attr = attr->next_attribute())
526                     result->append_attribute(allocate_attribute(attr->name(), attr->value(), attr->name_size(),
527                                              attr->value_size()));
528
529                 return result;
530             }
531
532             //! Clears the pool.
533             //! This causes memory occupied by nodes allocated by the pool to be freed.
534             //! Any nodes or strings allocated from the pool will no longer be valid.
535             void clear()
536             {
537                 while (m_begin != m_static_memory)
538                 {
539                     char *previous_begin = reinterpret_cast<header *>(align(m_begin))->previous_begin;
540                     if (m_free_func)
541                         m_free_func(m_begin);
542                     else
543                         delete[] m_begin;
544                     m_begin = previous_begin;
545                 }
546                 init();
547             }
548
549             //! Sets or resets the user-defined memory allocation functions for the pool.
550             //! This can only be called when no memory is allocated from the pool yet, otherwise results are undefined.
551             //! Allocation function must not return invalid pointer on failure. It should either throw,
552             //! stop the program, or use <code>longjmp()</code> function to pass control to other place of program.
553             //! If it returns invalid pointer, results are undefined.
554             //! <br><br>
555             //! User defined allocation functions must have the following forms:
556             //! <br><code>
557             //! <br>void *allocate(std::size_t size);
558             //! <br>void free(void *pointer);
559             //! </code><br>
560             //! \param af Allocation function, or 0 to restore default function
561             //! \param ff Free function, or 0 to restore default function
562             void set_allocator(alloc_func *af, free_func *ff)
563             {
564                 assert(m_begin == m_static_memory
565                        && m_ptr == align(m_begin));    // Verify that no memory is allocated yet
566                 m_alloc_func = af;
567                 m_free_func = ff;
568             }
569
570         private:
571
572             struct header
573             {
574                 char *previous_begin;
575             };
576
577             void init()
578             {
579                 m_begin = m_static_memory;
580                 m_ptr = align(m_begin);
581                 m_end = m_static_memory + sizeof(m_static_memory);
582             }
583
584             char *align(char *ptr)
585             {
586                 std::size_t alignment = ((RAPIDXML_ALIGNMENT - (std::size_t(ptr) & (RAPIDXML_ALIGNMENT - 1))) &
587                                          (RAPIDXML_ALIGNMENT - 1));
588                 return ptr + alignment;
589             }
590
591             char *allocate_raw(std::size_t size)
592             {
593                 // Allocate
594                 void *memory;
595                 if (m_alloc_func)   // Allocate memory using either user-specified allocation function or global operator new[]
596                 {
597                     memory = m_alloc_func(size);
598                     assert(memory); // Allocator is not allowed to return 0, on failure it must either throw, stop the program or use longjmp
599                 }
600                 else
601                 {
602                     memory = new char[size];
603 #ifdef RAPIDXML_NO_EXCEPTIONS
604                     if (!memory)            // If exceptions are disabled, verify memory allocation, because new will not be able to throw bad_alloc
605                         RAPIDXML_PARSE_ERROR("out of memory", 0);
606 #endif
607                 }
608                 return static_cast<char *>(memory);
609             }
610
611             void *allocate_aligned(std::size_t size)
612             {
613                 // Calculate aligned pointer
614                 char *result = align(m_ptr);
615
616                 // If not enough memory left in current pool, allocate a new pool
617                 if (result + size > m_end)
618                 {
619                     // Calculate required pool size (may be bigger than RAPIDXML_DYNAMIC_POOL_SIZE)
620                     std::size_t pool_size = RAPIDXML_DYNAMIC_POOL_SIZE;
621                     if (pool_size < size)
622                         pool_size = size;
623
624                     // Allocate
625                     std::size_t alloc_size = sizeof(header) + (2 * RAPIDXML_ALIGNMENT - 2) +
626                                              pool_size;     // 2 alignments required in worst case: one for header, one for actual allocation
627                     char *raw_memory = allocate_raw(alloc_size);
628
629                     // Setup new pool in allocated memory
630                     char *pool = align(raw_memory);
631                     header *new_header = reinterpret_cast<header *>(pool);
632                     new_header->previous_begin = m_begin;
633                     m_begin = raw_memory;
634                     m_ptr = pool + sizeof(header);
635                     m_end = raw_memory + alloc_size;
636
637                     // Calculate aligned pointer again using new pool
638                     result = align(m_ptr);
639                 }
640
641                 // Update pool and return aligned pointer
642                 m_ptr = result + size;
643                 return result;
644             }
645
646             char *m_begin;                                      // Start of raw memory making up current pool
647             char *m_ptr;                                        // First free byte in current pool
648             char *m_end;                                        // One past last available byte in current pool
649             char m_static_memory[RAPIDXML_STATIC_POOL_SIZE];    // Static raw memory
650             alloc_func
651             *m_alloc_func;                           // Allocator function, or 0 if default is to be used
652             free_func *m_free_func;                             // Free function, or 0 if default is to be used
653     };
654
655     ///////////////////////////////////////////////////////////////////////////
656     // XML base
657
658     //! Base class for xml_node and xml_attribute implementing common functions:
659     //! name(), name_size(), value(), value_size() and parent().
660     //! \param Ch Character type to use
661     template<class Ch = char>
662     class xml_base
663     {
664
665         public:
666
667             ///////////////////////////////////////////////////////////////////////////
668             // Construction & destruction
669
670             // Construct a base with empty name, value and parent
671             xml_base()
672                 : m_name(0)
673                 , m_value(0)
674                 , m_parent(0)
675             {
676             }
677
678             ///////////////////////////////////////////////////////////////////////////
679             // Node data access
680
681             //! Gets name of the node.
682             //! Interpretation of name depends on type of node.
683             //! Note that name will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.
684             //! <br><br>
685             //! Use name_size() function to determine length of the name.
686             //! \return Name of node, or empty string if node has no name.
687             Ch *name() const
688             {
689                 return m_name ? m_name : nullstr();
690             }
691
692             //! Gets size of node name, not including terminator character.
693             //! This function works correctly irrespective of whether name is or is not zero terminated.
694             //! \return Size of node name, in characters.
695             std::size_t name_size() const
696             {
697                 return m_name ? m_name_size : 0;
698             }
699
700             //! Gets value of node.
701             //! Interpretation of value depends on type of node.
702             //! Note that value will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.
703             //! <br><br>
704             //! Use value_size() function to determine length of the value.
705             //! \return Value of node, or empty string if node has no value.
706             Ch *value() const
707             {
708                 return m_value ? m_value : nullstr();
709             }
710
711             //! Gets size of node value, not including terminator character.
712             //! This function works correctly irrespective of whether value is or is not zero terminated.
713             //! \return Size of node value, in characters.
714             std::size_t value_size() const
715             {
716                 return m_value ? m_value_size : 0;
717             }
718
719             ///////////////////////////////////////////////////////////////////////////
720             // Node modification
721
722             //! Sets name of node to a non zero-terminated string.
723             //! See \ref ownership_of_strings.
724             //! <br><br>
725             //! Note that node does not own its name or value, it only stores a pointer to it.
726             //! It will not delete or otherwise free the pointer on destruction.
727             //! It is reponsibility of the user to properly manage lifetime of the string.
728             //! The easiest way to achieve it is to use memory_pool of the document to allocate the string -
729             //! on destruction of the document the string will be automatically freed.
730             //! <br><br>
731             //! Size of name must be specified separately, because name does not have to be zero terminated.
732             //! Use name(const Ch *) function to have the length automatically calculated (string must be zero terminated).
733             //! \param name Name of node to set. Does not have to be zero terminated.
734             //! \param size Size of name, in characters. This does not include zero terminator, if one is present.
735             void name(const Ch *name, std::size_t size)
736             {
737                 m_name = const_cast<Ch *>(name);
738                 m_name_size = size;
739             }
740
741             //! Sets name of node to a zero-terminated string.
742             //! See also \ref ownership_of_strings and xml_node::name(const Ch *, std::size_t).
743             //! \param name Name of node to set. Must be zero terminated.
744             void name(const Ch *name)
745             {
746                 this->name(name, internal::measure(name));
747             }
748
749             //! Sets value of node to a non zero-terminated string.
750             //! See \ref ownership_of_strings.
751             //! <br><br>
752             //! Note that node does not own its name or value, it only stores a pointer to it.
753             //! It will not delete or otherwise free the pointer on destruction.
754             //! It is reponsibility of the user to properly manage lifetime of the string.
755             //! The easiest way to achieve it is to use memory_pool of the document to allocate the string -
756             //! on destruction of the document the string will be automatically freed.
757             //! <br><br>
758             //! Size of value must be specified separately, because it does not have to be zero terminated.
759             //! Use value(const Ch *) function to have the length automatically calculated (string must be zero terminated).
760             //! <br><br>
761             //! If an element has a child node of type node_data, it will take precedence over element value when printing.
762             //! If you want to manipulate data of elements using values, use parser flag rapidxml::parse_no_data_nodes to prevent creation of data nodes by the parser.
763             //! \param value value of node to set. Does not have to be zero terminated.
764             //! \param size Size of value, in characters. This does not include zero terminator, if one is present.
765             void value(const Ch *value, std::size_t size)
766             {
767                 m_value = const_cast<Ch *>(value);
768                 m_value_size = size;
769             }
770
771             //! Sets value of node to a zero-terminated string.
772             //! See also \ref ownership_of_strings and xml_node::value(const Ch *, std::size_t).
773             //! \param value Vame of node to set. Must be zero terminated.
774             void value(const Ch *value)
775             {
776                 this->value(value, internal::measure(value));
777             }
778
779             ///////////////////////////////////////////////////////////////////////////
780             // Related nodes access
781
782             //! Gets node parent.
783             //! \return Pointer to parent node, or 0 if there is no parent.
784             xml_node<Ch> *parent() const
785             {
786                 return m_parent;
787             }
788
789         protected:
790
791             // Return empty string
792             static Ch *nullstr()
793             {
794                 static Ch zero = Ch('\0');
795                 return &zero;
796             }
797
798             Ch *m_name;                         // Name of node, or 0 if no name
799             Ch *m_value;                        // Value of node, or 0 if no value
800             std::size_t m_name_size;            // Length of node name, or undefined of no name
801             std::size_t m_value_size;           // Length of node value, or undefined if no value
802             xml_node<Ch> *m_parent;             // Pointer to parent node, or 0 if none
803
804     };
805
806     //! Class representing attribute node of XML document.
807     //! Each attribute has name and value strings, which are available through name() and value() functions (inherited from xml_base).
808     //! Note that after parse, both name and value of attribute will point to interior of source text used for parsing.
809     //! Thus, this text must persist in memory for the lifetime of attribute.
810     //! \param Ch Character type to use.
811     template<class Ch = char>
812     class xml_attribute: public xml_base<Ch>
813     {
814
815             friend class xml_node<Ch>;
816
817         public:
818
819             ///////////////////////////////////////////////////////////////////////////
820             // Construction & destruction
821
822             //! Constructs an empty attribute with the specified type.
823             //! Consider using memory_pool of appropriate xml_document if allocating attributes manually.
824             xml_attribute()
825             {
826             }
827
828             ///////////////////////////////////////////////////////////////////////////
829             // Related nodes access
830
831             //! Gets document of which attribute is a child.
832             //! \return Pointer to document that contains this attribute, or 0 if there is no parent document.
833             xml_document<Ch> *document() const
834             {
835                 if (xml_node<Ch> *node = this->parent())
836                 {
837                     while (node->parent())
838                         node = node->parent();
839                     return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0;
840                 }
841                 else
842                     return 0;
843             }
844
845             //! Gets previous attribute, optionally matching attribute name.
846             //! \param name Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
847             //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
848             //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
849             //! \return Pointer to found attribute, or 0 if not found.
850             xml_attribute<Ch> *previous_attribute(const Ch *name = 0, std::size_t name_size = 0,
851                                                   bool case_sensitive = true) const
852             {
853                 if (name)
854                 {
855                     if (name_size == 0)
856                         name_size = internal::measure(name);
857                     for (xml_attribute<Ch> *attribute = m_prev_attribute; attribute;
858                          attribute = attribute->m_prev_attribute)
859                         if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive))
860                             return attribute;
861                     return 0;
862                 }
863                 else
864                     return this->m_parent ? m_prev_attribute : 0;
865             }
866
867             //! Gets next attribute, optionally matching attribute name.
868             //! \param name Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
869             //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
870             //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
871             //! \return Pointer to found attribute, or 0 if not found.
872             xml_attribute<Ch> *next_attribute(const Ch *name = 0, std::size_t name_size = 0,
873                                               bool case_sensitive = true) const
874             {
875                 if (name)
876                 {
877                     if (name_size == 0)
878                         name_size = internal::measure(name);
879                     for (xml_attribute<Ch> *attribute = m_next_attribute; attribute;
880                          attribute = attribute->m_next_attribute)
881                         if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive))
882                             return attribute;
883                     return 0;
884                 }
885                 else
886                     return this->m_parent ? m_next_attribute : 0;
887             }
888
889         private:
890
891             xml_attribute<Ch>
892             *m_prev_attribute;        // Pointer to previous sibling of attribute, or 0 if none; only valid if parent is non-zero
893             xml_attribute<Ch>
894             *m_next_attribute;        // Pointer to next sibling of attribute, or 0 if none; only valid if parent is non-zero
895
896     };
897
898     ///////////////////////////////////////////////////////////////////////////
899     // XML node
900
901     //! Class representing a node of XML document.
902     //! Each node may have associated name and value strings, which are available through name() and value() functions.
903     //! Interpretation of name and value depends on type of the node.
904     //! Type of node can be determined by using type() function.
905     //! <br><br>
906     //! Note that after parse, both name and value of node, if any, will point interior of source text used for parsing.
907     //! Thus, this text must persist in the memory for the lifetime of node.
908     //! \param Ch Character type to use.
909     template<class Ch = char>
910     class xml_node: public xml_base<Ch>
911     {
912
913         public:
914
915             ///////////////////////////////////////////////////////////////////////////
916             // Construction & destruction
917
918             //! Constructs an empty node with the specified type.
919             //! Consider using memory_pool of appropriate document to allocate nodes manually.
920             //! \param type Type of node to construct.
921             xml_node(node_type type)
922                 : m_type(type)
923                 , m_first_node(0)
924                 , m_first_attribute(0)
925             {
926             }
927
928             ///////////////////////////////////////////////////////////////////////////
929             // Node data access
930
931             //! Gets type of node.
932             //! \return Type of node.
933             node_type type() const
934             {
935                 return m_type;
936             }
937
938             ///////////////////////////////////////////////////////////////////////////
939             // Related nodes access
940
941             //! Gets document of which node is a child.
942             //! \return Pointer to document that contains this node, or 0 if there is no parent document.
943             xml_document<Ch> *document() const
944             {
945                 xml_node<Ch> *node = const_cast<xml_node<Ch> *>(this);
946                 while (node->parent())
947                     node = node->parent();
948                 return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0;
949             }
950
951             //! Gets first child node, optionally matching node name.
952             //! \param name Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
953             //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
954             //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
955             //! \return Pointer to found child, or 0 if not found.
956             xml_node<Ch> *first_node(const Ch *name = 0, std::size_t name_size = 0,
957                                      bool case_sensitive = true) const
958             {
959                 if (name)
960                 {
961                     if (name_size == 0)
962                         name_size = internal::measure(name);
963                     for (xml_node<Ch> *child = m_first_node; child; child = child->next_sibling())
964                         if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive))
965                             return child;
966                     return 0;
967                 }
968                 else
969                     return m_first_node;
970             }
971
972             //! Gets last child node, optionally matching node name.
973             //! Behaviour is undefined if node has no children.
974             //! Use first_node() to test if node has children.
975             //! \param name Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
976             //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
977             //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
978             //! \return Pointer to found child, or 0 if not found.
979             xml_node<Ch> *last_node(const Ch *name = 0, std::size_t name_size = 0,
980                                     bool case_sensitive = true) const
981             {
982                 assert(m_first_node);  // Cannot query for last child if node has no children
983                 if (name)
984                 {
985                     if (name_size == 0)
986                         name_size = internal::measure(name);
987                     for (xml_node<Ch> *child = m_last_node; child; child = child->previous_sibling())
988                         if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive))
989                             return child;
990                     return 0;
991                 }
992                 else
993                     return m_last_node;
994             }
995
996             //! Gets previous sibling node, optionally matching node name.
997             //! Behaviour is undefined if node has no parent.
998             //! Use parent() to test if node has a parent.
999             //! \param name Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
1000             //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
1001             //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
1002             //! \return Pointer to found sibling, or 0 if not found.
1003             xml_node<Ch> *previous_sibling(const Ch *name = 0, std::size_t name_size = 0,
1004                                            bool case_sensitive = true) const
1005             {
1006                 assert(this->m_parent);     // Cannot query for siblings if node has no parent
1007                 if (name)
1008                 {
1009                     if (name_size == 0)
1010                         name_size = internal::measure(name);
1011                     for (xml_node<Ch> *sibling = m_prev_sibling; sibling; sibling = sibling->m_prev_sibling)
1012                         if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive))
1013                             return sibling;
1014                     return 0;
1015                 }
1016                 else
1017                     return m_prev_sibling;
1018             }
1019
1020             //! Gets next sibling node, optionally matching node name.
1021             //! Behaviour is undefined if node has no parent.
1022             //! Use parent() to test if node has a parent.
1023             //! \param name Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
1024             //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
1025             //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
1026             //! \return Pointer to found sibling, or 0 if not found.
1027             xml_node<Ch> *next_sibling(const Ch *name = 0, std::size_t name_size = 0,
1028                                        bool case_sensitive = true) const
1029             {
1030                 assert(this->m_parent);     // Cannot query for siblings if node has no parent
1031                 if (name)
1032                 {
1033                     if (name_size == 0)
1034                         name_size = internal::measure(name);
1035                     for (xml_node<Ch> *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling)
1036                         if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive))
1037                             return sibling;
1038                     return 0;
1039                 }
1040                 else
1041                     return m_next_sibling;
1042             }
1043
1044             //! Gets first attribute of node, optionally matching attribute name.
1045             //! \param name Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
1046             //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
1047             //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
1048             //! \return Pointer to found attribute, or 0 if not found.
1049             xml_attribute<Ch> *first_attribute(const Ch *name = 0, std::size_t name_size = 0,
1050                                                bool case_sensitive = true) const
1051             {
1052                 if (name)
1053                 {
1054                     if (name_size == 0)
1055                         name_size = internal::measure(name);
1056                     for (xml_attribute<Ch> *attribute = m_first_attribute; attribute;
1057                          attribute = attribute->m_next_attribute)
1058                         if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive))
1059                             return attribute;
1060                     return 0;
1061                 }
1062                 else
1063                     return m_first_attribute;
1064             }
1065
1066             //! Gets last attribute of node, optionally matching attribute name.
1067             //! \param name Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
1068             //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
1069             //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
1070             //! \return Pointer to found attribute, or 0 if not found.
1071             xml_attribute<Ch> *last_attribute(const Ch *name = 0, std::size_t name_size = 0,
1072                                               bool case_sensitive = true) const
1073             {
1074                 if (name)
1075                 {
1076                     if (name_size == 0)
1077                         name_size = internal::measure(name);
1078                     for (xml_attribute<Ch> *attribute = m_last_attribute; attribute;
1079                          attribute = attribute->m_prev_attribute)
1080                         if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive))
1081                             return attribute;
1082                     return 0;
1083                 }
1084                 else
1085                     return m_first_attribute ? m_last_attribute : 0;
1086             }
1087
1088             ///////////////////////////////////////////////////////////////////////////
1089             // Node modification
1090
1091             //! Sets type of node.
1092             //! \param type Type of node to set.
1093             void type(node_type type)
1094             {
1095                 m_type = type;
1096             }
1097
1098             ///////////////////////////////////////////////////////////////////////////
1099             // Node manipulation
1100
1101             //! Prepends a new child node.
1102             //! The prepended child becomes the first child, and all existing children are moved one position back.
1103             //! \param child Node to prepend.
1104             void prepend_node(xml_node<Ch> *child)
1105             {
1106                 assert(child && !child->parent() && child->type() != node_document);
1107                 if (first_node())
1108                 {
1109                     child->m_next_sibling = m_first_node;
1110                     m_first_node->m_prev_sibling = child;
1111                 }
1112                 else
1113                 {
1114                     child->m_next_sibling = 0;
1115                     m_last_node = child;
1116                 }
1117                 m_first_node = child;
1118                 child->m_parent = this;
1119                 child->m_prev_sibling = 0;
1120             }
1121
1122             //! Appends a new child node.
1123             //! The appended child becomes the last child.
1124             //! \param child Node to append.
1125             void append_node(xml_node<Ch> *child)
1126             {
1127                 assert(child && !child->parent() && child->type() != node_document);
1128                 if (first_node())
1129                 {
1130                     child->m_prev_sibling = m_last_node;
1131                     m_last_node->m_next_sibling = child;
1132                 }
1133                 else
1134                 {
1135                     child->m_prev_sibling = 0;
1136                     m_first_node = child;
1137                 }
1138                 m_last_node = child;
1139                 child->m_parent = this;
1140                 child->m_next_sibling = 0;
1141             }
1142
1143             //! Inserts a new child node at specified place inside the node.
1144             //! All children after and including the specified node are moved one position back.
1145             //! \param where Place where to insert the child, or 0 to insert at the back.
1146             //! \param child Node to insert.
1147             void insert_node(xml_node<Ch> *where, xml_node<Ch> *child)
1148             {
1149                 assert(!where || where->parent() == this);
1150                 assert(child && !child->parent() && child->type() != node_document);
1151                 if (where == m_first_node)
1152                     prepend_node(child);
1153                 else if (where == 0)
1154                     append_node(child);
1155                 else
1156                 {
1157                     child->m_prev_sibling = where->m_prev_sibling;
1158                     child->m_next_sibling = where;
1159                     where->m_prev_sibling->m_next_sibling = child;
1160                     where->m_prev_sibling = child;
1161                     child->m_parent = this;
1162                 }
1163             }
1164
1165             //! Removes first child node.
1166             //! If node has no children, behaviour is undefined.
1167             //! Use first_node() to test if node has children.
1168             void remove_first_node()
1169             {
1170                 assert(first_node());
1171                 xml_node<Ch> *child = m_first_node;
1172                 m_first_node = child->m_next_sibling;
1173                 if (child->m_next_sibling)
1174                     child->m_next_sibling->m_prev_sibling = 0;
1175                 else
1176                     m_last_node = 0;
1177                 child->m_parent = 0;
1178             }
1179
1180             //! Removes last child of the node.
1181             //! If node has no children, behaviour is undefined.
1182             //! Use first_node() to test if node has children.
1183             void remove_last_node()
1184             {
1185                 assert(first_node());
1186                 xml_node<Ch> *child = m_last_node;
1187                 if (child->m_prev_sibling)
1188                 {
1189                     m_last_node = child->m_prev_sibling;
1190                     child->m_prev_sibling->m_next_sibling = 0;
1191                 }
1192                 else
1193                     m_first_node = 0;
1194                 child->m_parent = 0;
1195             }
1196
1197             //! Removes specified child from the node
1198             // \param where Pointer to child to be removed.
1199             void remove_node(xml_node<Ch> *where)
1200             {
1201                 assert(where && where->parent() == this);
1202                 assert(first_node());
1203                 if (where == m_first_node)
1204                     remove_first_node();
1205                 else if (where == m_last_node)
1206                     remove_last_node();
1207                 else
1208                 {
1209                     where->m_prev_sibling->m_next_sibling = where->m_next_sibling;
1210                     where->m_next_sibling->m_prev_sibling = where->m_prev_sibling;
1211                     where->m_parent = 0;
1212                 }
1213             }
1214
1215             //! Removes all child nodes (but not attributes).
1216             void remove_all_nodes()
1217             {
1218                 for (xml_node<Ch> *node = first_node(); node; node = node->m_next_sibling)
1219                     node->m_parent = 0;
1220                 m_first_node = 0;
1221             }
1222
1223             //! Prepends a new attribute to the node.
1224             //! \param attribute Attribute to prepend.
1225             void prepend_attribute(xml_attribute<Ch> *attribute)
1226             {
1227                 assert(attribute && !attribute->parent());
1228                 if (first_attribute())
1229                 {
1230                     attribute->m_next_attribute = m_first_attribute;
1231                     m_first_attribute->m_prev_attribute = attribute;
1232                 }
1233                 else
1234                 {
1235                     attribute->m_next_attribute = 0;
1236                     m_last_attribute = attribute;
1237                 }
1238                 m_first_attribute = attribute;
1239                 attribute->m_parent = this;
1240                 attribute->m_prev_attribute = 0;
1241             }
1242
1243             //! Appends a new attribute to the node.
1244             //! \param attribute Attribute to append.
1245             void append_attribute(xml_attribute<Ch> *attribute)
1246             {
1247                 assert(attribute && !attribute->parent());
1248                 if (first_attribute())
1249                 {
1250                     attribute->m_prev_attribute = m_last_attribute;
1251                     m_last_attribute->m_next_attribute = attribute;
1252                 }
1253                 else
1254                 {
1255                     attribute->m_prev_attribute = 0;
1256                     m_first_attribute = attribute;
1257                 }
1258                 m_last_attribute = attribute;
1259                 attribute->m_parent = this;
1260                 attribute->m_next_attribute = 0;
1261             }
1262
1263             //! Inserts a new attribute at specified place inside the node.
1264             //! All attributes after and including the specified attribute are moved one position back.
1265             //! \param where Place where to insert the attribute, or 0 to insert at the back.
1266             //! \param attribute Attribute to insert.
1267             void insert_attribute(xml_attribute<Ch> *where, xml_attribute<Ch> *attribute)
1268             {
1269                 assert(!where || where->parent() == this);
1270                 assert(attribute && !attribute->parent());
1271                 if (where == m_first_attribute)
1272                     prepend_attribute(attribute);
1273                 else if (where == 0)
1274                     append_attribute(attribute);
1275                 else
1276                 {
1277                     attribute->m_prev_attribute = where->m_prev_attribute;
1278                     attribute->m_next_attribute = where;
1279                     where->m_prev_attribute->m_next_attribute = attribute;
1280                     where->m_prev_attribute = attribute;
1281                     attribute->m_parent = this;
1282                 }
1283             }
1284
1285             //! Removes first attribute of the node.
1286             //! If node has no attributes, behaviour is undefined.
1287             //! Use first_attribute() to test if node has attributes.
1288             void remove_first_attribute()
1289             {
1290                 assert(first_attribute());
1291                 xml_attribute<Ch> *attribute = m_first_attribute;
1292                 if (attribute->m_next_attribute)
1293                 {
1294                     attribute->m_next_attribute->m_prev_attribute = 0;
1295                 }
1296                 else
1297                     m_last_attribute = 0;
1298                 attribute->m_parent = 0;
1299                 m_first_attribute = attribute->m_next_attribute;
1300             }
1301
1302             //! Removes last attribute of the node.
1303             //! If node has no attributes, behaviour is undefined.
1304             //! Use first_attribute() to test if node has attributes.
1305             void remove_last_attribute()
1306             {
1307                 assert(first_attribute());
1308                 xml_attribute<Ch> *attribute = m_last_attribute;
1309                 if (attribute->m_prev_attribute)
1310                 {
1311                     attribute->m_prev_attribute->m_next_attribute = 0;
1312                     m_last_attribute = attribute->m_prev_attribute;
1313                 }
1314                 else
1315                     m_first_attribute = 0;
1316                 attribute->m_parent = 0;
1317             }
1318
1319             //! Removes specified attribute from node.
1320             //! \param where Pointer to attribute to be removed.
1321             void remove_attribute(xml_attribute<Ch> *where)
1322             {
1323                 assert(first_attribute() && where->parent() == this);
1324                 if (where == m_first_attribute)
1325                     remove_first_attribute();
1326                 else if (where == m_last_attribute)
1327                     remove_last_attribute();
1328                 else
1329                 {
1330                     where->m_prev_attribute->m_next_attribute = where->m_next_attribute;
1331                     where->m_next_attribute->m_prev_attribute = where->m_prev_attribute;
1332                     where->m_parent = 0;
1333                 }
1334             }
1335
1336             //! Removes all attributes of node.
1337             void remove_all_attributes()
1338             {
1339                 for (xml_attribute<Ch> *attribute = first_attribute(); attribute;
1340                      attribute = attribute->m_next_attribute)
1341                     attribute->m_parent = 0;
1342                 m_first_attribute = 0;
1343             }
1344
1345         private:
1346
1347             ///////////////////////////////////////////////////////////////////////////
1348             // Restrictions
1349
1350             // No copying
1351             xml_node(const xml_node &);
1352             void operator =(const xml_node &);
1353
1354             ///////////////////////////////////////////////////////////////////////////
1355             // Data members
1356
1357             // Note that some of the pointers below have UNDEFINED values if certain other pointers are 0.
1358             // This is required for maximum performance, as it allows the parser to omit initialization of
1359             // unneded/redundant values.
1360             //
1361             // The rules are as follows:
1362             // 1. first_node and first_attribute contain valid pointers, or 0 if node has no children/attributes respectively
1363             // 2. last_node and last_attribute are valid only if node has at least one child/attribute respectively, otherwise they contain garbage
1364             // 3. prev_sibling and next_sibling are valid only if node has a parent, otherwise they contain garbage
1365
1366             node_type m_type;                       // Type of node; always valid
1367             xml_node<Ch> *m_first_node;             // Pointer to first child node, or 0 if none; always valid
1368             xml_node<Ch>
1369             *m_last_node;              // Pointer to last child node, or 0 if none; this value is only valid if m_first_node is non-zero
1370             xml_attribute<Ch>
1371             *m_first_attribute;   // Pointer to first attribute of node, or 0 if none; always valid
1372             xml_attribute<Ch>
1373             *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
1374             xml_node<Ch>
1375             *m_prev_sibling;           // Pointer to previous sibling of node, or 0 if none; this value is only valid if m_parent is non-zero
1376             xml_node<Ch>
1377             *m_next_sibling;           // Pointer to next sibling of node, or 0 if none; this value is only valid if m_parent is non-zero
1378
1379     };
1380
1381     ///////////////////////////////////////////////////////////////////////////
1382     // XML document
1383
1384     //! This class represents root of the DOM hierarchy.
1385     //! It is also an xml_node and a memory_pool through public inheritance.
1386     //! Use parse() function to build a DOM tree from a zero-terminated XML text string.
1387     //! parse() function allocates memory for nodes and attributes by using functions of xml_document,
1388     //! which are inherited from memory_pool.
1389     //! To access root node of the document, use the document itself, as if it was an xml_node.
1390     //! \param Ch Character type to use.
1391     template<class Ch = char>
1392     class xml_document: public xml_node<Ch>, public memory_pool<Ch>
1393     {
1394
1395         public:
1396
1397             //! Constructs empty XML document
1398             xml_document()
1399                 : xml_node<Ch>(node_document)
1400             {
1401             }
1402
1403             //! Parses zero-terminated XML string according to given flags.
1404             //! Passed string will be modified by the parser, unless rapidxml::parse_non_destructive flag is used.
1405             //! The string must persist for the lifetime of the document.
1406             //! In case of error, rapidxml::parse_error exception will be thrown.
1407             //! <br><br>
1408             //! If you want to parse contents of a file, you must first load the file into the memory, and pass pointer to its beginning.
1409             //! Make sure that data is zero-terminated.
1410             //! <br><br>
1411             //! Document can be parsed into multiple times.
1412             //! Each new call to parse removes previous nodes and attributes (if any), but does not clear memory pool.
1413             //! \param text XML data to parse; pointer is non-const to denote fact that this data may be modified by the parser.
1414             template<int Flags>
1415             void parse(Ch *text)
1416             {
1417                 assert(text);
1418
1419                 // Remove current contents
1420                 this->remove_all_nodes();
1421                 this->remove_all_attributes();
1422
1423                 // Parse BOM, if any
1424                 parse_bom<Flags>(text);
1425
1426                 // Parse children
1427                 while (1)
1428                 {
1429                     // Skip whitespace before node
1430                     skip<whitespace_pred, Flags>(text);
1431                     if (*text == 0)
1432                         break;
1433
1434                     // Parse and append new child
1435                     if (*text == Ch('<'))
1436                     {
1437                         ++text;     // Skip '<'
1438                         if (xml_node<Ch> *node = parse_node<Flags>(text))
1439                             this->append_node(node);
1440                     }
1441                     else
1442                         RAPIDXML_PARSE_ERROR("expected <", text);
1443                 }
1444
1445             }
1446
1447             //! Clears the document by deleting all nodes and clearing the memory pool.
1448             //! All nodes owned by document pool are destroyed.
1449             void clear()
1450             {
1451                 this->remove_all_nodes();
1452                 this->remove_all_attributes();
1453                 memory_pool<Ch>::clear();
1454             }
1455
1456         private:
1457
1458             ///////////////////////////////////////////////////////////////////////
1459             // Internal character utility functions
1460
1461             // Detect whitespace character
1462             struct whitespace_pred
1463             {
1464                 static unsigned char test(Ch ch)
1465                 {
1466                     return internal::lookup_tables<0>::lookup_whitespace[static_cast<unsigned char>(ch)];
1467                 }
1468             };
1469
1470             // Detect node name character
1471             struct node_name_pred
1472             {
1473                 static unsigned char test(Ch ch)
1474                 {
1475                     return internal::lookup_tables<0>::lookup_node_name[static_cast<unsigned char>(ch)];
1476                 }
1477             };
1478
1479             // Detect attribute name character
1480             struct attribute_name_pred
1481             {
1482                 static unsigned char test(Ch ch)
1483                 {
1484                     return internal::lookup_tables<0>::lookup_attribute_name[static_cast<unsigned char>(ch)];
1485                 }
1486             };
1487
1488             // Detect text character (PCDATA)
1489             struct text_pred
1490             {
1491                 static unsigned char test(Ch ch)
1492                 {
1493                     return internal::lookup_tables<0>::lookup_text[static_cast<unsigned char>(ch)];
1494                 }
1495             };
1496
1497             // Detect text character (PCDATA) that does not require processing
1498             struct text_pure_no_ws_pred
1499             {
1500                 static unsigned char test(Ch ch)
1501                 {
1502                     return internal::lookup_tables<0>::lookup_text_pure_no_ws[static_cast<unsigned char>(ch)];
1503                 }
1504             };
1505
1506             // Detect text character (PCDATA) that does not require processing
1507             struct text_pure_with_ws_pred
1508             {
1509                 static unsigned char test(Ch ch)
1510                 {
1511                     return internal::lookup_tables<0>::lookup_text_pure_with_ws[static_cast<unsigned char>(ch)];
1512                 }
1513             };
1514
1515             // Detect attribute value character
1516             template<Ch Quote>
1517             struct attribute_value_pred
1518             {
1519                 static unsigned char test(Ch ch)
1520                 {
1521                     if (Quote == Ch('\''))
1522                         return internal::lookup_tables<0>::lookup_attribute_data_1[static_cast<unsigned char>(ch)];
1523                     if (Quote == Ch('\"'))
1524                         return internal::lookup_tables<0>::lookup_attribute_data_2[static_cast<unsigned char>(ch)];
1525                     return 0;       // Should never be executed, to avoid warnings on Comeau
1526                 }
1527             };
1528
1529             // Detect attribute value character
1530             template<Ch Quote>
1531             struct attribute_value_pure_pred
1532             {
1533                 static unsigned char test(Ch ch)
1534                 {
1535                     if (Quote == Ch('\''))
1536                         return internal::lookup_tables<0>::lookup_attribute_data_1_pure[static_cast<unsigned char>(ch)];
1537                     if (Quote == Ch('\"'))
1538                         return internal::lookup_tables<0>::lookup_attribute_data_2_pure[static_cast<unsigned char>(ch)];
1539                     return 0;       // Should never be executed, to avoid warnings on Comeau
1540                 }
1541             };
1542
1543             // Insert coded character, using UTF8 or 8-bit ASCII
1544             template<int Flags>
1545             static void insert_coded_character(Ch *&text, unsigned long code)
1546             {
1547                 if (Flags & parse_no_utf8)
1548                 {
1549                     // Insert 8-bit ASCII character
1550                     // Todo: possibly verify that code is less than 256 and use replacement char otherwise?
1551                     text[0] = static_cast<unsigned char>(code);
1552                     text += 1;
1553                 }
1554                 else
1555                 {
1556                     // Insert UTF8 sequence
1557                     if (code < 0x80)    // 1 byte sequence
1558                     {
1559                         text[0] = static_cast<unsigned char>(code);
1560                         text += 1;
1561                     }
1562                     else if (code < 0x800)  // 2 byte sequence
1563                     {
1564                         text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1565                         text[0] = static_cast<unsigned char>(code | 0xC0);
1566                         text += 2;
1567                     }
1568                     else if (code < 0x10000)    // 3 byte sequence
1569                     {
1570                         text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1571                         text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1572                         text[0] = static_cast<unsigned char>(code | 0xE0);
1573                         text += 3;
1574                     }
1575                     else if (code < 0x110000)   // 4 byte sequence
1576                     {
1577                         text[3] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1578                         text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1579                         text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1580                         text[0] = static_cast<unsigned char>(code | 0xF0);
1581                         text += 4;
1582                     }
1583                     else    // Invalid, only codes up to 0x10FFFF are allowed in Unicode
1584                     {
1585                         RAPIDXML_PARSE_ERROR("invalid numeric character entity", text);
1586                     }
1587                 }
1588             }
1589
1590             // Skip characters until predicate evaluates to true
1591             template<class StopPred, int Flags>
1592             static void skip(Ch *&text)
1593             {
1594                 Ch *tmp = text;
1595                 while (StopPred::test(*tmp))
1596                     ++tmp;
1597                 text = tmp;
1598             }
1599
1600             // Skip characters until predicate evaluates to true while doing the following:
1601             // - replacing XML character entity references with proper characters (&apos; &amp; &quot; &lt; &gt; &#...;)
1602             // - condensing whitespace sequences to single space character
1603             template<class StopPred, class StopPredPure, int Flags>
1604             static Ch *skip_and_expand_character_refs(Ch *&text)
1605             {
1606                 // If entity translation, whitespace condense and whitespace trimming is disabled, use plain skip
1607                 if (Flags & parse_no_entity_translation &&
1608                     !(Flags & parse_normalize_whitespace) &&
1609                     !(Flags & parse_trim_whitespace))
1610                 {
1611                     skip<StopPred, Flags>(text);
1612                     return text;
1613                 }
1614
1615                 // Use simple skip until first modification is detected
1616                 skip<StopPredPure, Flags>(text);
1617
1618                 // Use translation skip
1619                 Ch *src = text;
1620                 Ch *dest = src;
1621                 while (StopPred::test(*src))
1622                 {
1623                     // If entity translation is enabled
1624                     if (!(Flags & parse_no_entity_translation))
1625                     {
1626                         // Test if replacement is needed
1627                         if (src[0] == Ch('&'))
1628                         {
1629                             switch (src[1])
1630                             {
1631
1632                                 // &amp; &apos;
1633                                 case Ch('a'):
1634                                     if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';'))
1635                                     {
1636                                         *dest = Ch('&');
1637                                         ++dest;
1638                                         src += 5;
1639                                         continue;
1640                                     }
1641                                     if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s') && src[5] == Ch(';'))
1642                                     {
1643                                         *dest = Ch('\'');
1644                                         ++dest;
1645                                         src += 6;
1646                                         continue;
1647                                     }
1648                                     break;
1649
1650                                 // &quot;
1651                                 case Ch('q'):
1652                                     if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t') && src[5] == Ch(';'))
1653                                     {
1654                                         *dest = Ch('"');
1655                                         ++dest;
1656                                         src += 6;
1657                                         continue;
1658                                     }
1659                                     break;
1660
1661                                 // &gt;
1662                                 case Ch('g'):
1663                                     if (src[2] == Ch('t') && src[3] == Ch(';'))
1664                                     {
1665                                         *dest = Ch('>');
1666                                         ++dest;
1667                                         src += 4;
1668                                         continue;
1669                                     }
1670                                     break;
1671
1672                                 // &lt;
1673                                 case Ch('l'):
1674                                     if (src[2] == Ch('t') && src[3] == Ch(';'))
1675                                     {
1676                                         *dest = Ch('<');
1677                                         ++dest;
1678                                         src += 4;
1679                                         continue;
1680                                     }
1681                                     break;
1682
1683                                 // &#...; - assumes ASCII
1684                                 case Ch('#'):
1685                                     if (src[2] == Ch('x'))
1686                                     {
1687                                         unsigned long code = 0;
1688                                         src += 3;   // Skip &#x
1689                                         while (1)
1690                                         {
1691                                             unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
1692                                             if (digit == 0xFF)
1693                                                 break;
1694                                             code = code * 16 + digit;
1695                                             ++src;
1696                                         }
1697                                         insert_coded_character<Flags>(dest, code);    // Put character in output
1698                                     }
1699                                     else
1700                                     {
1701                                         unsigned long code = 0;
1702                                         src += 2;   // Skip &#
1703                                         while (1)
1704                                         {
1705                                             unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
1706                                             if (digit == 0xFF)
1707                                                 break;
1708                                             code = code * 10 + digit;
1709                                             ++src;
1710                                         }
1711                                         insert_coded_character<Flags>(dest, code);    // Put character in output
1712                                     }
1713                                     if (*src == Ch(';'))
1714                                         ++src;
1715                                     else
1716                                         RAPIDXML_PARSE_ERROR("expected ;", src);
1717                                     continue;
1718
1719                                 // Something else
1720                                 default:
1721                                     // Ignore, just copy '&' verbatim
1722                                     break;
1723
1724                             }
1725                         }
1726                     }
1727
1728                     // If whitespace condensing is enabled
1729                     if (Flags & parse_normalize_whitespace)
1730                     {
1731                         // Test if condensing is needed
1732                         if (whitespace_pred::test(*src))
1733                         {
1734                             *dest = Ch(' '); ++dest;    // Put single space in dest
1735                             ++src;                      // Skip first whitespace char
1736                             // Skip remaining whitespace chars
1737                             while (whitespace_pred::test(*src))
1738                                 ++src;
1739                             continue;
1740                         }
1741                     }
1742
1743                     // No replacement, only copy character
1744                     *dest++ = *src++;
1745
1746                 }
1747
1748                 // Return new end
1749                 text = src;
1750                 return dest;
1751
1752             }
1753
1754             ///////////////////////////////////////////////////////////////////////
1755             // Internal parsing functions
1756
1757             // Parse BOM, if any
1758             template<int Flags>
1759             void parse_bom(Ch *&text)
1760             {
1761                 // UTF-8?
1762                 if (static_cast<unsigned char>(text[0]) == 0xEF &&
1763                     static_cast<unsigned char>(text[1]) == 0xBB &&
1764                     static_cast<unsigned char>(text[2]) == 0xBF)
1765                 {
1766                     text += 3;      // Skup utf-8 bom
1767                 }
1768             }
1769
1770             // Parse XML declaration (<?xml...)
1771             template<int Flags>
1772             xml_node<Ch> *parse_xml_declaration(Ch *&text)
1773             {
1774                 // If parsing of declaration is disabled
1775                 if (!(Flags & parse_declaration_node))
1776                 {
1777                     // Skip until end of declaration
1778                     while (text[0] != Ch('?') || text[1] != Ch('>'))
1779                     {
1780                         if (!text[0])
1781                             RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1782                         ++text;
1783                     }
1784                     text += 2;    // Skip '?>'
1785                     return 0;
1786                 }
1787
1788                 // Create declaration
1789                 xml_node<Ch> *declaration = this->allocate_node(node_declaration);
1790
1791                 // Skip whitespace before attributes or ?>
1792                 skip<whitespace_pred, Flags>(text);
1793
1794                 // Parse declaration attributes
1795                 parse_node_attributes<Flags>(text, declaration);
1796
1797                 // Skip ?>
1798                 if (text[0] != Ch('?') || text[1] != Ch('>'))
1799                     RAPIDXML_PARSE_ERROR("expected ?>", text);
1800                 text += 2;
1801
1802                 return declaration;
1803             }
1804
1805             // Parse XML comment (<!--...)
1806             template<int Flags>
1807             xml_node<Ch> *parse_comment(Ch *&text)
1808             {
1809                 // If parsing of comments is disabled
1810                 if (!(Flags & parse_comment_nodes))
1811                 {
1812                     // Skip until end of comment
1813                     while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>'))
1814                     {
1815                         if (!text[0])
1816                             RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1817                         ++text;
1818                     }
1819                     text += 3;     // Skip '-->'
1820                     return 0;      // Do not produce comment node
1821                 }
1822
1823                 // Remember value start
1824                 Ch *value = text;
1825
1826                 // Skip until end of comment
1827                 while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>'))
1828                 {
1829                     if (!text[0])
1830                         RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1831                     ++text;
1832                 }
1833
1834                 // Create comment node
1835                 xml_node<Ch> *comment = this->allocate_node(node_comment);
1836                 comment->value(value, text - value);
1837
1838                 // Place zero terminator after comment value
1839                 if (!(Flags & parse_no_string_terminators))
1840                     *text = Ch('\0');
1841
1842                 text += 3;     // Skip '-->'
1843                 return comment;
1844             }
1845
1846             // Parse DOCTYPE
1847             template<int Flags>
1848             xml_node<Ch> *parse_doctype(Ch *&text)
1849             {
1850                 // Remember value start
1851                 Ch *value = text;
1852
1853                 // Skip to >
1854                 while (*text != Ch('>'))
1855                 {
1856                     // Determine character type
1857                     switch (*text)
1858                     {
1859
1860                         // If '[' encountered, scan for matching ending ']' using naive algorithm with depth
1861                         // This works for all W3C test files except for 2 most wicked
1862                         case Ch('['):
1863                             {
1864                                 ++text;     // Skip '['
1865                                 int depth = 1;
1866                                 while (depth > 0)
1867                                 {
1868                                     switch (*text)
1869                                     {
1870                                         case Ch('['): ++depth; break;
1871                                         case Ch(']'): --depth; break;
1872                                         case 0: RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1873                                         default: break;
1874                                     }
1875                                     ++text;
1876                                 }
1877                                 break;
1878                             }
1879
1880                         // Error on end of text
1881                         case Ch('\0'):
1882                             RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1883
1884                         // Other character, skip it
1885                         default:
1886                             ++text;
1887
1888                     }
1889                 }
1890
1891                 // If DOCTYPE nodes enabled
1892                 if (Flags & parse_doctype_node)
1893                 {
1894                     // Create a new doctype node
1895                     xml_node<Ch> *doctype = this->allocate_node(node_doctype);
1896                     doctype->value(value, text - value);
1897
1898                     // Place zero terminator after value
1899                     if (!(Flags & parse_no_string_terminators))
1900                         *text = Ch('\0');
1901
1902                     text += 1;      // skip '>'
1903                     return doctype;
1904                 }
1905                 else
1906                 {
1907                     text += 1;      // skip '>'
1908                     return 0;
1909                 }
1910
1911             }
1912
1913             // Parse PI
1914             template<int Flags>
1915             xml_node<Ch> *parse_pi(Ch *&text)
1916             {
1917                 // If creation of PI nodes is enabled
1918                 if (Flags & parse_pi_nodes)
1919                 {
1920                     // Create pi node
1921                     xml_node<Ch> *pi = this->allocate_node(node_pi);
1922
1923                     // Extract PI target name
1924                     Ch *name = text;
1925                     skip<node_name_pred, Flags>(text);
1926                     if (text == name)
1927                         RAPIDXML_PARSE_ERROR("expected PI target", text);
1928                     pi->name(name, text - name);
1929
1930                     // Skip whitespace between pi target and pi
1931                     skip<whitespace_pred, Flags>(text);
1932
1933                     // Remember start of pi
1934                     Ch *value = text;
1935
1936                     // Skip to '?>'
1937                     while (text[0] != Ch('?') || text[1] != Ch('>'))
1938                     {
1939                         if (*text == Ch('\0'))
1940                             RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1941                         ++text;
1942                     }
1943
1944                     // Set pi value (verbatim, no entity expansion or whitespace normalization)
1945                     pi->value(value, text - value);
1946
1947                     // Place zero terminator after name and value
1948                     if (!(Flags & parse_no_string_terminators))
1949                     {
1950                         pi->name()[pi->name_size()] = Ch('\0');
1951                         pi->value()[pi->value_size()] = Ch('\0');
1952                     }
1953
1954                     text += 2;                          // Skip '?>'
1955                     return pi;
1956                 }
1957                 else
1958                 {
1959                     // Skip to '?>'
1960                     while (text[0] != Ch('?') || text[1] != Ch('>'))
1961                     {
1962                         if (*text == Ch('\0'))
1963                             RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1964                         ++text;
1965                     }
1966                     text += 2;    // Skip '?>'
1967                     return 0;
1968                 }
1969             }
1970
1971             // Parse and append data
1972             // Return character that ends data.
1973             // This is necessary because this character might have been overwritten by a terminating 0
1974             template<int Flags>
1975             Ch parse_and_append_data(xml_node<Ch> *node, Ch *&text, Ch *contents_start)
1976             {
1977                 // Backup to contents start if whitespace trimming is disabled
1978                 if (!(Flags & parse_trim_whitespace))
1979                     text = contents_start;
1980
1981                 // Skip until end of data
1982                 Ch *value = text, *end;
1983                 if (Flags & parse_normalize_whitespace)
1984                     end = skip_and_expand_character_refs<text_pred, text_pure_with_ws_pred, Flags>(text);
1985                 else
1986                     end = skip_and_expand_character_refs<text_pred, text_pure_no_ws_pred, Flags>(text);
1987
1988                 // Trim trailing whitespace if flag is set; leading was already trimmed by whitespace skip after >
1989                 if (Flags & parse_trim_whitespace)
1990                 {
1991                     if (Flags & parse_normalize_whitespace)
1992                     {
1993                         // Whitespace is already condensed to single space characters by skipping function, so just trim 1 char off the end
1994                         if (*(end - 1) == Ch(' '))
1995                             --end;
1996                     }
1997                     else
1998                     {
1999                         // Backup until non-whitespace character is found
2000                         while (whitespace_pred::test(*(end - 1)))
2001                             --end;
2002                     }
2003                 }
2004
2005                 // If characters are still left between end and value (this test is only necessary if normalization is enabled)
2006                 // Create new data node
2007                 if (!(Flags & parse_no_data_nodes))
2008                 {
2009                     xml_node<Ch> *data = this->allocate_node(node_data);
2010                     data->value(value, end - value);
2011                     node->append_node(data);
2012                 }
2013
2014                 // Add data to parent node if no data exists yet
2015                 if (!(Flags & parse_no_element_values))
2016                     if (*node->value() == Ch('\0'))
2017                         node->value(value, end - value);
2018
2019                 // Place zero terminator after value
2020                 if (!(Flags & parse_no_string_terminators))
2021                 {
2022                     Ch ch = *text;
2023                     *end = Ch('\0');
2024                     return ch;      // Return character that ends data; this is required because zero terminator overwritten it
2025                 }
2026
2027                 // Return character that ends data
2028                 return *text;
2029             }
2030
2031             // Parse CDATA
2032             template<int Flags>
2033             xml_node<Ch> *parse_cdata(Ch *&text)
2034             {
2035                 // If CDATA is disabled
2036                 if (Flags & parse_no_data_nodes)
2037                 {
2038                     // Skip until end of cdata
2039                     while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>'))
2040                     {
2041                         if (!text[0])
2042                             RAPIDXML_PARSE_ERROR("unexpected end of data", text);
2043                         ++text;
2044                     }
2045                     text += 3;      // Skip ]]>
2046                     return 0;       // Do not produce CDATA node
2047                 }
2048
2049                 // Skip until end of cdata
2050                 Ch *value = text;
2051                 while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>'))
2052                 {
2053                     if (!text[0])
2054                         RAPIDXML_PARSE_ERROR("unexpected end of data", text);
2055                     ++text;
2056                 }
2057
2058                 // Create new cdata node
2059                 xml_node<Ch> *cdata = this->allocate_node(node_cdata);
2060                 cdata->value(value, text - value);
2061
2062                 // Place zero terminator after value
2063                 if (!(Flags & parse_no_string_terminators))
2064                     *text = Ch('\0');
2065
2066                 text += 3;      // Skip ]]>
2067                 return cdata;
2068             }
2069
2070             // Parse element node
2071             template<int Flags>
2072             xml_node<Ch> *parse_element(Ch *&text)
2073             {
2074                 // Create element node
2075                 xml_node<Ch> *element = this->allocate_node(node_element);
2076
2077                 // Extract element name
2078                 Ch *name = text;
2079                 skip<node_name_pred, Flags>(text);
2080                 if (text == name)
2081                     RAPIDXML_PARSE_ERROR("expected element name", text);
2082                 element->name(name, text - name);
2083
2084                 // Skip whitespace between element name and attributes or >
2085                 skip<whitespace_pred, Flags>(text);
2086
2087                 // Parse attributes, if any
2088                 parse_node_attributes<Flags>(text, element);
2089
2090                 // Determine ending type
2091                 if (*text == Ch('>'))
2092                 {
2093                     ++text;
2094                     parse_node_contents<Flags>(text, element);
2095                 }
2096                 else if (*text == Ch('/'))
2097                 {
2098                     ++text;
2099                     if (*text != Ch('>'))
2100                         RAPIDXML_PARSE_ERROR("expected >", text);
2101                     ++text;
2102                 }
2103                 else
2104                     RAPIDXML_PARSE_ERROR("expected >", text);
2105
2106                 // Place zero terminator after name
2107                 if (!(Flags & parse_no_string_terminators))
2108                     element->name()[element->name_size()] = Ch('\0');
2109
2110                 // Return parsed element
2111                 return element;
2112             }
2113
2114             // Determine node type, and parse it
2115             template<int Flags>
2116             xml_node<Ch> *parse_node(Ch *&text)
2117             {
2118                 // Parse proper node type
2119                 switch (text[0])
2120                 {
2121
2122                     // <...
2123                     default:
2124                         // Parse and append element node
2125                         return parse_element<Flags>(text);
2126
2127                     // <?...
2128                     case Ch('?'):
2129                         ++text;     // Skip ?
2130                         if ((text[0] == Ch('x') || text[0] == Ch('X')) &&
2131                             (text[1] == Ch('m') || text[1] == Ch('M')) &&
2132                             (text[2] == Ch('l') || text[2] == Ch('L')) &&
2133                             whitespace_pred::test(text[3]))
2134                         {
2135                             // '<?xml ' - xml declaration
2136                             text += 4;      // Skip 'xml '
2137                             return parse_xml_declaration<Flags>(text);
2138                         }
2139                         else
2140                         {
2141                             // Parse PI
2142                             return parse_pi<Flags>(text);
2143                         }
2144
2145                     // <!...
2146                     case Ch('!'):
2147
2148                         // Parse proper subset of <! node
2149                         switch (text[1])
2150                         {
2151
2152                             // <!-
2153                             case Ch('-'):
2154                                 if (text[2] == Ch('-'))
2155                                 {
2156                                     // '<!--' - xml comment
2157                                     text += 3;     // Skip '!--'
2158                                     return parse_comment<Flags>(text);
2159                                 }
2160                                 break;
2161
2162                             // <![
2163                             case Ch('['):
2164                                 if (text[2] == Ch('C') && text[3] == Ch('D') && text[4] == Ch('A') &&
2165                                     text[5] == Ch('T') && text[6] == Ch('A') && text[7] == Ch('['))
2166                                 {
2167                                     // '<![CDATA[' - cdata
2168                                     text += 8;     // Skip '![CDATA['
2169                                     return parse_cdata<Flags>(text);
2170                                 }
2171                                 break;
2172
2173                             // <!D
2174                             case Ch('D'):
2175                                 if (text[2] == Ch('O') && text[3] == Ch('C') && text[4] == Ch('T') &&
2176                                     text[5] == Ch('Y') && text[6] == Ch('P') && text[7] == Ch('E') &&
2177                                     whitespace_pred::test(text[8]))
2178                                 {
2179                                     // '<!DOCTYPE ' - doctype
2180                                     text += 9;      // skip '!DOCTYPE '
2181                                     return parse_doctype<Flags>(text);
2182                                 }
2183                                 break;
2184
2185                             default:
2186                                 break;
2187
2188                         }   // switch
2189
2190                         // Attempt to skip other, unrecognized node types starting with <!
2191                         ++text;     // Skip !
2192                         while (*text != Ch('>'))
2193                         {
2194                             if (*text == 0)
2195                                 RAPIDXML_PARSE_ERROR("unexpected end of data", text);
2196                             ++text;
2197                         }
2198                         ++text;     // Skip '>'
2199                         return 0;   // No node recognized
2200
2201                 }
2202             }
2203
2204             // Parse contents of the node - children, data etc.
2205             template<int Flags>
2206             void parse_node_contents(Ch *&text, xml_node<Ch> *node)
2207             {
2208                 // For all children and text
2209                 while (1)
2210                 {
2211                     // Skip whitespace between > and node contents
2212                     Ch *contents_start = text;      // Store start of node contents before whitespace is skipped
2213                     skip<whitespace_pred, Flags>(text);
2214                     Ch next_char = *text;
2215
2216                     // After data nodes, instead of continuing the loop, control jumps here.
2217                     // This is because zero termination inside parse_and_append_data() function
2218                     // would wreak havoc with the above code.
2219                     // Also, skipping whitespace after data nodes is unnecessary.
2220 after_data_node:
2221
2222                     // Determine what comes next: node closing, child node, data node, or 0?
2223                     switch (next_char)
2224                     {
2225
2226                         // Node closing or child node
2227                         case Ch('<'):
2228                             if (text[1] == Ch('/'))
2229                             {
2230                                 // Node closing
2231                                 text += 2;      // Skip '</'
2232                                 if (Flags & parse_validate_closing_tags)
2233                                 {
2234                                     // Skip and validate closing tag name
2235                                     Ch *closing_name = text;
2236                                     skip<node_name_pred, Flags>(text);
2237                                     if (!internal::compare(node->name(), node->name_size(), closing_name, text - closing_name, true))
2238                                         RAPIDXML_PARSE_ERROR("invalid closing tag name", text);
2239                                 }
2240                                 else
2241                                 {
2242                                     // No validation, just skip name
2243                                     skip<node_name_pred, Flags>(text);
2244                                 }
2245                                 // Skip remaining whitespace after node name
2246                                 skip<whitespace_pred, Flags>(text);
2247                                 if (*text != Ch('>'))
2248                                     RAPIDXML_PARSE_ERROR("expected >", text);
2249                                 ++text;     // Skip '>'
2250                                 return;     // Node closed, finished parsing contents
2251                             }
2252                             else
2253                             {
2254                                 // Child node
2255                                 ++text;     // Skip '<'
2256                                 if (xml_node<Ch> *child = parse_node<Flags>(text))
2257                                     node->append_node(child);
2258                             }
2259                             break;
2260
2261                         // End of data - error
2262                         case Ch('\0'):
2263                             RAPIDXML_PARSE_ERROR("unexpected end of data", text);
2264
2265                         // Data node
2266                         default:
2267                             next_char = parse_and_append_data<Flags>(node, text, contents_start);
2268                             goto after_data_node;   // Bypass regular processing after data nodes
2269
2270                     }
2271                 }
2272             }
2273
2274             // Parse XML attributes of the node
2275             template<int Flags>
2276             void parse_node_attributes(Ch *&text, xml_node<Ch> *node)
2277             {
2278                 // For all attributes
2279                 while (attribute_name_pred::test(*text))
2280                 {
2281                     // Extract attribute name
2282                     Ch *name = text;
2283                     ++text;     // Skip first character of attribute name
2284                     skip<attribute_name_pred, Flags>(text);
2285                     if (text == name)
2286                         RAPIDXML_PARSE_ERROR("expected attribute name", name);
2287
2288                     // Create new attribute
2289                     xml_attribute<Ch> *attribute = this->allocate_attribute();
2290                     attribute->name(name, text - name);
2291                     node->append_attribute(attribute);
2292
2293                     // Skip whitespace after attribute name
2294                     skip<whitespace_pred, Flags>(text);
2295
2296                     // Skip =
2297                     if (*text != Ch('='))
2298                         RAPIDXML_PARSE_ERROR("expected =", text);
2299                     ++text;
2300
2301                     // Add terminating zero after name
2302                     if (!(Flags & parse_no_string_terminators))
2303                         attribute->name()[attribute->name_size()] = 0;
2304
2305                     // Skip whitespace after =
2306                     skip<whitespace_pred, Flags>(text);
2307
2308                     // Skip quote and remember if it was ' or "
2309                     Ch quote = *text;
2310                     if (quote != Ch('\'') && quote != Ch('"'))
2311                         RAPIDXML_PARSE_ERROR("expected ' or \"", text);
2312                     ++text;
2313
2314                     // Extract attribute value and expand char refs in it
2315                     Ch *value = text, *end;
2316                     const int AttFlags = Flags &
2317                                          ~parse_normalize_whitespace;   // No whitespace normalization in attributes
2318                     if (quote == Ch('\''))
2319                         end = skip_and_expand_character_refs<attribute_value_pred<Ch('\'')>, attribute_value_pure_pred<Ch('\'')>, AttFlags>
2320                               (text);
2321                     else
2322                         end = skip_and_expand_character_refs<attribute_value_pred<Ch('"')>, attribute_value_pure_pred<Ch('"')>, AttFlags>
2323                               (text);
2324
2325                     // Set attribute value
2326                     attribute->value(value, end - value);
2327
2328                     // Make sure that end quote is present
2329                     if (*text != quote)
2330                         RAPIDXML_PARSE_ERROR("expected ' or \"", text);
2331                     ++text;     // Skip quote
2332
2333                     // Add terminating zero after value
2334                     if (!(Flags & parse_no_string_terminators))
2335                         attribute->value()[attribute->value_size()] = 0;
2336
2337                     // Skip whitespace after attribute value
2338                     skip<whitespace_pred, Flags>(text);
2339                 }
2340             }
2341
2342     };
2343
2344     //! \cond internal
2345     namespace internal
2346     {
2347
2348         // Whitespace (space \n \r \t)
2349         template<int Dummy>
2350         const unsigned char lookup_tables<Dummy>::lookup_whitespace[256] =
2351         {
2352             // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
2353             0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  1,  0,  0,  // 0
2354             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 1
2355             1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 2
2356             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 3
2357             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 4
2358             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 5
2359             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 6
2360             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 7
2361             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 8
2362             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // 9
2363             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // A
2364             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // B
2365             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // C
2366             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // D
2367             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  // E
2368             0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0   // F
2369         };
2370
2371         // Node name (anything but space \n \r \t / > ? \0)
2372         template<int Dummy>
2373         const unsigned char lookup_tables<Dummy>::lookup_node_name[256] =
2374         {
2375             // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
2376             0,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  1,  1,  0,  1,  1,  // 0
2377             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
2378             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  // 2
2379             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  // 3
2380             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
2381             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
2382             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
2383             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
2384             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
2385             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
2386             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
2387             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
2388             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
2389             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
2390             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
2391             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
2392         };
2393
2394         // Text (i.e. PCDATA) (anything but < \0)
2395         template<int Dummy>
2396         const unsigned char lookup_tables<Dummy>::lookup_text[256] =
2397         {
2398             // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
2399             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 0
2400             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
2401             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
2402             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  // 3
2403             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
2404             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
2405             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
2406             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
2407             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
2408             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
2409             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
2410             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
2411             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
2412             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
2413             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
2414             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
2415         };
2416
2417         // Text (i.e. PCDATA) that does not require processing when ws normalization is disabled
2418         // (anything but < \0 &)
2419         template<int Dummy>
2420         const unsigned char lookup_tables<Dummy>::lookup_text_pure_no_ws[256] =
2421         {
2422             // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
2423             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 0
2424             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
2425             1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
2426             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  // 3
2427             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
2428             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
2429             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
2430             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
2431             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
2432             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
2433             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
2434             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
2435             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
2436             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
2437             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
2438             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
2439         };
2440
2441         // Text (i.e. PCDATA) that does not require processing when ws normalizationis is enabled
2442         // (anything but < \0 & space \n \r \t)
2443         template<int Dummy>
2444         const unsigned char lookup_tables<Dummy>::lookup_text_pure_with_ws[256] =
2445         {
2446             // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
2447             0,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  1,  1,  0,  1,  1,  // 0
2448             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
2449             0,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
2450             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  // 3
2451             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
2452             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
2453             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
2454             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
2455             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
2456             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
2457             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
2458             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
2459             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
2460             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
2461             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
2462             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
2463         };
2464
2465         // Attribute name (anything but space \n \r \t / < > = ? ! \0)
2466         template<int Dummy>
2467         const unsigned char lookup_tables<Dummy>::lookup_attribute_name[256] =
2468         {
2469             // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
2470             0,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  1,  1,  0,  1,  1,  // 0
2471             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
2472             0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  // 2
2473             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  // 3
2474             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
2475             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
2476             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
2477             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
2478             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
2479             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
2480             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
2481             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
2482             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
2483             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
2484             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
2485             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
2486         };
2487
2488         // Attribute data with single quote (anything but ' \0)
2489         template<int Dummy>
2490         const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1[256] =
2491         {
2492             // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
2493             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 0
2494             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
2495             1,  1,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
2496             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 3
2497             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
2498             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
2499             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
2500             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
2501             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
2502             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
2503             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
2504             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
2505             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
2506             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
2507             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
2508             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
2509         };
2510
2511         // Attribute data with single quote that does not require processing (anything but ' \0 &)
2512         template<int Dummy>
2513         const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1_pure[256] =
2514         {
2515             // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
2516             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 0
2517             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
2518             1,  1,  1,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
2519             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 3
2520             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
2521             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
2522             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
2523             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
2524             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
2525             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
2526             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
2527             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
2528             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
2529             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
2530             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
2531             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
2532         };
2533
2534         // Attribute data with double quote (anything but " \0)
2535         template<int Dummy>
2536         const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2[256] =
2537         {
2538             // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
2539             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 0
2540             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
2541             1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
2542             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 3
2543             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
2544             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
2545             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
2546             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
2547             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
2548             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
2549             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
2550             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
2551             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
2552             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
2553             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
2554             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
2555         };
2556
2557         // Attribute data with double quote that does not require processing (anything but " \0 &)
2558         template<int Dummy>
2559         const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2_pure[256] =
2560         {
2561             // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
2562             0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 0
2563             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 1
2564             1,  1,  0,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 2
2565             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 3
2566             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 4
2567             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 5
2568             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 6
2569             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 7
2570             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 8
2571             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // 9
2572             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // A
2573             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // B
2574             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // C
2575             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // D
2576             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  // E
2577             1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1   // F
2578         };
2579
2580         // Digits (dec and hex, 255 denotes end of numeric character reference)
2581         template<int Dummy>
2582         const unsigned char lookup_tables<Dummy>::lookup_digits[256] =
2583         {
2584             // 0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
2585             255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 0
2586             255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 1
2587             255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 2
2588             0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 255, 255, 255, 255, 255, 255, // 3
2589             255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 4
2590             255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 5
2591             255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 6
2592             255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 7
2593             255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 8
2594             255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 9
2595             255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // A
2596             255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // B
2597             255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // C
2598             255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // D
2599             255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // E
2600             255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 // F
2601         };
2602
2603         // Upper case conversion
2604         template<int Dummy>
2605         const unsigned char lookup_tables<Dummy>::lookup_upcase[256] =
2606         {
2607             // 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  A   B   C   D   E   F
2608             0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,   // 0
2609             16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,   // 1
2610             32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,   // 2
2611             48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,   // 3
2612             64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,   // 4
2613             80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,   // 5
2614             96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,   // 6
2615             80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127, // 7
2616             128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, // 8
2617             144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, // 9
2618             160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, // A
2619             176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, // B
2620             192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, // C
2621             208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, // D
2622             224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, // E
2623             240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 // F
2624         };
2625     }
2626     //! \endcond
2627
2628 }
2629
2630 // Undefine internal macros
2631 #undef RAPIDXML_PARSE_ERROR
2632
2633 // On MSVC, restore warnings state
2634 #ifdef _MSC_VER
2635 #pragma warning(pop)
2636 #endif
2637
2638 #endif