File indexing completed on 2025-01-18 09:50:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED
0011 #define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED
0012
0013 #include "boost/property_tree/ptree.hpp"
0014 #include "boost/property_tree/detail/info_parser_utils.hpp"
0015 #include <string>
0016
0017 namespace boost { namespace property_tree { namespace info_parser
0018 {
0019 template<class Ch>
0020 void write_info_indent(std::basic_ostream<Ch> &stream,
0021 int indent,
0022 const info_writer_settings<Ch> &settings
0023 )
0024 {
0025 stream << std::basic_string<Ch>(indent * settings.indent_count, settings.indent_char);
0026 }
0027
0028
0029 template<class Ch>
0030 std::basic_string<Ch> create_escapes(const std::basic_string<Ch> &s)
0031 {
0032 std::basic_string<Ch> result;
0033 typename std::basic_string<Ch>::const_iterator b = s.begin();
0034 typename std::basic_string<Ch>::const_iterator e = s.end();
0035 while (b != e)
0036 {
0037 if (*b == Ch('\0')) result += Ch('\\'), result += Ch('0');
0038 else if (*b == Ch('\a')) result += Ch('\\'), result += Ch('a');
0039 else if (*b == Ch('\b')) result += Ch('\\'), result += Ch('b');
0040 else if (*b == Ch('\f')) result += Ch('\\'), result += Ch('f');
0041 else if (*b == Ch('\n')) result += Ch('\\'), result += Ch('n');
0042 else if (*b == Ch('\r')) result += Ch('\\'), result += Ch('r');
0043 else if (*b == Ch('\v')) result += Ch('\\'), result += Ch('v');
0044 else if (*b == Ch('"')) result += Ch('\\'), result += Ch('"');
0045 else if (*b == Ch('\\')) result += Ch('\\'), result += Ch('\\');
0046 else
0047 result += *b;
0048 ++b;
0049 }
0050 return result;
0051 }
0052
0053 template<class Ch>
0054 bool is_simple_key(const std::basic_string<Ch> &key)
0055 {
0056 const static std::basic_string<Ch> chars = convert_chtype<Ch, char>(" \t{};\n\"");
0057 return !key.empty() && key.find_first_of(chars) == key.npos;
0058 }
0059
0060 template<class Ch>
0061 bool is_simple_data(const std::basic_string<Ch> &data)
0062 {
0063 const static std::basic_string<Ch> chars = convert_chtype<Ch, char>(" \t{};\n\"");
0064 return !data.empty() && data.find_first_of(chars) == data.npos;
0065 }
0066
0067 template<class Ptree>
0068 void write_info_helper(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
0069 const Ptree &pt,
0070 int indent,
0071 const info_writer_settings<typename Ptree::key_type::value_type> &settings)
0072 {
0073
0074
0075 typedef typename Ptree::key_type::value_type Ch;
0076
0077
0078 if (indent >= 0)
0079 {
0080 if (!pt.data().empty())
0081 {
0082 std::basic_string<Ch> data = create_escapes(pt.template get_value<std::basic_string<Ch> >());
0083 if (is_simple_data(data))
0084 stream << Ch(' ') << data << Ch('\n');
0085 else
0086 stream << Ch(' ') << Ch('\"') << data << Ch('\"') << Ch('\n');
0087 }
0088 else if (pt.empty())
0089 stream << Ch(' ') << Ch('\"') << Ch('\"') << Ch('\n');
0090 else
0091 stream << Ch('\n');
0092 }
0093
0094
0095 if (!pt.empty())
0096 {
0097
0098
0099 if (indent >= 0)
0100 {
0101 write_info_indent( stream, indent, settings);
0102 stream << Ch('{') << Ch('\n');
0103 }
0104
0105
0106 typename Ptree::const_iterator it = pt.begin();
0107 for (; it != pt.end(); ++it)
0108 {
0109
0110
0111 std::basic_string<Ch> key = create_escapes(it->first);
0112 write_info_indent( stream, indent+1, settings);
0113 if (is_simple_key(key))
0114 stream << key;
0115 else
0116 stream << Ch('\"') << key << Ch('\"');
0117
0118
0119 write_info_helper(stream, it->second, indent + 1, settings);
0120
0121 }
0122
0123
0124 if (indent >= 0)
0125 {
0126 write_info_indent( stream, indent, settings);
0127 stream << Ch('}') << Ch('\n');
0128 }
0129
0130 }
0131 }
0132
0133
0134 template<class Ptree>
0135 void write_info_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
0136 const Ptree &pt,
0137 const std::string &filename,
0138 const info_writer_settings<typename Ptree::key_type::value_type> &settings)
0139 {
0140 write_info_helper(stream, pt, -1, settings);
0141 stream.flush();
0142 if (!stream.good())
0143 BOOST_PROPERTY_TREE_THROW(info_parser_error("write error", filename, 0));
0144 }
0145
0146 } } }
0147
0148 #endif