config.hpp

Go to the documentation of this file.
00001 /* $Id: config.hpp 25673 2008-04-08 06:12:24Z sapient $ */
00002 /*
00003    Copyright (C) 2003 - 2008 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License version 2
00008    or at your option any later version.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 //! @file config.hpp
00016 //! Definitions for the interface to Wesnoth Markup Language (WML).
00017 
00018 #ifndef CONFIG_HPP_INCLUDED
00019 #define CONFIG_HPP_INCLUDED
00020 
00021 #include "global.hpp"
00022 
00023 #include <map>
00024 #include <memory>
00025 #include <ostream>
00026 #include <string>
00027 #include <vector>
00028 #include "tstring.hpp"
00029 #include "serialization/string_utils.hpp"
00030 
00031 
00032 // This module defines the interface to Wesnoth Markup Language (WML).
00033 // WML is a simple hierarchical text-based file format.
00034 // The format is defined in Wiki, under BuildingScenariosWML
00035 //
00036 // All configuration files are stored in this format,
00037 // and data is sent across the network in this format.
00038 // It is thus used extensively throughout the game.
00039 
00040 typedef std::map<std::string,t_string> string_map;
00041 
00042 //! A config object defines a single node in a WML file, with access to child nodes.
00043 class config
00044 {
00045 public:
00046     // Create an empty node.
00047     config();
00048 
00049     config(const config& cfg);
00050 
00051     // Create a config with an empty child of name 'child'.
00052     config(const std::string& child);
00053     ~config();
00054 
00055     config& operator=(const config& cfg);
00056 
00057     typedef std::vector<config*> child_list;
00058     typedef std::map<std::string,child_list> child_map;
00059 
00060     typedef std::vector<config*>::iterator child_iterator;
00061     typedef std::vector<config*>::const_iterator const_child_iterator;
00062 
00063     typedef std::pair<child_iterator,child_iterator> child_itors;
00064     typedef std::pair<const_child_iterator,const_child_iterator> const_child_itors;
00065 
00066     child_itors child_range(const std::string& key);
00067     const_child_itors child_range(const std::string& key) const;
00068 
00069     const child_list& get_children(const std::string& key) const;
00070     const child_map& all_children() const;
00071 
00072     config* child(const std::string& key);
00073     const config* child(const std::string& key) const;
00074     config& add_child(const std::string& key);
00075     config& add_child(const std::string& key, const config& val);
00076     config& add_child_at(const std::string& key, const config& val, size_t index);
00077     t_string& operator[](const std::string& key);
00078     const t_string& operator[](const std::string& key) const;
00079 
00080     const t_string& get_attribute(const std::string& key) const;
00081     bool has_attribute(const std::string& key) const {return values.find(key) != values.end();}
00082 
00083     config* find_child(const std::string& key, const std::string& name,
00084                        const t_string& value);
00085     const config* find_child(const std::string& key, const std::string& name,
00086                              const t_string& value) const;
00087 
00088     void clear_children(const std::string& key);
00089     void remove_child(const std::string& key, size_t index);
00090     void recursive_clear_value(const std::string& key);
00091 
00092     void clear();
00093     bool empty() const;
00094 
00095     std::string debug() const;
00096     std::string hash() const;
00097 
00098     struct error {
00099         error(const std::string& msg) : message(msg) {}
00100         std::string message;
00101     };
00102 
00103     struct child_pos {
00104         child_pos(child_map::const_iterator p, size_t i) : pos(p), index(i) {}
00105         child_map::const_iterator pos;
00106         size_t index;
00107 
00108         bool operator==(const child_pos& o) const { return pos == o.pos && index == o.index; }
00109         bool operator!=(const child_pos& o) const { return !operator==(o); }
00110     };
00111 
00112     struct all_children_iterator {
00113         typedef std::pair<const std::string*,const config*> value_type;
00114         typedef std::forward_iterator_tag iterator_category;
00115         typedef int difference_type;
00116         typedef std::auto_ptr<value_type> pointer;
00117         typedef value_type& reference;
00118         typedef std::vector<child_pos>::const_iterator Itor;
00119         explicit all_children_iterator(Itor i=Itor());
00120 
00121         all_children_iterator& operator++();
00122         all_children_iterator  operator++(int);
00123 
00124         value_type operator*() const;
00125         pointer operator->() const;
00126 
00127         const std::string& get_key() const;
00128         size_t get_index() const;
00129         const config& get_child() const;
00130 
00131         bool operator==(all_children_iterator i) const;
00132         bool operator!=(all_children_iterator i) const;
00133 
00134     private:
00135         Itor i_;
00136     };
00137 
00138     //! In-order iteration over all children.
00139     all_children_iterator ordered_begin() const;
00140     all_children_iterator ordered_end() const;
00141     all_children_iterator erase(const all_children_iterator& i);
00142 
00143     //! A function to get the differences between this object,
00144     //! and 'c', as another config object.
00145     //! I.e. calling cfg2.apply_diff(cfg1.get_diff(cfg2))
00146     //! will make cfg1 identical to cfg2.
00147     config get_diff(const config& c) const;
00148     void get_diff(const config& c, config& res) const;
00149 
00150     void apply_diff(const config& diff); //throw error
00151 
00152     //! Merge config 'c' into this config.
00153     //! Overwrites this config's values.
00154     void merge_with(const config& c);
00155 
00156     //! Merge config 'c' into this config.
00157     //! Keeps this config's values and does not add existing elements.
00158     //! NOTICE: other nonstandard behavior includes no merge recursion into child
00159     //! and has limited merging for child lists of differing lengths
00160     void merge_and_keep(const config& c);
00161 
00162     bool matches(const config &filter) const;
00163 
00164     //! Removes keys with empty values.
00165     void prune();
00166 
00167     //! Append data from another config object to this one.
00168     //! Attributes in the latter config object will clobber attributes in this one.
00169     void append(const config& cfg);
00170 
00171     //! All children with the given key will be merged
00172     //! into the first element with that key.
00173     void merge_children(const std::string& key);
00174 
00175     //! Resets the translated values of all strings contained in this object
00176     void reset_translation() const;
00177 
00178     //this is a cheap O(1) operation
00179     void swap(config& cfg);
00180 
00181     //! All the attributes of this node.
00182     string_map values;
00183 
00184 private:
00185     //! A list of all children of this node.
00186     child_map children;
00187 
00188     std::vector<child_pos> ordered_children;
00189 };
00190 
00191 bool operator==(const config& a, const config& b);
00192 bool operator!=(const config& a, const config& b);
00193 std::ostream& operator << (std::ostream& os, const config& cfg);
00194 
00195 #endif

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs