rapidxml.hpp 97 KB

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