Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // ----------------------------------------------------------------------------
0002 // Copyright (C) 2007 Marcin Kalicinski
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. 
0005 // (See accompanying file LICENSE_1_0.txt or copy at 
0006 // http://www.boost.org/LICENSE_1_0.txt)
0007 //
0008 // For more information, see www.boost.org
0009 // ----------------------------------------------------------------------------
0010 #ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
0011 #define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
0012 
0013 #include <boost/property_tree/ptree.hpp>
0014 #include <boost/property_tree/detail/xml_parser_error.hpp>
0015 #include <boost/property_tree/detail/xml_parser_flags.hpp>
0016 #include <boost/property_tree/detail/xml_parser_utils.hpp>
0017 #include <boost/property_tree/detail/rapidxml.hpp>
0018 #include <vector>
0019 
0020 namespace boost { namespace property_tree { namespace xml_parser
0021 {
0022 
0023     template<class Ptree, class Ch>
0024     void read_xml_node(detail::rapidxml::xml_node<Ch> *node,
0025                        Ptree &pt, int flags)
0026     {
0027         using namespace detail::rapidxml;
0028         switch (node->type())
0029         {
0030             // Element nodes
0031             case node_element: 
0032             {
0033                 // Create node
0034                 Ptree &pt_node = pt.push_back(std::make_pair(node->name(),
0035                                                              Ptree()))->second;
0036 
0037                 // Copy attributes
0038                 if (node->first_attribute())
0039                 {
0040                     Ptree &pt_attr_root = pt_node.push_back(
0041                         std::make_pair(xmlattr<typename Ptree::key_type>(), Ptree()))->second;
0042                     for (xml_attribute<Ch> *attr = node->first_attribute();
0043                          attr; attr = attr->next_attribute())
0044                     {
0045                         Ptree &pt_attr = pt_attr_root.push_back(
0046                             std::make_pair(attr->name(), Ptree()))->second;
0047                         pt_attr.data() = typename Ptree::key_type(attr->value(), attr->value_size());
0048                     }
0049                 }
0050 
0051                 // Copy children
0052                 for (xml_node<Ch> *child = node->first_node();
0053                      child; child = child->next_sibling())
0054                     read_xml_node(child, pt_node, flags);
0055             }
0056             break;
0057 
0058             // Data nodes
0059             case node_data:
0060             case node_cdata:
0061             {
0062                 if (flags & no_concat_text)
0063                     pt.push_back(std::make_pair(xmltext<typename Ptree::key_type>(),
0064                                                 Ptree(node->value())));
0065                 else
0066                     pt.data() += typename Ptree::key_type(node->value(), node->value_size());
0067             }
0068             break;
0069 
0070             // Comment nodes
0071             case node_comment:
0072             {
0073                 if (!(flags & no_comments))
0074                     pt.push_back(std::make_pair(xmlcomment<typename Ptree::key_type>(),
0075                                     Ptree(typename Ptree::key_type(node->value(), node->value_size()))));
0076             }
0077             break;
0078 
0079             default:
0080                 // Skip other node types
0081                 break;
0082         }
0083     }
0084 
0085     template<class Ptree>
0086     void read_xml_internal(std::basic_istream<
0087                                typename Ptree::key_type::value_type> &stream,
0088                            Ptree &pt,
0089                            int flags,
0090                            const std::string &filename)
0091     {
0092         typedef typename Ptree::key_type::value_type Ch;
0093         using namespace detail::rapidxml;
0094 
0095         // Load data into vector
0096         stream.unsetf(std::ios::skipws);
0097         std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
0098                           std::istreambuf_iterator<Ch>());
0099         if (!stream.good())
0100             BOOST_PROPERTY_TREE_THROW(
0101                 xml_parser_error("read error", filename, 0));
0102         v.push_back(0); // zero-terminate
0103 
0104         try {
0105             // Parse using appropriate flags
0106             const int f_tws = parse_normalize_whitespace
0107                             | parse_trim_whitespace;
0108             const int f_c = parse_comment_nodes;
0109             // Some compilers don't like the bitwise or in the template arg.
0110             const int f_tws_c = parse_normalize_whitespace
0111                               | parse_trim_whitespace
0112                               | parse_comment_nodes;
0113             xml_document<Ch> doc;
0114             if (flags & no_comments) {
0115                 if (flags & trim_whitespace)
0116                     doc.BOOST_NESTED_TEMPLATE parse<f_tws>(&v.front());
0117                 else
0118                     doc.BOOST_NESTED_TEMPLATE parse<0>(&v.front());
0119             } else {
0120                 if (flags & trim_whitespace)
0121                     doc.BOOST_NESTED_TEMPLATE parse<f_tws_c>(&v.front());
0122                 else
0123                     doc.BOOST_NESTED_TEMPLATE parse<f_c>(&v.front());
0124             }
0125 
0126             // Create ptree from nodes
0127             Ptree local;
0128             for (xml_node<Ch> *child = doc.first_node();
0129                  child; child = child->next_sibling())
0130                 read_xml_node(child, local, flags);
0131 
0132             // Swap local and result ptrees
0133             pt.swap(local);
0134         } catch (parse_error &e) {
0135             long line = static_cast<long>(
0136                 std::count(&v.front(), e.where<Ch>(), Ch('\n')) + 1);
0137             BOOST_PROPERTY_TREE_THROW(
0138                 xml_parser_error(e.what(), filename, line));  
0139         }
0140     }
0141 
0142 } } }
0143 
0144 #endif