libs/property_tree/examples/debug_settings.cpp
// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <string>
#include <set>
#include <exception>
#include <iostream>
struct debug_settings
{
std::string m_file; // log filename
int m_level; // debug level
std::set<std::string> m_modules; // modules where logging is enabled
void load(const std::string &filename);
void save(const std::string &filename);
};
void debug_settings::load(const std::string &filename)
{
// Create empty property tree object
using boost::property_tree::ptree;
ptree pt;
// Load XML file and put its contents in property tree.
// No namespace qualification is needed, because of Koenig
// lookup on the second argument. If reading fails, exception
// is thrown.
read_xml(filename, pt);
// Get filename and store it in m_file variable. Note that
// we specify a path to the value using notation where keys
// are separated with dots (different separator may be used
// if keys themselves contain dots). If debug.filename key is
// not found, exception is thrown.
m_file = pt.get<std::string>("debug.filename");
// Get debug level and store it in m_level variable. This is
// another version of get method: if debug.level key is not
// found, it will return default value (specified by second
// parameter) instead of throwing. Type of the value extracted
// is determined by type of second parameter, so we can simply
// write get(...) instead of get<int>(...).
m_level = pt.get("debug.level", 0);
// Iterate over debug.modules section and store all found
// modules in m_modules set. get_child() function returns a
// reference to child at specified path; if there is no such
// child, it throws. Property tree iterator can be used in
// the same way as standard container iterator. Category
// is bidirectional_iterator.
BOOST_FOREACH(ptree::value_type &v, pt.get_child("debug.modules"))
m_modules.insert(v.second.data());
}
void debug_settings::save(const std::string &filename)
{
// Create empty property tree object
using boost::property_tree::ptree;
ptree pt;
// Put log filename in property tree
pt.put("debug.filename", m_file);
// Put debug level in property tree
pt.put("debug.level", m_level);
// Iterate over modules in set and put them in property
// tree. Note that the add function places new key at the
// end of list of keys. This is fine in most of the
// situations. If you want to place item at some other
// place (i.e. at front or somewhere in the middle),
// this can be achieved using a combination of the insert
// and put_value functions
BOOST_FOREACH(const std::string &name, m_modules)
pt.add("debug.modules.module", name);
// Write property tree to XML file
write_xml(filename, pt);
}
int main()
{
try
{
debug_settings ds;
ds.load("debug_settings.xml");
ds.save("debug_settings_out.xml");
std::cout << "Success\n";
}
catch (std::exception &e)
{
std::cout << "Error: " << e.what() << "\n";
}
return 0;
}