PageRenderTime 26ms CodeModel.GetById 11ms app.highlight 12ms RepoModel.GetById 2ms app.codeStats 0ms

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

http://hadesmem.googlecode.com/
C++ Header | 147 lines | 109 code | 19 blank | 19 comment | 44 complexity | a96a6579cb71f2cd2fc3ffd8cc980382 MD5 | raw file
  1// ----------------------------------------------------------------------------
  2// Copyright (C) 2002-2006 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_INFO_PARSER_WRITE_HPP_INCLUDED
 11#define BOOST_PROPERTY_TREE_DETAIL_INFO_PARSER_WRITE_HPP_INCLUDED
 12
 13#include "boost/property_tree/ptree.hpp"
 14#include "boost/property_tree/detail/info_parser_utils.hpp"
 15#include <string>
 16
 17namespace boost { namespace property_tree { namespace info_parser
 18{
 19    template<class Ch>
 20    void write_info_indent(std::basic_ostream<Ch> &stream,
 21          int indent,
 22          const info_writer_settings<Ch> &settings
 23          )
 24    {
 25        stream << std::basic_string<Ch>(indent * settings.indent_count, settings.indent_char);
 26    }
 27    
 28    // Create necessary escape sequences from illegal characters
 29    template<class Ch>
 30    std::basic_string<Ch> create_escapes(const std::basic_string<Ch> &s)
 31    {
 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();
 35        while (b != e)
 36        {
 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('\\');
 46            else
 47                result += *b;
 48            ++b;
 49        }
 50        return result;
 51    }
 52
 53    template<class Ch>
 54    bool is_simple_key(const std::basic_string<Ch> &key)
 55    {
 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;
 58    }
 59    
 60    template<class Ch>
 61    bool is_simple_data(const std::basic_string<Ch> &data)
 62    {
 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;
 65    }
 66
 67    template<class Ptree>
 68    void write_info_helper(std::basic_ostream<typename Ptree::key_type::value_type> &stream, 
 69                           const Ptree &pt, 
 70                           int indent,
 71                           const info_writer_settings<typename Ptree::key_type::value_type> &settings)
 72    {
 73
 74        // Character type
 75        typedef typename Ptree::key_type::value_type Ch;
 76        
 77        // Write data
 78        if (indent >= 0)
 79        {
 80            if (!pt.data().empty())
 81            {
 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');
 85                else
 86                    stream << Ch(' ') << Ch('\"') << data << Ch('\"') << Ch('\n');
 87            }
 88            else if (pt.empty())
 89                stream << Ch(' ') << Ch('\"') << Ch('\"') << Ch('\n');
 90            else
 91                stream << Ch('\n');
 92        }
 93        
 94        // Write keys
 95        if (!pt.empty())
 96        {
 97            
 98            // Open brace
 99            if (indent >= 0)
100            {
101                write_info_indent( stream, indent, settings);
102                stream << Ch('{') << Ch('\n');
103            }
104            
105            // Write keys
106            typename Ptree::const_iterator it = pt.begin();
107            for (; it != pt.end(); ++it)
108            {
109
110                // Output key
111                std::basic_string<Ch> key = create_escapes(it->first);
112                write_info_indent( stream, indent+1, settings);
113                if (is_simple_key(key))
114                    stream << key;
115                else
116                    stream << Ch('\"') << key << Ch('\"');
117
118                // Output data and children  
119                write_info_helper(stream, it->second, indent + 1, settings);
120
121            }
122            
123            // Close brace
124            if (indent >= 0)
125            {
126                write_info_indent( stream, indent, settings);
127                stream << Ch('}') << Ch('\n');
128            }
129
130        }
131    }
132
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, 
136                             const Ptree &pt,
137                             const std::string &filename,
138                             const info_writer_settings<typename Ptree::key_type::value_type> &settings)
139    {
140        write_info_helper(stream, pt, -1, settings);
141        if (!stream.good())
142            BOOST_PROPERTY_TREE_THROW(info_parser_error("write error", filename, 0));
143    }
144
145} } }
146
147#endif