1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2002-2006 Marcin Kalicinski
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)
8 // For more information, see www.boost.org
9 // ----------------------------------------------------------------------------
10 #ifndef BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED
11 #define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED
13 #include "boost/property_tree/ptree.hpp"
14 #include "boost/property_tree/detail/info_parser_utils.hpp"
17 namespace boost
{ namespace property_tree
{ namespace info_parser
20 void write_info_indent(std::basic_ostream
<Ch
> &stream
,
22 const info_writer_settings
<Ch
> &settings
25 stream
<< std::basic_string
<Ch
>(indent
* settings
.indent_count
, settings
.indent_char
);
28 // Create necessary escape sequences from illegal characters
30 std::basic_string
<Ch
> create_escapes(const std::basic_string
<Ch
> &s
)
32 std::basic_string
<Ch
> result
;
33 typename
std::basic_string
<Ch
>::const_iterator b
= s
.begin();
34 typename
std::basic_string
<Ch
>::const_iterator e
= s
.end();
37 if (*b
== Ch('\0')) result
+= Ch('\\'), result
+= Ch('0');
38 else if (*b
== Ch('\a')) result
+= Ch('\\'), result
+= Ch('a');
39 else if (*b
== Ch('\b')) result
+= Ch('\\'), result
+= Ch('b');
40 else if (*b
== Ch('\f')) result
+= Ch('\\'), result
+= Ch('f');
41 else if (*b
== Ch('\n')) result
+= Ch('\\'), result
+= Ch('n');
42 else if (*b
== Ch('\r')) result
+= Ch('\\'), result
+= Ch('r');
43 else if (*b
== Ch('\v')) result
+= Ch('\\'), result
+= Ch('v');
44 else if (*b
== Ch('"')) result
+= Ch('\\'), result
+= Ch('"');
45 else if (*b
== Ch('\\')) result
+= Ch('\\'), result
+= Ch('\\');
54 bool is_simple_key(const std::basic_string
<Ch
> &key
)
56 const static std::basic_string
<Ch
> chars
= convert_chtype
<Ch
, char>(" \t{};\n\"");
57 return !key
.empty() && key
.find_first_of(chars
) == key
.npos
;
61 bool is_simple_data(const std::basic_string
<Ch
> &data
)
63 const static std::basic_string
<Ch
> chars
= convert_chtype
<Ch
, char>(" \t{};\n\"");
64 return !data
.empty() && data
.find_first_of(chars
) == data
.npos
;
68 void write_info_helper(std::basic_ostream
<typename
Ptree::key_type::value_type
> &stream
,
71 const info_writer_settings
<typename
Ptree::key_type::value_type
> &settings
)
75 typedef typename
Ptree::key_type::value_type Ch
;
80 if (!pt
.data().empty())
82 std::basic_string
<Ch
> data
= create_escapes(pt
.template get_value
<std::basic_string
<Ch
> >());
83 if (is_simple_data(data
))
84 stream
<< Ch(' ') << data
<< Ch('\n');
86 stream
<< Ch(' ') << Ch('\"') << data
<< Ch('\"') << Ch('\n');
89 stream
<< Ch(' ') << Ch('\"') << Ch('\"') << Ch('\n');
101 write_info_indent( stream
, indent
, settings
);
102 stream
<< Ch('{') << Ch('\n');
106 typename
Ptree::const_iterator it
= pt
.begin();
107 for (; it
!= pt
.end(); ++it
)
111 std::basic_string
<Ch
> key
= create_escapes(it
->first
);
112 write_info_indent( stream
, indent
+1, settings
);
113 if (is_simple_key(key
))
116 stream
<< Ch('\"') << key
<< Ch('\"');
118 // Output data and children
119 write_info_helper(stream
, it
->second
, indent
+ 1, settings
);
126 write_info_indent( stream
, indent
, settings
);
127 stream
<< Ch('}') << Ch('\n');
133 // Write ptree to info stream
134 template<class Ptree
>
135 void write_info_internal(std::basic_ostream
<typename
Ptree::key_type::value_type
> &stream
,
137 const std::string
&filename
,
138 const info_writer_settings
<typename
Ptree::key_type::value_type
> &settings
)
140 write_info_helper(stream
, pt
, -1, settings
);
142 BOOST_PROPERTY_TREE_THROW(info_parser_error("write error", filename
, 0));