File indexing completed on 2025-01-18 09:50:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_PROPERTY_TREE_RAPIDXML_HPP_INCLUDED
0011 #define BOOST_PROPERTY_TREE_RAPIDXML_HPP_INCLUDED
0012
0013
0014
0015 #include <boost/config.hpp>
0016 #include <boost/assert.hpp>
0017 #include <cstddef> // For std::size_t
0018 #include <new> // For placement new
0019
0020
0021
0022 #ifdef _MSC_VER
0023 #pragma warning(push)
0024 #pragma warning(disable:4127)
0025 #endif
0026
0027
0028
0029
0030 #include <exception> // For std::exception
0031
0032 #define BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where)
0033
0034 namespace boost { namespace property_tree { namespace detail {namespace rapidxml
0035 {
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 class parse_error: public std::exception
0049 {
0050
0051 public:
0052
0053
0054 parse_error(const char *wa, void *we)
0055 : m_what(wa)
0056 , m_where(we)
0057 {
0058 }
0059
0060
0061
0062 const char *what() const throw() BOOST_OVERRIDE
0063 {
0064 return m_what;
0065 }
0066
0067
0068
0069
0070 template<class Ch>
0071 Ch *where() const
0072 {
0073 return reinterpret_cast<Ch *>(m_where);
0074 }
0075
0076 private:
0077
0078 const char *m_what;
0079 void *m_where;
0080
0081 };
0082 }}}}
0083
0084
0085
0086
0087 #ifndef BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE
0088
0089
0090
0091 #define BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE (64 * 1024)
0092 #endif
0093
0094 #ifndef BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE
0095
0096
0097
0098 #define BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024)
0099 #endif
0100
0101 #ifndef BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT
0102
0103
0104
0105
0106 #define BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT sizeof(void *)
0107 #endif
0108
0109 namespace boost { namespace property_tree { namespace detail {namespace rapidxml
0110 {
0111
0112 template<class Ch> class xml_node;
0113 template<class Ch> class xml_attribute;
0114 template<class Ch> class xml_document;
0115
0116
0117
0118 enum node_type
0119 {
0120 node_document,
0121 node_element,
0122 node_data,
0123 node_cdata,
0124 node_comment,
0125 node_declaration,
0126 node_doctype,
0127 node_pi
0128 };
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138 const int parse_no_data_nodes = 0x1;
0139
0140
0141
0142
0143
0144
0145
0146
0147 const int parse_no_element_values = 0x2;
0148
0149
0150
0151
0152
0153
0154 const int parse_no_string_terminators = 0x4;
0155
0156
0157
0158
0159
0160
0161 const int parse_no_entity_translation = 0x8;
0162
0163
0164
0165
0166
0167
0168 const int parse_no_utf8 = 0x10;
0169
0170
0171
0172
0173
0174
0175 const int parse_declaration_node = 0x20;
0176
0177
0178
0179
0180
0181
0182 const int parse_comment_nodes = 0x40;
0183
0184
0185
0186
0187
0188
0189
0190 const int parse_doctype_node = 0x80;
0191
0192
0193
0194
0195
0196
0197 const int parse_pi_nodes = 0x100;
0198
0199
0200
0201
0202
0203
0204
0205 const int parse_validate_closing_tags = 0x200;
0206
0207
0208
0209
0210
0211
0212
0213 const int parse_trim_whitespace = 0x400;
0214
0215
0216
0217
0218
0219
0220
0221
0222 const int parse_normalize_whitespace = 0x800;
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234 const int parse_default = 0;
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244 const int parse_non_destructive = parse_no_string_terminators | parse_no_entity_translation;
0245
0246
0247
0248
0249 const int parse_fastest = parse_non_destructive | parse_no_data_nodes;
0250
0251
0252
0253
0254
0255 const int parse_full = parse_declaration_node | parse_comment_nodes | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags;
0256
0257
0258
0259
0260
0261 namespace internal
0262 {
0263
0264
0265
0266 template<int Dummy>
0267 struct lookup_tables
0268 {
0269 static const unsigned char lookup_whitespace[256];
0270 static const unsigned char lookup_node_name[256];
0271 static const unsigned char lookup_text[256];
0272 static const unsigned char lookup_text_pure_no_ws[256];
0273 static const unsigned char lookup_text_pure_with_ws[256];
0274 static const unsigned char lookup_attribute_name[256];
0275 static const unsigned char lookup_attribute_data_1[256];
0276 static const unsigned char lookup_attribute_data_1_pure[256];
0277 static const unsigned char lookup_attribute_data_2[256];
0278 static const unsigned char lookup_attribute_data_2_pure[256];
0279 static const unsigned char lookup_digits[256];
0280 static const unsigned char lookup_upcase[256];
0281 };
0282
0283
0284 template<class Ch>
0285 inline std::size_t measure(const Ch *p)
0286 {
0287 const Ch *tmp = p;
0288 while (*tmp)
0289 ++tmp;
0290 return tmp - p;
0291 }
0292
0293
0294 template<class Ch>
0295 inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2, std::size_t size2, bool case_sensitive)
0296 {
0297 if (size1 != size2)
0298 return false;
0299 if (case_sensitive)
0300 {
0301 for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
0302 if (*p1 != *p2)
0303 return false;
0304 }
0305 else
0306 {
0307 for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
0308 if (lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p1)] != lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p2)])
0309 return false;
0310 }
0311 return true;
0312 }
0313
0314 template<class Ch>
0315 inline size_t get_index(const Ch c)
0316 {
0317
0318
0319 unsigned n = c;
0320 if (n > 127)
0321 {
0322 return 'z';
0323 }
0324 return c;
0325 }
0326 }
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366 template<class Ch = char>
0367 class memory_pool
0368 {
0369
0370 public:
0371
0372
0373
0374 typedef void *(boost_ptree_raw_alloc_func)(std::size_t);
0375 typedef void (boost_ptree_raw_free_func)(void *);
0376
0377
0378
0379 memory_pool()
0380 : m_alloc_func(0)
0381 , m_free_func(0)
0382 {
0383 init();
0384 }
0385
0386
0387
0388
0389 ~memory_pool()
0390 {
0391 clear();
0392 }
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404 xml_node<Ch> *allocate_node(node_type type,
0405 const Ch *name = 0, const Ch *value = 0,
0406 std::size_t name_size = 0, std::size_t value_size = 0)
0407 {
0408 void *memory = allocate_aligned(sizeof(xml_node<Ch>));
0409 xml_node<Ch> *node = new(memory) xml_node<Ch>(type);
0410 if (name)
0411 {
0412 if (name_size > 0)
0413 node->name(name, name_size);
0414 else
0415 node->name(name);
0416 }
0417 if (value)
0418 {
0419 if (value_size > 0)
0420 node->value(value, value_size);
0421 else
0422 node->value(value);
0423 }
0424 return node;
0425 }
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436 xml_attribute<Ch> *allocate_attribute(const Ch *name = 0, const Ch *value = 0,
0437 std::size_t name_size = 0, std::size_t value_size = 0)
0438 {
0439 void *memory = allocate_aligned(sizeof(xml_attribute<Ch>));
0440 xml_attribute<Ch> *attribute = new(memory) xml_attribute<Ch>;
0441 if (name)
0442 {
0443 if (name_size > 0)
0444 attribute->name(name, name_size);
0445 else
0446 attribute->name(name);
0447 }
0448 if (value)
0449 {
0450 if (value_size > 0)
0451 attribute->value(value, value_size);
0452 else
0453 attribute->value(value);
0454 }
0455 return attribute;
0456 }
0457
0458
0459
0460
0461
0462
0463
0464
0465 Ch *allocate_string(const Ch *source = 0, std::size_t size = 0)
0466 {
0467 BOOST_ASSERT(source || size);
0468 if (size == 0)
0469 size = internal::measure(source) + 1;
0470 Ch *result = static_cast<Ch *>(allocate_aligned(size * sizeof(Ch)));
0471 if (source)
0472 for (std::size_t i = 0; i < size; ++i)
0473 result[i] = source[i];
0474 return result;
0475 }
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486 xml_node<Ch> *clone_node(const xml_node<Ch> *source, xml_node<Ch> *result = 0)
0487 {
0488
0489 if (result)
0490 {
0491 result->remove_all_attributes();
0492 result->remove_all_nodes();
0493 result->type(source->type());
0494 }
0495 else
0496 result = allocate_node(source->type());
0497
0498
0499 result->name(source->name(), source->name_size());
0500 result->value(source->value(), source->value_size());
0501
0502
0503 for (xml_node<Ch> *child = source->first_node(); child; child = child->next_sibling())
0504 result->append_node(clone_node(child));
0505 for (xml_attribute<Ch> *attr = source->first_attribute(); attr; attr = attr->next_attribute())
0506 result->append_attribute(allocate_attribute(attr->name(), attr->value(), attr->name_size(), attr->value_size()));
0507
0508 return result;
0509 }
0510
0511
0512
0513
0514 void clear()
0515 {
0516 while (m_begin != m_static_memory)
0517 {
0518 char *previous_begin = reinterpret_cast<header *>(align(m_begin))->previous_begin;
0519 if (m_free_func)
0520 m_free_func(m_begin);
0521 else
0522 delete[] m_begin;
0523 m_begin = previous_begin;
0524 }
0525 init();
0526 }
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541 void set_allocator(boost_ptree_raw_alloc_func *af, boost_ptree_raw_free_func *ff)
0542 {
0543 BOOST_ASSERT(m_begin == m_static_memory && m_ptr == align(m_begin));
0544 m_alloc_func = af;
0545 m_free_func = ff;
0546 }
0547
0548 private:
0549
0550 struct header
0551 {
0552 char *previous_begin;
0553 };
0554
0555 void init()
0556 {
0557 m_begin = m_static_memory;
0558 m_ptr = align(m_begin);
0559 m_end = m_static_memory + sizeof(m_static_memory);
0560 }
0561
0562 char *align(char *ptr)
0563 {
0564 std::size_t alignment = ((BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - (std::size_t(ptr) & (BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - 1))) & (BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - 1));
0565 return ptr + alignment;
0566 }
0567
0568 char *allocate_raw(std::size_t size)
0569 {
0570
0571 void *memory;
0572 if (m_alloc_func)
0573 {
0574 memory = m_alloc_func(size);
0575 BOOST_ASSERT(memory);
0576 }
0577 else
0578 {
0579 memory = new char[size];
0580 }
0581 return static_cast<char *>(memory);
0582 }
0583
0584 void *allocate_aligned(std::size_t size)
0585 {
0586
0587 char *result = align(m_ptr);
0588
0589
0590 if (result + size > m_end)
0591 {
0592
0593 std::size_t pool_size = BOOST_PROPERTY_TREE_RAPIDXML_DYNAMIC_POOL_SIZE;
0594 if (pool_size < size)
0595 pool_size = size;
0596
0597
0598 std::size_t alloc_size = sizeof(header) + (2 * BOOST_PROPERTY_TREE_RAPIDXML_ALIGNMENT - 2) + pool_size;
0599 char *raw_memory = allocate_raw(alloc_size);
0600
0601
0602 char *pool = align(raw_memory);
0603 header *new_header = reinterpret_cast<header *>(pool);
0604 new_header->previous_begin = m_begin;
0605 m_begin = raw_memory;
0606 m_ptr = pool + sizeof(header);
0607 m_end = raw_memory + alloc_size;
0608
0609
0610 result = align(m_ptr);
0611 }
0612
0613
0614 m_ptr = result + size;
0615 return result;
0616 }
0617
0618 char *m_begin;
0619 char *m_ptr;
0620 char *m_end;
0621 char m_static_memory[BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE];
0622 boost_ptree_raw_alloc_func *m_alloc_func;
0623 boost_ptree_raw_free_func *m_free_func;
0624 };
0625
0626
0627
0628
0629
0630
0631
0632 template<class Ch = char>
0633 class xml_base
0634 {
0635
0636 public:
0637
0638
0639
0640
0641
0642 xml_base()
0643 : m_name(0)
0644 , m_value(0)
0645 , m_parent(0)
0646 {
0647 }
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658 Ch *name() const
0659 {
0660 return m_name ? m_name : nullstr();
0661 }
0662
0663
0664
0665
0666 std::size_t name_size() const
0667 {
0668 return m_name ? m_name_size : 0;
0669 }
0670
0671
0672
0673
0674
0675
0676
0677 Ch *value() const
0678 {
0679 return m_value ? m_value : nullstr();
0680 }
0681
0682
0683
0684
0685 std::size_t value_size() const
0686 {
0687 return m_value ? m_value_size : 0;
0688 }
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706 void name(const Ch *n, std::size_t size)
0707 {
0708 m_name = const_cast<Ch *>(n);
0709 m_name_size = size;
0710 }
0711
0712
0713
0714
0715 void name(const Ch *n)
0716 {
0717 name(n, internal::measure(n));
0718 }
0719
0720
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736 void value(const Ch *val, std::size_t size)
0737 {
0738 m_value = const_cast<Ch *>(val);
0739 m_value_size = size;
0740 }
0741
0742
0743
0744
0745 void value(const Ch *val)
0746 {
0747 this->value(val, internal::measure(val));
0748 }
0749
0750
0751
0752
0753
0754
0755 xml_node<Ch> *parent() const
0756 {
0757 return m_parent;
0758 }
0759
0760 protected:
0761
0762
0763 static Ch *nullstr()
0764 {
0765 static Ch zero = Ch('\0');
0766 return &zero;
0767 }
0768
0769 Ch *m_name;
0770 Ch *m_value;
0771 std::size_t m_name_size;
0772 std::size_t m_value_size;
0773 xml_node<Ch> *m_parent;
0774
0775 };
0776
0777
0778
0779
0780
0781
0782 template<class Ch = char>
0783 class xml_attribute: public xml_base<Ch>
0784 {
0785
0786 friend class xml_node<Ch>;
0787
0788 public:
0789
0790
0791
0792
0793
0794
0795 xml_attribute()
0796 {
0797 }
0798
0799
0800
0801
0802
0803
0804 xml_document<Ch> *document() const
0805 {
0806 if (xml_node<Ch> *node = this->parent())
0807 {
0808 while (node->parent())
0809 node = node->parent();
0810 return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0;
0811 }
0812 else
0813 return 0;
0814 }
0815
0816
0817
0818
0819
0820
0821 xml_attribute<Ch> *previous_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
0822 {
0823 if (n)
0824 {
0825 if (nsize == 0)
0826 nsize = internal::measure(n);
0827 for (xml_attribute<Ch> *attribute = m_prev_attribute; attribute; attribute = attribute->m_prev_attribute)
0828 if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive))
0829 return attribute;
0830 return 0;
0831 }
0832 else
0833 return this->m_parent ? m_prev_attribute : 0;
0834 }
0835
0836
0837
0838
0839
0840
0841 xml_attribute<Ch> *next_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
0842 {
0843 if (n)
0844 {
0845 if (nsize == 0)
0846 nsize = internal::measure(n);
0847 for (xml_attribute<Ch> *attribute = m_next_attribute; attribute; attribute = attribute->m_next_attribute)
0848 if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive))
0849 return attribute;
0850 return 0;
0851 }
0852 else
0853 return this->m_parent ? m_next_attribute : 0;
0854 }
0855
0856 private:
0857
0858 xml_attribute<Ch> *m_prev_attribute;
0859 xml_attribute<Ch> *m_next_attribute;
0860
0861 };
0862
0863
0864
0865
0866
0867
0868
0869
0870
0871
0872
0873
0874 template<class Ch = char>
0875 class xml_node: public xml_base<Ch>
0876 {
0877
0878 public:
0879
0880
0881
0882
0883
0884
0885
0886 xml_node(node_type t)
0887 : m_type(t)
0888 , m_first_node(0)
0889 , m_first_attribute(0)
0890 {
0891 }
0892
0893
0894
0895
0896
0897
0898 node_type type() const
0899 {
0900 return m_type;
0901 }
0902
0903
0904
0905
0906
0907
0908 xml_document<Ch> *document() const
0909 {
0910 xml_node<Ch> *node = const_cast<xml_node<Ch> *>(this);
0911 while (node->parent())
0912 node = node->parent();
0913 return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0;
0914 }
0915
0916
0917
0918
0919
0920
0921 xml_node<Ch> *first_node(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
0922 {
0923 if (n)
0924 {
0925 if (nsize == 0)
0926 nsize = internal::measure(n);
0927 for (xml_node<Ch> *child = m_first_node; child; child = child->next_sibling())
0928 if (internal::compare(child->name(), child->name_size(), n, nsize, case_sensitive))
0929 return child;
0930 return 0;
0931 }
0932 else
0933 return m_first_node;
0934 }
0935
0936
0937
0938
0939
0940
0941
0942
0943 xml_node<Ch> *last_node(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
0944 {
0945 BOOST_ASSERT(m_first_node);
0946 if (n)
0947 {
0948 if (nsize == 0)
0949 nsize = internal::measure(n);
0950 for (xml_node<Ch> *child = m_last_node; child; child = child->previous_sibling())
0951 if (internal::compare(child->name(), child->name_size(), n, nsize, case_sensitive))
0952 return child;
0953 return 0;
0954 }
0955 else
0956 return m_last_node;
0957 }
0958
0959
0960
0961
0962
0963
0964
0965
0966 xml_node<Ch> *previous_sibling(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
0967 {
0968 BOOST_ASSERT(this->m_parent);
0969 if (n)
0970 {
0971 if (nsize == 0)
0972 nsize = internal::measure(n);
0973 for (xml_node<Ch> *sibling = m_prev_sibling; sibling; sibling = sibling->m_prev_sibling)
0974 if (internal::compare(sibling->name(), sibling->name_size(), n, nsize, case_sensitive))
0975 return sibling;
0976 return 0;
0977 }
0978 else
0979 return m_prev_sibling;
0980 }
0981
0982
0983
0984
0985
0986
0987
0988
0989 xml_node<Ch> *next_sibling(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
0990 {
0991 BOOST_ASSERT(this->m_parent);
0992 if (n)
0993 {
0994 if (nsize == 0)
0995 nsize = internal::measure(n);
0996 for (xml_node<Ch> *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling)
0997 if (internal::compare(sibling->name(), sibling->name_size(), n, nsize, case_sensitive))
0998 return sibling;
0999 return 0;
1000 }
1001 else
1002 return m_next_sibling;
1003 }
1004
1005
1006
1007
1008
1009
1010 xml_attribute<Ch> *first_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
1011 {
1012 if (n)
1013 {
1014 if (nsize == 0)
1015 nsize = internal::measure(n);
1016 for (xml_attribute<Ch> *attribute = m_first_attribute; attribute; attribute = attribute->m_next_attribute)
1017 if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive))
1018 return attribute;
1019 return 0;
1020 }
1021 else
1022 return m_first_attribute;
1023 }
1024
1025
1026
1027
1028
1029
1030 xml_attribute<Ch> *last_attribute(const Ch *n = 0, std::size_t nsize = 0, bool case_sensitive = true) const
1031 {
1032 if (n)
1033 {
1034 if (nsize == 0)
1035 nsize = internal::measure(n);
1036 for (xml_attribute<Ch> *attribute = m_last_attribute; attribute; attribute = attribute->m_prev_attribute)
1037 if (internal::compare(attribute->name(), attribute->name_size(), n, nsize, case_sensitive))
1038 return attribute;
1039 return 0;
1040 }
1041 else
1042 return m_first_attribute ? m_last_attribute : 0;
1043 }
1044
1045
1046
1047
1048
1049
1050 void type(node_type t)
1051 {
1052 m_type = t;
1053 }
1054
1055
1056
1057
1058
1059
1060
1061 void prepend_node(xml_node<Ch> *child)
1062 {
1063 BOOST_ASSERT(child && !child->parent() && child->type() != node_document);
1064 if (first_node())
1065 {
1066 child->m_next_sibling = m_first_node;
1067 m_first_node->m_prev_sibling = child;
1068 }
1069 else
1070 {
1071 child->m_next_sibling = 0;
1072 m_last_node = child;
1073 }
1074 m_first_node = child;
1075 child->m_parent = this;
1076 child->m_prev_sibling = 0;
1077 }
1078
1079
1080
1081
1082 void append_node(xml_node<Ch> *child)
1083 {
1084 BOOST_ASSERT(child && !child->parent() && child->type() != node_document);
1085 if (first_node())
1086 {
1087 child->m_prev_sibling = m_last_node;
1088 m_last_node->m_next_sibling = child;
1089 }
1090 else
1091 {
1092 child->m_prev_sibling = 0;
1093 m_first_node = child;
1094 }
1095 m_last_node = child;
1096 child->m_parent = this;
1097 child->m_next_sibling = 0;
1098 }
1099
1100
1101
1102
1103
1104 void insert_node(xml_node<Ch> *where, xml_node<Ch> *child)
1105 {
1106 BOOST_ASSERT(!where || where->parent() == this);
1107 BOOST_ASSERT(child && !child->parent() && child->type() != node_document);
1108 if (where == m_first_node)
1109 prepend_node(child);
1110 else if (where == 0)
1111 append_node(child);
1112 else
1113 {
1114 child->m_prev_sibling = where->m_prev_sibling;
1115 child->m_next_sibling = where;
1116 where->m_prev_sibling->m_next_sibling = child;
1117 where->m_prev_sibling = child;
1118 child->m_parent = this;
1119 }
1120 }
1121
1122
1123
1124
1125 void remove_first_node()
1126 {
1127 BOOST_ASSERT(first_node());
1128 xml_node<Ch> *child = m_first_node;
1129 m_first_node = child->m_next_sibling;
1130 if (child->m_next_sibling)
1131 child->m_next_sibling->m_prev_sibling = 0;
1132 else
1133 m_last_node = 0;
1134 child->m_parent = 0;
1135 }
1136
1137
1138
1139
1140 void remove_last_node()
1141 {
1142 BOOST_ASSERT(first_node());
1143 xml_node<Ch> *child = m_last_node;
1144 if (child->m_prev_sibling)
1145 {
1146 m_last_node = child->m_prev_sibling;
1147 child->m_prev_sibling->m_next_sibling = 0;
1148 }
1149 else
1150 m_first_node = 0;
1151 child->m_parent = 0;
1152 }
1153
1154
1155
1156 void remove_node(xml_node<Ch> *where)
1157 {
1158 BOOST_ASSERT(where && where->parent() == this);
1159 BOOST_ASSERT(first_node());
1160 if (where == m_first_node)
1161 remove_first_node();
1162 else if (where == m_last_node)
1163 remove_last_node();
1164 else
1165 {
1166 where->m_prev_sibling->m_next_sibling = where->m_next_sibling;
1167 where->m_next_sibling->m_prev_sibling = where->m_prev_sibling;
1168 where->m_parent = 0;
1169 }
1170 }
1171
1172
1173 void remove_all_nodes()
1174 {
1175 for (xml_node<Ch> *node = first_node(); node; node = node->m_next_sibling)
1176 node->m_parent = 0;
1177 m_first_node = 0;
1178 }
1179
1180
1181
1182 void prepend_attribute(xml_attribute<Ch> *attribute)
1183 {
1184 BOOST_ASSERT(attribute && !attribute->parent());
1185 if (first_attribute())
1186 {
1187 attribute->m_next_attribute = m_first_attribute;
1188 m_first_attribute->m_prev_attribute = attribute;
1189 }
1190 else
1191 {
1192 attribute->m_next_attribute = 0;
1193 m_last_attribute = attribute;
1194 }
1195 m_first_attribute = attribute;
1196 attribute->m_parent = this;
1197 attribute->m_prev_attribute = 0;
1198 }
1199
1200
1201
1202 void append_attribute(xml_attribute<Ch> *attribute)
1203 {
1204 BOOST_ASSERT(attribute && !attribute->parent());
1205 if (first_attribute())
1206 {
1207 attribute->m_prev_attribute = m_last_attribute;
1208 m_last_attribute->m_next_attribute = attribute;
1209 }
1210 else
1211 {
1212 attribute->m_prev_attribute = 0;
1213 m_first_attribute = attribute;
1214 }
1215 m_last_attribute = attribute;
1216 attribute->m_parent = this;
1217 attribute->m_next_attribute = 0;
1218 }
1219
1220
1221
1222
1223
1224 void insert_attribute(xml_attribute<Ch> *where, xml_attribute<Ch> *attribute)
1225 {
1226 BOOST_ASSERT(!where || where->parent() == this);
1227 BOOST_ASSERT(attribute && !attribute->parent());
1228 if (where == m_first_attribute)
1229 prepend_attribute(attribute);
1230 else if (where == 0)
1231 append_attribute(attribute);
1232 else
1233 {
1234 attribute->m_prev_attribute = where->m_prev_attribute;
1235 attribute->m_next_attribute = where;
1236 where->m_prev_attribute->m_next_attribute = attribute;
1237 where->m_prev_attribute = attribute;
1238 attribute->m_parent = this;
1239 }
1240 }
1241
1242
1243
1244
1245 void remove_first_attribute()
1246 {
1247 BOOST_ASSERT(first_attribute());
1248 xml_attribute<Ch> *attribute = m_first_attribute;
1249 if (attribute->m_next_attribute)
1250 {
1251 attribute->m_next_attribute->m_prev_attribute = 0;
1252 }
1253 else
1254 m_last_attribute = 0;
1255 attribute->m_parent = 0;
1256 m_first_attribute = attribute->m_next_attribute;
1257 }
1258
1259
1260
1261
1262 void remove_last_attribute()
1263 {
1264 BOOST_ASSERT(first_attribute());
1265 xml_attribute<Ch> *attribute = m_last_attribute;
1266 if (attribute->m_prev_attribute)
1267 {
1268 attribute->m_prev_attribute->m_next_attribute = 0;
1269 m_last_attribute = attribute->m_prev_attribute;
1270 }
1271 else
1272 m_first_attribute = 0;
1273 attribute->m_parent = 0;
1274 }
1275
1276
1277
1278 void remove_attribute(xml_attribute<Ch> *where)
1279 {
1280 BOOST_ASSERT(first_attribute() && where->parent() == this);
1281 if (where == m_first_attribute)
1282 remove_first_attribute();
1283 else if (where == m_last_attribute)
1284 remove_last_attribute();
1285 else
1286 {
1287 where->m_prev_attribute->m_next_attribute = where->m_next_attribute;
1288 where->m_next_attribute->m_prev_attribute = where->m_prev_attribute;
1289 where->m_parent = 0;
1290 }
1291 }
1292
1293
1294 void remove_all_attributes()
1295 {
1296 for (xml_attribute<Ch> *attribute = first_attribute(); attribute; attribute = attribute->m_next_attribute)
1297 attribute->m_parent = 0;
1298 m_first_attribute = 0;
1299 }
1300
1301 private:
1302
1303
1304
1305
1306
1307 xml_node(const xml_node &);
1308 void operator =(const xml_node &);
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322 node_type m_type;
1323 xml_node<Ch> *m_first_node;
1324 xml_node<Ch> *m_last_node;
1325 xml_attribute<Ch> *m_first_attribute;
1326 xml_attribute<Ch> *m_last_attribute;
1327 xml_node<Ch> *m_prev_sibling;
1328 xml_node<Ch> *m_next_sibling;
1329
1330 };
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342 template<class Ch = char>
1343 class xml_document: public xml_node<Ch>, public memory_pool<Ch>
1344 {
1345
1346 public:
1347
1348
1349 xml_document()
1350 : xml_node<Ch>(node_document)
1351 {
1352 }
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365 template<int Flags>
1366 void parse(Ch *text)
1367 {
1368 BOOST_ASSERT(text);
1369
1370
1371 this->remove_all_nodes();
1372 this->remove_all_attributes();
1373
1374
1375 parse_bom<Flags>(text);
1376
1377
1378 while (true)
1379 {
1380
1381 skip<whitespace_pred, Flags>(text);
1382 if (*text == 0)
1383 break;
1384
1385
1386 if (*text == Ch('<'))
1387 {
1388 ++text;
1389 if (xml_node<Ch> *node = parse_node<Flags>(text))
1390 this->append_node(node);
1391 }
1392 else
1393 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected <", text);
1394 }
1395
1396 }
1397
1398
1399
1400 void clear()
1401 {
1402 this->remove_all_nodes();
1403 this->remove_all_attributes();
1404 memory_pool<Ch>::clear();
1405 }
1406
1407 private:
1408
1409
1410
1411
1412
1413 struct whitespace_pred
1414 {
1415 static unsigned char test(Ch ch)
1416 {
1417 return internal::lookup_tables<0>::lookup_whitespace[internal::get_index(ch)];
1418 }
1419 };
1420
1421
1422 struct node_name_pred
1423 {
1424 static unsigned char test(Ch ch)
1425 {
1426 return internal::lookup_tables<0>::lookup_node_name[internal::get_index(ch)];
1427 }
1428 };
1429
1430
1431 struct attribute_name_pred
1432 {
1433 static unsigned char test(Ch ch)
1434 {
1435 return internal::lookup_tables<0>::lookup_attribute_name[internal::get_index(ch)];
1436 }
1437 };
1438
1439
1440 struct text_pred
1441 {
1442 static unsigned char test(Ch ch)
1443 {
1444 return internal::lookup_tables<0>::lookup_text[internal::get_index(ch)];
1445 }
1446 };
1447
1448
1449 struct text_pure_no_ws_pred
1450 {
1451 static unsigned char test(Ch ch)
1452 {
1453 return internal::lookup_tables<0>::lookup_text_pure_no_ws[internal::get_index(ch)];
1454 }
1455 };
1456
1457
1458 struct text_pure_with_ws_pred
1459 {
1460 static unsigned char test(Ch ch)
1461 {
1462 return internal::lookup_tables<0>::lookup_text_pure_with_ws[internal::get_index(ch)];
1463 }
1464 };
1465
1466
1467 template<Ch Quote>
1468 struct attribute_value_pred
1469 {
1470 static unsigned char test(Ch ch)
1471 {
1472 if (Quote == Ch('\''))
1473 return internal::lookup_tables<0>::lookup_attribute_data_1[internal::get_index(ch)];
1474 if (Quote == Ch('\"'))
1475 return internal::lookup_tables<0>::lookup_attribute_data_2[internal::get_index(ch)];
1476 return 0;
1477 }
1478 };
1479
1480
1481 template<Ch Quote>
1482 struct attribute_value_pure_pred
1483 {
1484 static unsigned char test(Ch ch)
1485 {
1486 if (Quote == Ch('\''))
1487 return internal::lookup_tables<0>::lookup_attribute_data_1_pure[internal::get_index(ch)];
1488 if (Quote == Ch('\"'))
1489 return internal::lookup_tables<0>::lookup_attribute_data_2_pure[internal::get_index(ch)];
1490 return 0;
1491 }
1492 };
1493
1494
1495 template<int Flags>
1496 static void insert_coded_character(Ch *&text, unsigned long code)
1497 {
1498 if (Flags & parse_no_utf8)
1499 {
1500
1501
1502 text[0] = static_cast<unsigned char>(code);
1503 text += 1;
1504 }
1505 else
1506 {
1507
1508 if (code < 0x80)
1509 {
1510 text[0] = static_cast<unsigned char>(code);
1511 text += 1;
1512 }
1513 else if (code < 0x800)
1514 {
1515 text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1516 text[0] = static_cast<unsigned char>(code | 0xC0);
1517 text += 2;
1518 }
1519 else if (code < 0x10000)
1520 {
1521 text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1522 text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1523 text[0] = static_cast<unsigned char>(code | 0xE0);
1524 text += 3;
1525 }
1526 else if (code < 0x110000)
1527 {
1528 text[3] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1529 text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1530 text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
1531 text[0] = static_cast<unsigned char>(code | 0xF0);
1532 text += 4;
1533 }
1534 else
1535 {
1536 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("invalid numeric character entity", text);
1537 }
1538 }
1539 }
1540
1541
1542 template<class StopPred, int Flags>
1543 static void skip(Ch *&text)
1544 {
1545 Ch *tmp = text;
1546 while (StopPred::test(*tmp))
1547 ++tmp;
1548 text = tmp;
1549 }
1550
1551
1552
1553
1554 template<class StopPred, class StopPredPure, int Flags>
1555 static Ch *skip_and_expand_character_refs(Ch *&text)
1556 {
1557
1558 if (Flags & parse_no_entity_translation &&
1559 !(Flags & parse_normalize_whitespace) &&
1560 !(Flags & parse_trim_whitespace))
1561 {
1562 skip<StopPred, Flags>(text);
1563 return text;
1564 }
1565
1566
1567 skip<StopPredPure, Flags>(text);
1568
1569
1570 Ch *src = text;
1571 Ch *dest = src;
1572 while (StopPred::test(*src))
1573 {
1574
1575 if (!(Flags & parse_no_entity_translation))
1576 {
1577
1578 if (src[0] == Ch('&'))
1579 {
1580 switch (src[1])
1581 {
1582
1583
1584 case Ch('a'):
1585 if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';'))
1586 {
1587 *dest = Ch('&');
1588 ++dest;
1589 src += 5;
1590 continue;
1591 }
1592 if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s') && src[5] == Ch(';'))
1593 {
1594 *dest = Ch('\'');
1595 ++dest;
1596 src += 6;
1597 continue;
1598 }
1599 break;
1600
1601
1602 case Ch('q'):
1603 if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t') && src[5] == Ch(';'))
1604 {
1605 *dest = Ch('"');
1606 ++dest;
1607 src += 6;
1608 continue;
1609 }
1610 break;
1611
1612
1613 case Ch('g'):
1614 if (src[2] == Ch('t') && src[3] == Ch(';'))
1615 {
1616 *dest = Ch('>');
1617 ++dest;
1618 src += 4;
1619 continue;
1620 }
1621 break;
1622
1623
1624 case Ch('l'):
1625 if (src[2] == Ch('t') && src[3] == Ch(';'))
1626 {
1627 *dest = Ch('<');
1628 ++dest;
1629 src += 4;
1630 continue;
1631 }
1632 break;
1633
1634
1635 case Ch('#'):
1636 if (src[2] == Ch('x'))
1637 {
1638 unsigned long code = 0;
1639 src += 3;
1640 while (true)
1641 {
1642 unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
1643 if (digit == 0xFF)
1644 break;
1645 code = code * 16 + digit;
1646 ++src;
1647 }
1648 insert_coded_character<Flags>(dest, code);
1649 }
1650 else
1651 {
1652 unsigned long code = 0;
1653 src += 2;
1654 while (true)
1655 {
1656 unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
1657 if (digit == 0xFF)
1658 break;
1659 code = code * 10 + digit;
1660 ++src;
1661 }
1662 insert_coded_character<Flags>(dest, code);
1663 }
1664 if (*src == Ch(';'))
1665 ++src;
1666 else
1667 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ;", src);
1668 continue;
1669
1670
1671 default:
1672
1673 break;
1674
1675 }
1676 }
1677 }
1678
1679
1680 if (Flags & parse_normalize_whitespace)
1681 {
1682
1683 if (whitespace_pred::test(*src))
1684 {
1685 *dest = Ch(' '); ++dest;
1686 ++src;
1687
1688 while (whitespace_pred::test(*src))
1689 ++src;
1690 continue;
1691 }
1692 }
1693
1694
1695 *dest++ = *src++;
1696
1697 }
1698
1699
1700 text = src;
1701 return dest;
1702
1703 }
1704
1705
1706
1707
1708
1709 template<int Flags>
1710 void parse_bom(char *&text)
1711 {
1712 if (static_cast<unsigned char>(text[0]) == 0xEF &&
1713 static_cast<unsigned char>(text[1]) == 0xBB &&
1714 static_cast<unsigned char>(text[2]) == 0xBF)
1715 {
1716 text += 3;
1717 }
1718 }
1719
1720
1721 template<int Flags>
1722 void parse_bom(wchar_t *&text)
1723 {
1724 const wchar_t bom = 0xFEFF;
1725 if (text[0] == bom)
1726 {
1727 ++text;
1728 }
1729 }
1730
1731
1732 template<int Flags>
1733 xml_node<Ch> *parse_xml_declaration(Ch *&text)
1734 {
1735
1736 if (!(Flags & parse_declaration_node))
1737 {
1738
1739 while (text[0] != Ch('?') || text[1] != Ch('>'))
1740 {
1741 if (!text[0])
1742 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1743 ++text;
1744 }
1745 text += 2;
1746 return 0;
1747 }
1748
1749
1750 xml_node<Ch> *declaration = this->allocate_node(node_declaration);
1751
1752
1753 skip<whitespace_pred, Flags>(text);
1754
1755
1756 parse_node_attributes<Flags>(text, declaration);
1757
1758
1759 if (text[0] != Ch('?') || text[1] != Ch('>'))
1760 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ?>", text);
1761 text += 2;
1762
1763 return declaration;
1764 }
1765
1766
1767 template<int Flags>
1768 xml_node<Ch> *parse_comment(Ch *&text)
1769 {
1770
1771 if (!(Flags & parse_comment_nodes))
1772 {
1773
1774 while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>'))
1775 {
1776 if (!text[0])
1777 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1778 ++text;
1779 }
1780 text += 3;
1781 return 0;
1782 }
1783
1784
1785 Ch *val = text;
1786
1787
1788 while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>'))
1789 {
1790 if (!text[0])
1791 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1792 ++text;
1793 }
1794
1795
1796 xml_node<Ch> *comment = this->allocate_node(node_comment);
1797 comment->value(val, text - val);
1798
1799
1800 if (!(Flags & parse_no_string_terminators))
1801 *text = Ch('\0');
1802
1803 text += 3;
1804 return comment;
1805 }
1806
1807
1808 template<int Flags>
1809 xml_node<Ch> *parse_doctype(Ch *&text)
1810 {
1811
1812 Ch *val = text;
1813
1814
1815 while (*text != Ch('>'))
1816 {
1817
1818 switch (*text)
1819 {
1820
1821
1822
1823 case Ch('['):
1824 {
1825 ++text;
1826 int depth = 1;
1827 while (depth > 0)
1828 {
1829 switch (*text)
1830 {
1831 case Ch('['): ++depth; break;
1832 case Ch(']'): --depth; break;
1833 case 0: BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1834 default: break;
1835 }
1836 ++text;
1837 }
1838 break;
1839 }
1840
1841
1842 case Ch('\0'):
1843 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1844
1845
1846 default:
1847 ++text;
1848
1849 }
1850 }
1851
1852
1853 if (Flags & parse_doctype_node)
1854 {
1855
1856 xml_node<Ch> *doctype = this->allocate_node(node_doctype);
1857 doctype->value(val, text - val);
1858
1859
1860 if (!(Flags & parse_no_string_terminators))
1861 *text = Ch('\0');
1862
1863 text += 1;
1864 return doctype;
1865 }
1866 else
1867 {
1868 text += 1;
1869 return 0;
1870 }
1871
1872 }
1873
1874
1875 template<int Flags>
1876 xml_node<Ch> *parse_pi(Ch *&text)
1877 {
1878
1879 if (Flags & parse_pi_nodes)
1880 {
1881
1882 xml_node<Ch> *pi = this->allocate_node(node_pi);
1883
1884
1885 Ch *n = text;
1886 skip<node_name_pred, Flags>(text);
1887 if (text == n)
1888 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected PI target", text);
1889 pi->name(n, text - n);
1890
1891
1892 skip<whitespace_pred, Flags>(text);
1893
1894
1895 Ch *val = text;
1896
1897
1898 while (text[0] != Ch('?') || text[1] != Ch('>'))
1899 {
1900 if (*text == Ch('\0'))
1901 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1902 ++text;
1903 }
1904
1905
1906 pi->value(val, text - val);
1907
1908
1909 if (!(Flags & parse_no_string_terminators))
1910 {
1911 pi->name()[pi->name_size()] = Ch('\0');
1912 pi->value()[pi->value_size()] = Ch('\0');
1913 }
1914
1915 text += 2;
1916 return pi;
1917 }
1918 else
1919 {
1920
1921 while (text[0] != Ch('?') || text[1] != Ch('>'))
1922 {
1923 if (*text == Ch('\0'))
1924 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
1925 ++text;
1926 }
1927 text += 2;
1928 return 0;
1929 }
1930 }
1931
1932
1933
1934
1935 template<int Flags>
1936 Ch parse_and_append_data(xml_node<Ch> *node, Ch *&text, Ch *contents_start)
1937 {
1938
1939 if (!(Flags & parse_trim_whitespace))
1940 text = contents_start;
1941
1942
1943 Ch *val = text, *end;
1944 if (Flags & parse_normalize_whitespace)
1945 end = skip_and_expand_character_refs<text_pred, text_pure_with_ws_pred, Flags>(text);
1946 else
1947 end = skip_and_expand_character_refs<text_pred, text_pure_no_ws_pred, Flags>(text);
1948
1949
1950 if (Flags & parse_trim_whitespace)
1951 {
1952 if (Flags & parse_normalize_whitespace)
1953 {
1954
1955 if (*(end - 1) == Ch(' '))
1956 --end;
1957 }
1958 else
1959 {
1960
1961 while (whitespace_pred::test(*(end - 1)))
1962 --end;
1963 }
1964 }
1965
1966
1967
1968 if (!(Flags & parse_no_data_nodes))
1969 {
1970 xml_node<Ch> *data = this->allocate_node(node_data);
1971 data->value(val, end - val);
1972 node->append_node(data);
1973 }
1974
1975
1976 if (!(Flags & parse_no_element_values))
1977 if (*node->value() == Ch('\0'))
1978 node->value(val, end - val);
1979
1980
1981 if (!(Flags & parse_no_string_terminators))
1982 {
1983 Ch ch = *text;
1984 *end = Ch('\0');
1985 return ch;
1986 }
1987
1988
1989 return *text;
1990 }
1991
1992
1993 template<int Flags>
1994 xml_node<Ch> *parse_cdata(Ch *&text)
1995 {
1996
1997 if (Flags & parse_no_data_nodes)
1998 {
1999
2000 while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>'))
2001 {
2002 if (!text[0])
2003 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
2004 ++text;
2005 }
2006 text += 3;
2007 return 0;
2008 }
2009
2010
2011 Ch *val = text;
2012 while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>'))
2013 {
2014 if (!text[0])
2015 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
2016 ++text;
2017 }
2018
2019
2020 xml_node<Ch> *cdata = this->allocate_node(node_cdata);
2021 cdata->value(val, text - val);
2022
2023
2024 if (!(Flags & parse_no_string_terminators))
2025 *text = Ch('\0');
2026
2027 text += 3;
2028 return cdata;
2029 }
2030
2031
2032 template<int Flags>
2033 xml_node<Ch> *parse_element(Ch *&text)
2034 {
2035
2036 xml_node<Ch> *element = this->allocate_node(node_element);
2037
2038
2039 Ch *n = text;
2040 skip<node_name_pred, Flags>(text);
2041 if (text == n)
2042 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected element name", text);
2043 element->name(n, text - n);
2044
2045
2046 skip<whitespace_pred, Flags>(text);
2047
2048
2049 parse_node_attributes<Flags>(text, element);
2050
2051
2052 if (*text == Ch('>'))
2053 {
2054 ++text;
2055 parse_node_contents<Flags>(text, element);
2056 }
2057 else if (*text == Ch('/'))
2058 {
2059 ++text;
2060 if (*text != Ch('>'))
2061 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text);
2062 ++text;
2063 }
2064 else
2065 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text);
2066
2067
2068 if (!(Flags & parse_no_string_terminators))
2069 element->name()[element->name_size()] = Ch('\0');
2070
2071
2072 return element;
2073 }
2074
2075
2076 template<int Flags>
2077 xml_node<Ch> *parse_node(Ch *&text)
2078 {
2079
2080 switch (text[0])
2081 {
2082
2083
2084 default:
2085
2086 return parse_element<Flags>(text);
2087
2088
2089 case Ch('?'):
2090 ++text;
2091 if ((text[0] == Ch('x') || text[0] == Ch('X')) &&
2092 (text[1] == Ch('m') || text[1] == Ch('M')) &&
2093 (text[2] == Ch('l') || text[2] == Ch('L')) &&
2094 whitespace_pred::test(text[3]))
2095 {
2096
2097 text += 4;
2098 return parse_xml_declaration<Flags>(text);
2099 }
2100 else
2101 {
2102
2103 return parse_pi<Flags>(text);
2104 }
2105
2106
2107 case Ch('!'):
2108
2109
2110 switch (text[1])
2111 {
2112
2113
2114 case Ch('-'):
2115 if (text[2] == Ch('-'))
2116 {
2117
2118 text += 3;
2119 return parse_comment<Flags>(text);
2120 }
2121 break;
2122
2123
2124 case Ch('['):
2125 if (text[2] == Ch('C') && text[3] == Ch('D') && text[4] == Ch('A') &&
2126 text[5] == Ch('T') && text[6] == Ch('A') && text[7] == Ch('['))
2127 {
2128
2129 text += 8;
2130 return parse_cdata<Flags>(text);
2131 }
2132 break;
2133
2134
2135 case Ch('D'):
2136 if (text[2] == Ch('O') && text[3] == Ch('C') && text[4] == Ch('T') &&
2137 text[5] == Ch('Y') && text[6] == Ch('P') && text[7] == Ch('E') &&
2138 whitespace_pred::test(text[8]))
2139 {
2140
2141 text += 9;
2142 return parse_doctype<Flags>(text);
2143 }
2144 break;
2145
2146 default: break;
2147
2148 }
2149
2150
2151 ++text;
2152 while (*text != Ch('>'))
2153 {
2154 if (*text == 0)
2155 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
2156 ++text;
2157 }
2158 ++text;
2159 return 0;
2160
2161 }
2162 }
2163
2164
2165 template<int Flags>
2166 void parse_node_contents(Ch *&text, xml_node<Ch> *node)
2167 {
2168
2169 while (true)
2170 {
2171
2172 Ch *contents_start = text;
2173 if (Flags & parse_trim_whitespace)
2174 skip<whitespace_pred, Flags>(text);
2175 Ch next_char = *text;
2176
2177
2178
2179
2180
2181 after_data_node:
2182
2183
2184 switch (next_char)
2185 {
2186
2187
2188 case Ch('<'):
2189 if (text[1] == Ch('/'))
2190 {
2191
2192 text += 2;
2193 if (Flags & parse_validate_closing_tags)
2194 {
2195
2196 Ch *closing_name = text;
2197 skip<node_name_pred, Flags>(text);
2198 if (!internal::compare(node->name(), node->name_size(), closing_name, text - closing_name, true))
2199 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("invalid closing tag name", text);
2200 }
2201 else
2202 {
2203
2204 skip<node_name_pred, Flags>(text);
2205 }
2206
2207 skip<whitespace_pred, Flags>(text);
2208 if (*text != Ch('>'))
2209 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected >", text);
2210 ++text;
2211 return;
2212 }
2213 else
2214 {
2215
2216 ++text;
2217 if (xml_node<Ch> *child = parse_node<Flags>(text))
2218 node->append_node(child);
2219 }
2220 break;
2221
2222
2223 case Ch('\0'):
2224 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("unexpected end of data", text);
2225
2226
2227 default:
2228 next_char = parse_and_append_data<Flags>(node, text, contents_start);
2229 goto after_data_node;
2230
2231 }
2232 }
2233 }
2234
2235
2236 template<int Flags>
2237 void parse_node_attributes(Ch *&text, xml_node<Ch> *node)
2238 {
2239
2240 while (attribute_name_pred::test(*text))
2241 {
2242
2243 Ch *n = text;
2244 ++text;
2245 skip<attribute_name_pred, Flags>(text);
2246 if (text == n)
2247 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected attribute name", n);
2248
2249
2250 xml_attribute<Ch> *attribute = this->allocate_attribute();
2251 attribute->name(n, text - n);
2252 node->append_attribute(attribute);
2253
2254
2255 skip<whitespace_pred, Flags>(text);
2256
2257
2258 if (*text != Ch('='))
2259 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected =", text);
2260 ++text;
2261
2262
2263 if (!(Flags & parse_no_string_terminators))
2264 attribute->name()[attribute->name_size()] = 0;
2265
2266
2267 skip<whitespace_pred, Flags>(text);
2268
2269
2270 Ch quote = *text;
2271 if (quote != Ch('\'') && quote != Ch('"'))
2272 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ' or \"", text);
2273 ++text;
2274
2275
2276 Ch *val = text, *end;
2277 const int AttFlags = Flags & ~parse_normalize_whitespace;
2278 if (quote == Ch('\''))
2279 end = skip_and_expand_character_refs<attribute_value_pred<Ch('\'')>, attribute_value_pure_pred<Ch('\'')>, AttFlags>(text);
2280 else
2281 end = skip_and_expand_character_refs<attribute_value_pred<Ch('"')>, attribute_value_pure_pred<Ch('"')>, AttFlags>(text);
2282
2283
2284 attribute->value(val, end - val);
2285
2286
2287 if (*text != quote)
2288 BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR("expected ' or \"", text);
2289 ++text;
2290
2291
2292 if (!(Flags & parse_no_string_terminators))
2293 attribute->value()[attribute->value_size()] = 0;
2294
2295
2296 skip<whitespace_pred, Flags>(text);
2297 }
2298 }
2299
2300 };
2301
2302
2303 namespace internal
2304 {
2305
2306
2307 template<int Dummy>
2308 const unsigned char lookup_tables<Dummy>::lookup_whitespace[256] =
2309 {
2310
2311 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
2312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2313 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2314 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2315 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2316 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2318 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2322 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2323 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2324 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2325 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2326 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2327 };
2328
2329
2330 template<int Dummy>
2331 const unsigned char lookup_tables<Dummy>::lookup_node_name[256] =
2332 {
2333
2334 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,
2335 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2336 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
2337 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
2338 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2339 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2340 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2341 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2342 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2343 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2344 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2345 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2346 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2347 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2348 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2349 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2350 };
2351
2352
2353 template<int Dummy>
2354 const unsigned char lookup_tables<Dummy>::lookup_text[256] =
2355 {
2356
2357 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2358 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2359 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2360 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
2361 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2362 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2363 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2364 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2365 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2366 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2367 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2368 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2369 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2370 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2371 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2372 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2373 };
2374
2375
2376
2377 template<int Dummy>
2378 const unsigned char lookup_tables<Dummy>::lookup_text_pure_no_ws[256] =
2379 {
2380
2381 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2382 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2383 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2384 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
2385 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2386 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2387 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2388 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2389 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2390 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2391 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2392 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2393 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2394 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2395 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2396 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2397 };
2398
2399
2400
2401 template<int Dummy>
2402 const unsigned char lookup_tables<Dummy>::lookup_text_pure_with_ws[256] =
2403 {
2404
2405 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,
2406 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2407 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2408 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
2409 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2410 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2411 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2412 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2413 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2414 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2415 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2416 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2417 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2418 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2419 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2420 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2421 };
2422
2423
2424 template<int Dummy>
2425 const unsigned char lookup_tables<Dummy>::lookup_attribute_name[256] =
2426 {
2427
2428 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,
2429 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2430 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
2431 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
2432 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2433 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2434 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2435 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2436 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2437 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2438 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2439 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2440 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2441 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2442 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2443 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2444 };
2445
2446
2447 template<int Dummy>
2448 const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1[256] =
2449 {
2450
2451 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2452 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2453 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
2454 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2455 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2456 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2457 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2458 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2459 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2460 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2461 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2462 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2463 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2464 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2465 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2466 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2467 };
2468
2469
2470 template<int Dummy>
2471 const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1_pure[256] =
2472 {
2473
2474 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2475 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2476 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
2477 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2478 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2479 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2480 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2481 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2482 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2483 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2484 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2485 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2486 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2487 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2488 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2489 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2490 };
2491
2492
2493 template<int Dummy>
2494 const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2[256] =
2495 {
2496
2497 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2498 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2499 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2500 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2501 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2502 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2503 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2504 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2505 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2506 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2507 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2508 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2509 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2510 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2511 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2512 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2513 };
2514
2515
2516 template<int Dummy>
2517 const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2_pure[256] =
2518 {
2519
2520 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2521 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2522 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2523 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2524 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2525 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2526 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2527 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2528 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2529 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2530 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2531 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2532 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2533 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2534 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2535 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
2536 };
2537
2538
2539 template<int Dummy>
2540 const unsigned char lookup_tables<Dummy>::lookup_digits[256] =
2541 {
2542
2543 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
2544 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
2545 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
2546 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,255,255,255,255,255,255,
2547 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255,
2548 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
2549 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255,
2550 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
2551 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
2552 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
2553 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
2554 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
2555 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
2556 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
2557 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
2558 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
2559 };
2560
2561
2562 template<int Dummy>
2563 const unsigned char lookup_tables<Dummy>::lookup_upcase[256] =
2564 {
2565
2566 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
2567 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
2568 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
2569 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
2570 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
2571 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
2572 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
2573 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123,124,125,126,127,
2574 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
2575 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
2576 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
2577 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
2578 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
2579 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
2580 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
2581 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
2582 };
2583 }
2584
2585
2586 }}}}
2587
2588
2589 #undef BOOST_PROPERTY_TREE_RAPIDXML_PARSE_ERROR
2590
2591
2592 #ifdef _MSC_VER
2593 #pragma warning(pop)
2594 #endif
2595
2596 #endif