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