Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:18

0001 // ----------------------------------------------------------------------------
0002 // Copyright (C) 2002-2006 Marcin Kalicinski
0003 // Copyright (C) 2013 Sebastian Redl
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. 
0006 // (See accompanying file LICENSE_1_0.txt or copy at 
0007 // http://www.boost.org/LICENSE_1_0.txt)
0008 //
0009 // For more information, see www.boost.org
0010 // ----------------------------------------------------------------------------
0011 #ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
0012 #define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
0013 
0014 #include <boost/property_tree/ptree.hpp>
0015 #include <boost/property_tree/detail/xml_parser_utils.hpp>
0016 #include <boost/optional/optional.hpp>
0017 #include <string>
0018 #include <ostream>
0019 #include <iomanip>
0020 
0021 namespace boost { namespace property_tree { namespace xml_parser
0022 {
0023     template<class Str>
0024     void write_xml_indent(std::basic_ostream<typename Str::value_type> &stream,
0025           int indent,
0026           const xml_writer_settings<Str> & settings
0027           )
0028     {
0029         stream << std::basic_string<typename Str::value_type>(indent * settings.indent_count, settings.indent_char);
0030     }
0031 
0032     template<class Str>
0033     void write_xml_comment(std::basic_ostream<typename Str::value_type> &stream,
0034                            const Str &s,
0035                            int indent,
0036                            bool separate_line,
0037                            const xml_writer_settings<Str> & settings
0038                            )
0039     {
0040         typedef typename Str::value_type Ch;
0041         if (separate_line)
0042             write_xml_indent(stream,indent,settings);
0043         stream << Ch('<') << Ch('!') << Ch('-') << Ch('-');
0044         stream << s;
0045         stream << Ch('-') << Ch('-') << Ch('>');
0046         if (separate_line)
0047             stream << Ch('\n');
0048     }
0049 
0050     template<class Str>
0051     void write_xml_text(std::basic_ostream<typename Str::value_type> &stream,
0052                         const Str &s,
0053                         int indent, 
0054                         bool separate_line,
0055                         const xml_writer_settings<Str> & settings
0056                         )
0057     {
0058         typedef typename Str::value_type Ch;
0059         if (separate_line)
0060             write_xml_indent(stream,indent,settings);
0061         stream << encode_char_entities(s);
0062         if (separate_line)
0063             stream << Ch('\n');
0064     }
0065 
0066     template<class Ptree>
0067     void write_xml_element(std::basic_ostream<typename Ptree::key_type::value_type> &stream,
0068                            const typename Ptree::key_type &key,
0069                            const Ptree &pt,
0070                            int indent,
0071                            const xml_writer_settings<typename Ptree::key_type> & settings)
0072     {
0073         typedef typename Ptree::key_type::value_type Ch;
0074         typedef typename Ptree::key_type Str;
0075         typedef typename Ptree::const_iterator It;
0076 
0077         bool want_pretty = settings.indent_count > 0;
0078         // Find if elements present
0079         bool has_elements = false;
0080         bool has_attrs_only = pt.data().empty();
0081         for (It it = pt.begin(), end = pt.end(); it != end; ++it)
0082         {
0083             if (it->first != xmlattr<Str>() )
0084             {
0085                 has_attrs_only = false;
0086                 if (it->first != xmltext<Str>())
0087                 {
0088                     has_elements = true;
0089                     break;
0090                 }
0091             }
0092         }
0093 
0094         // Write element
0095         if (pt.data().empty() && pt.empty())    // Empty key
0096         {
0097             if (indent >= 0)
0098             {
0099                 write_xml_indent(stream,indent,settings);
0100                 stream << Ch('<') << key << 
0101                           Ch('/') << Ch('>');
0102                 if (want_pretty)
0103                     stream << Ch('\n');
0104             }
0105         }
0106         else    // Nonempty key
0107         {
0108             // Write opening tag, attributes and data
0109             if (indent >= 0)
0110             {
0111                 // Write opening brace and key
0112                 write_xml_indent(stream,indent,settings);
0113                 stream << Ch('<') << key;
0114 
0115                 // Write attributes
0116                 if (optional<const Ptree &> attribs = pt.get_child_optional(xmlattr<Str>()))
0117                     for (It it = attribs.get().begin(); it != attribs.get().end(); ++it)
0118                         stream << Ch(' ') << it->first << Ch('=')
0119                                << Ch('"')
0120                                << encode_char_entities(
0121                                     it->second.template get_value<Str>())
0122                                << Ch('"');
0123 
0124                 if ( has_attrs_only )
0125                 {
0126                     // Write closing brace
0127                     stream << Ch('/') << Ch('>');
0128                     if (want_pretty)
0129                         stream << Ch('\n');
0130                 }
0131                 else
0132                 {
0133                     // Write closing brace
0134                     stream << Ch('>');
0135 
0136                     // Break line if needed and if we want pretty-printing
0137                     if (has_elements && want_pretty)
0138                         stream << Ch('\n');
0139                 }
0140             }
0141 
0142             // Write data text, if present
0143             if (!pt.data().empty())
0144                 write_xml_text(stream,
0145                     pt.template get_value<Str>(),
0146                     indent + 1, has_elements && want_pretty, settings);
0147 
0148             // Write elements, comments and texts
0149             for (It it = pt.begin(); it != pt.end(); ++it)
0150             {
0151                 if (it->first == xmlattr<Str>())
0152                     continue;
0153                 else if (it->first == xmlcomment<Str>())
0154                     write_xml_comment(stream,
0155                         it->second.template get_value<Str>(),
0156                         indent + 1, want_pretty, settings);
0157                 else if (it->first == xmltext<Str>())
0158                     write_xml_text(stream,
0159                         it->second.template get_value<Str>(),
0160                         indent + 1, has_elements && want_pretty, settings);
0161                 else
0162                     write_xml_element(stream, it->first, it->second,
0163                         indent + 1, settings);
0164             }
0165 
0166             // Write closing tag
0167             if (indent >= 0 && !has_attrs_only)
0168             {
0169                 if (has_elements)
0170                     write_xml_indent(stream,indent,settings);
0171                 stream << Ch('<') << Ch('/') << key << Ch('>');
0172                 if (want_pretty)
0173                     stream << Ch('\n');
0174             }
0175 
0176         }
0177     }
0178 
0179     template<class Ptree>
0180     void write_xml_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream, 
0181                             const Ptree &pt,
0182                             const std::string &filename,
0183                             const xml_writer_settings<typename Ptree::key_type> & settings)
0184     {
0185         typedef typename Ptree::key_type Str;
0186         stream  << detail::widen<Str>("<?xml version=\"1.0\" encoding=\"")
0187                 << settings.encoding
0188                 << detail::widen<Str>("\"?>\n");
0189         write_xml_element(stream, Str(), pt, -1, settings);
0190         stream.flush();
0191         if (!stream)
0192             BOOST_PROPERTY_TREE_THROW(xml_parser_error("write error", filename, 0));
0193     }
0194 
0195 } } }
0196 
0197 #endif