PageRenderTime 93ms CodeModel.GetById 77ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/property_tree/detail/xml_parser_read_rapidxml.hpp

http://hadesmem.googlecode.com/
C++ Header | 144 lines | 108 code | 15 blank | 21 comment | 12 complexity | ae743b8e3d06d4b0affbf8d9d4c7b285 MD5 | raw file
  1// ----------------------------------------------------------------------------
  2// Copyright (C) 2007 Marcin Kalicinski
  3//
  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)
  7//
  8// For more information, see www.boost.org
  9// ----------------------------------------------------------------------------
 10#ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
 11#define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_READ_RAPIDXML_HPP_INCLUDED
 12
 13#include <boost/property_tree/ptree.hpp>
 14#include <boost/property_tree/detail/xml_parser_error.hpp>
 15#include <boost/property_tree/detail/xml_parser_flags.hpp>
 16#include <boost/property_tree/detail/xml_parser_utils.hpp>
 17#include <boost/property_tree/detail/rapidxml.hpp>
 18#include <vector>
 19
 20namespace boost { namespace property_tree { namespace xml_parser
 21{
 22
 23    template<class Ptree, class Ch>
 24    void read_xml_node(detail::rapidxml::xml_node<Ch> *node,
 25                       Ptree &pt, int flags)
 26    {
 27        using namespace detail::rapidxml;
 28        switch (node->type())
 29        {
 30            // Element nodes
 31            case node_element: 
 32            {
 33                // Create node
 34                Ptree &pt_node = pt.push_back(std::make_pair(node->name(),
 35                                                             Ptree()))->second;
 36
 37                // Copy attributes
 38                if (node->first_attribute())
 39                {
 40                    Ptree &pt_attr_root = pt_node.push_back(
 41                        std::make_pair(xmlattr<Ch>(), Ptree()))->second;
 42                    for (xml_attribute<Ch> *attr = node->first_attribute();
 43                         attr; attr = attr->next_attribute())
 44                    {
 45                        Ptree &pt_attr = pt_attr_root.push_back(
 46                            std::make_pair(attr->name(), Ptree()))->second;
 47                        pt_attr.data() = attr->value();
 48                    }
 49                }
 50
 51                // Copy children
 52                for (xml_node<Ch> *child = node->first_node();
 53                     child; child = child->next_sibling())
 54                    read_xml_node(child, pt_node, flags);
 55            }
 56            break;
 57
 58            // Data nodes
 59            case node_data:
 60            case node_cdata:
 61            {
 62                if (flags & no_concat_text)
 63                    pt.push_back(std::make_pair(xmltext<Ch>(),
 64                                                Ptree(node->value())));
 65                else
 66                    pt.data() += node->value();
 67            }
 68            break;
 69
 70            // Comment nodes
 71            case node_comment:
 72            {
 73                if (!(flags & no_comments))
 74                    pt.push_back(std::make_pair(xmlcomment<Ch>(),
 75                                                Ptree(node->value())));
 76            }
 77            break;
 78
 79            default:
 80                // Skip other node types
 81                break;
 82        }
 83    }
 84
 85    template<class Ptree>
 86    void read_xml_internal(std::basic_istream<
 87                               typename Ptree::key_type::value_type> &stream,
 88                           Ptree &pt,
 89                           int flags,
 90                           const std::string &filename)
 91    {
 92        typedef typename Ptree::key_type::value_type Ch;
 93        using namespace detail::rapidxml;
 94
 95        // Load data into vector
 96        stream.unsetf(std::ios::skipws);
 97        std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
 98                          std::istreambuf_iterator<Ch>());
 99        if (!stream.good())
100            BOOST_PROPERTY_TREE_THROW(
101                xml_parser_error("read error", filename, 0));
102        v.push_back(0); // zero-terminate
103
104        try {
105            // Parse using appropriate flags
106            const int f_tws = parse_normalize_whitespace
107                            | parse_trim_whitespace;
108            const int f_c = parse_comment_nodes;
109            // Some compilers don't like the bitwise or in the template arg.
110            const int f_tws_c = parse_normalize_whitespace
111                              | parse_trim_whitespace
112                              | parse_comment_nodes;
113            xml_document<Ch> doc;
114            if (flags & no_comments) {
115                if (flags & trim_whitespace)
116                    doc.BOOST_NESTED_TEMPLATE parse<f_tws>(&v.front());
117                else
118                    doc.BOOST_NESTED_TEMPLATE parse<0>(&v.front());
119            } else {
120                if (flags & trim_whitespace)
121                    doc.BOOST_NESTED_TEMPLATE parse<f_tws_c>(&v.front());
122                else
123                    doc.BOOST_NESTED_TEMPLATE parse<f_c>(&v.front());
124            }
125
126            // Create ptree from nodes
127            Ptree local;
128            for (xml_node<Ch> *child = doc.first_node();
129                 child; child = child->next_sibling())
130                read_xml_node(child, local, flags);
131
132            // Swap local and result ptrees
133            pt.swap(local);
134        } catch (parse_error &e) {
135            long line = static_cast<long>(
136                std::count(&v.front(), e.where<Ch>(), Ch('\n')) + 1);
137            BOOST_PROPERTY_TREE_THROW(
138                xml_parser_error(e.what(), filename, line));  
139        }
140    }
141
142} } }
143
144#endif