]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/property_tree/include/boost/property_tree/detail/xml_parser_write.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / property_tree / include / boost / property_tree / detail / xml_parser_write.hpp
1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2002-2006 Marcin Kalicinski
3 // Copyright (C) 2013 Sebastian Redl
4 //
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // For more information, see www.boost.org
10 // ----------------------------------------------------------------------------
11 #ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
12 #define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
13
14 #include <boost/property_tree/ptree.hpp>
15 #include <boost/property_tree/detail/xml_parser_utils.hpp>
16 #include <string>
17 #include <ostream>
18 #include <iomanip>
19
20 namespace boost { namespace property_tree { namespace xml_parser
21 {
22 template<class Str>
23 void write_xml_indent(std::basic_ostream<typename Str::value_type> &stream,
24 int indent,
25 const xml_writer_settings<Str> & settings
26 )
27 {
28 stream << std::basic_string<typename Str::value_type>(indent * settings.indent_count, settings.indent_char);
29 }
30
31 template<class Str>
32 void write_xml_comment(std::basic_ostream<typename Str::value_type> &stream,
33 const Str &s,
34 int indent,
35 bool separate_line,
36 const xml_writer_settings<Str> & settings
37 )
38 {
39 typedef typename Str::value_type Ch;
40 if (separate_line)
41 write_xml_indent(stream,indent,settings);
42 stream << Ch('<') << Ch('!') << Ch('-') << Ch('-');
43 stream << s;
44 stream << Ch('-') << Ch('-') << Ch('>');
45 if (separate_line)
46 stream << Ch('\n');
47 }
48
49 template<class Str>
50 void write_xml_text(std::basic_ostream<typename Str::value_type> &stream,
51 const Str &s,
52 int indent,
53 bool separate_line,
54 const xml_writer_settings<Str> & settings
55 )
56 {
57 typedef typename Str::value_type Ch;
58 if (separate_line)
59 write_xml_indent(stream,indent,settings);
60 stream << encode_char_entities(s);
61 if (separate_line)
62 stream << Ch('\n');
63 }
64
65 template<class Ptree>
66 void write_xml_element(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
67 const typename Ptree::key_type &key,
68 const Ptree &pt,
69 int indent,
70 const xml_writer_settings<typename Ptree::key_type> & settings)
71 {
72 typedef typename Ptree::key_type::value_type Ch;
73 typedef typename Ptree::key_type Str;
74 typedef typename Ptree::const_iterator It;
75
76 bool want_pretty = settings.indent_count > 0;
77 // Find if elements present
78 bool has_elements = false;
79 bool has_attrs_only = pt.data().empty();
80 for (It it = pt.begin(), end = pt.end(); it != end; ++it)
81 {
82 if (it->first != xmlattr<Str>() )
83 {
84 has_attrs_only = false;
85 if (it->first != xmltext<Str>())
86 {
87 has_elements = true;
88 break;
89 }
90 }
91 }
92
93 // Write element
94 if (pt.data().empty() && pt.empty()) // Empty key
95 {
96 if (indent >= 0)
97 {
98 write_xml_indent(stream,indent,settings);
99 stream << Ch('<') << key <<
100 Ch('/') << Ch('>');
101 if (want_pretty)
102 stream << Ch('\n');
103 }
104 }
105 else // Nonempty key
106 {
107 // Write opening tag, attributes and data
108 if (indent >= 0)
109 {
110 // Write opening brace and key
111 write_xml_indent(stream,indent,settings);
112 stream << Ch('<') << key;
113
114 // Write attributes
115 if (optional<const Ptree &> attribs = pt.get_child_optional(xmlattr<Str>()))
116 for (It it = attribs.get().begin(); it != attribs.get().end(); ++it)
117 stream << Ch(' ') << it->first << Ch('=')
118 << Ch('"')
119 << encode_char_entities(
120 it->second.template get_value<Str>())
121 << Ch('"');
122
123 if ( has_attrs_only )
124 {
125 // Write closing brace
126 stream << Ch('/') << Ch('>');
127 if (want_pretty)
128 stream << Ch('\n');
129 }
130 else
131 {
132 // Write closing brace
133 stream << Ch('>');
134
135 // Break line if needed and if we want pretty-printing
136 if (has_elements && want_pretty)
137 stream << Ch('\n');
138 }
139 }
140
141 // Write data text, if present
142 if (!pt.data().empty())
143 write_xml_text(stream,
144 pt.template get_value<Str>(),
145 indent + 1, has_elements && want_pretty, settings);
146
147 // Write elements, comments and texts
148 for (It it = pt.begin(); it != pt.end(); ++it)
149 {
150 if (it->first == xmlattr<Str>())
151 continue;
152 else if (it->first == xmlcomment<Str>())
153 write_xml_comment(stream,
154 it->second.template get_value<Str>(),
155 indent + 1, want_pretty, settings);
156 else if (it->first == xmltext<Str>())
157 write_xml_text(stream,
158 it->second.template get_value<Str>(),
159 indent + 1, has_elements && want_pretty, settings);
160 else
161 write_xml_element(stream, it->first, it->second,
162 indent + 1, settings);
163 }
164
165 // Write closing tag
166 if (indent >= 0 && !has_attrs_only)
167 {
168 if (has_elements)
169 write_xml_indent(stream,indent,settings);
170 stream << Ch('<') << Ch('/') << key << Ch('>');
171 if (want_pretty)
172 stream << Ch('\n');
173 }
174
175 }
176 }
177
178 template<class Ptree>
179 void write_xml_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
180 const Ptree &pt,
181 const std::string &filename,
182 const xml_writer_settings<typename Ptree::key_type> & settings)
183 {
184 typedef typename Ptree::key_type Str;
185 stream << detail::widen<Str>("<?xml version=\"1.0\" encoding=\"")
186 << settings.encoding
187 << detail::widen<Str>("\"?>\n");
188 write_xml_element(stream, Str(), pt, -1, settings);
189 if (!stream)
190 BOOST_PROPERTY_TREE_THROW(xml_parser_error("write error", filename, 0));
191 }
192
193 } } }
194
195 #endif