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