]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/property_tree/include/boost/property_tree/detail/xml_parser_read_rapidxml.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / property_tree / include / boost / property_tree / detail / xml_parser_read_rapidxml.hpp
1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2007 Marcin Kalicinski
3 //
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // For more information, see www.boost.org
9 // ----------------------------------------------------------------------------
10 #ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
11 #define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
12
13 #include <boost/property_tree/ptree.hpp>
14 #include <boost/property_tree/detail/xml_parser_error.hpp>
15 #include <boost/property_tree/detail/xml_parser_flags.hpp>
16 #include <boost/property_tree/detail/xml_parser_utils.hpp>
17 #include <boost/property_tree/detail/rapidxml.hpp>
18 #include <vector>
19
20 namespace boost { namespace property_tree { namespace xml_parser
21 {
22
23 template<class Ptree, class Ch>
24 void read_xml_node(detail::rapidxml::xml_node<Ch> *node,
25 Ptree &pt, int flags)
26 {
27 using namespace detail::rapidxml;
28 switch (node->type())
29 {
30 // Element nodes
31 case node_element:
32 {
33 // Create node
34 Ptree &pt_node = pt.push_back(std::make_pair(node->name(),
35 Ptree()))->second;
36
37 // Copy attributes
38 if (node->first_attribute())
39 {
40 Ptree &pt_attr_root = pt_node.push_back(
41 std::make_pair(xmlattr<typename Ptree::key_type>(), Ptree()))->second;
42 for (xml_attribute<Ch> *attr = node->first_attribute();
43 attr; attr = attr->next_attribute())
44 {
45 Ptree &pt_attr = pt_attr_root.push_back(
46 std::make_pair(attr->name(), Ptree()))->second;
47 pt_attr.data() = typename Ptree::key_type(attr->value(), attr->value_size());
48 }
49 }
50
51 // Copy children
52 for (xml_node<Ch> *child = node->first_node();
53 child; child = child->next_sibling())
54 read_xml_node(child, pt_node, flags);
55 }
56 break;
57
58 // Data nodes
59 case node_data:
60 case node_cdata:
61 {
62 if (flags & no_concat_text)
63 pt.push_back(std::make_pair(xmltext<typename Ptree::key_type>(),
64 Ptree(node->value())));
65 else
66 pt.data() += typename Ptree::key_type(node->value(), node->value_size());
67 }
68 break;
69
70 // Comment nodes
71 case node_comment:
72 {
73 if (!(flags & no_comments))
74 pt.push_back(std::make_pair(xmlcomment<typename Ptree::key_type>(),
75 Ptree(typename Ptree::key_type(node->value(), node->value_size()))));
76 }
77 break;
78
79 default:
80 // Skip other node types
81 break;
82 }
83 }
84
85 template<class Ptree>
86 void read_xml_internal(std::basic_istream<
87 typename Ptree::key_type::value_type> &stream,
88 Ptree &pt,
89 int flags,
90 const std::string &filename)
91 {
92 typedef typename Ptree::key_type::value_type Ch;
93 using namespace detail::rapidxml;
94
95 // Load data into vector
96 stream.unsetf(std::ios::skipws);
97 std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
98 std::istreambuf_iterator<Ch>());
99 if (!stream.good())
100 BOOST_PROPERTY_TREE_THROW(
101 xml_parser_error("read error", filename, 0));
102 v.push_back(0); // zero-terminate
103
104 try {
105 // Parse using appropriate flags
106 const int f_tws = parse_normalize_whitespace
107 | parse_trim_whitespace;
108 const int f_c = parse_comment_nodes;
109 // Some compilers don't like the bitwise or in the template arg.
110 const int f_tws_c = parse_normalize_whitespace
111 | parse_trim_whitespace
112 | parse_comment_nodes;
113 xml_document<Ch> doc;
114 if (flags & no_comments) {
115 if (flags & trim_whitespace)
116 doc.BOOST_NESTED_TEMPLATE parse<f_tws>(&v.front());
117 else
118 doc.BOOST_NESTED_TEMPLATE parse<0>(&v.front());
119 } else {
120 if (flags & trim_whitespace)
121 doc.BOOST_NESTED_TEMPLATE parse<f_tws_c>(&v.front());
122 else
123 doc.BOOST_NESTED_TEMPLATE parse<f_c>(&v.front());
124 }
125
126 // Create ptree from nodes
127 Ptree local;
128 for (xml_node<Ch> *child = doc.first_node();
129 child; child = child->next_sibling())
130 read_xml_node(child, local, flags);
131
132 // Swap local and result ptrees
133 pt.swap(local);
134 } catch (parse_error &e) {
135 long line = static_cast<long>(
136 std::count(&v.front(), e.where<Ch>(), Ch('\n')) + 1);
137 BOOST_PROPERTY_TREE_THROW(
138 xml_parser_error(e.what(), filename, line));
139 }
140 }
141
142 } } }
143
144 #endif