Claw
1.7.3
|
00001 /* 00002 CLAW - a C++ Library Absolutely Wonderful 00003 00004 CLAW is a free library without any particular aim but being useful to 00005 anyone. 00006 00007 Copyright (C) 2005-2011 Julien Jorge 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public 00020 License along with this library; if not, write to the Free Software 00021 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00022 00023 contact: julien.jorge@gamned.org 00024 */ 00030 #ifndef __CLAW_CONFIGURATION_FILE_HPP__ 00031 #define __CLAW_CONFIGURATION_FILE_HPP__ 00032 00033 #include <claw/iterator.hpp> 00034 #include <claw/functional.hpp> 00035 00036 #include <iostream> 00037 #include <map> 00038 #include <string> 00039 00040 namespace claw 00041 { 00046 class configuration_file 00047 { 00048 public: 00050 struct syntax_description 00051 { 00052 public: 00054 typedef std::pair<char, char> paired_symbol; 00055 00056 public: 00057 syntax_description(); 00058 00059 std::string make_comment( const std::string& value ) const; 00060 std::string make_assignment 00061 ( const std::string& key, const std::string& value ) const; 00062 std::string make_section_name( const std::string& name ) const; 00063 00064 public: 00066 char comment; 00067 00069 char assignment; 00070 00072 paired_symbol section_name; 00073 00074 }; // struct syntax_descritpion 00075 00076 private: 00078 typedef std::multimap<std::string, std::string> section_content; 00079 00081 typedef std::map<std::string, section_content> file_content; 00082 00084 typedef section_content* section_content_ptr; 00085 00086 public: 00088 typedef claw::wrapped_iterator 00089 < const file_content::key_type, 00090 file_content::const_iterator, 00091 const_pair_first<file_content::value_type> 00092 >::iterator_type const_file_iterator; 00093 00095 typedef claw::wrapped_iterator 00096 < const section_content::key_type, 00097 section_content::const_iterator, 00098 const_pair_first<section_content::value_type> 00099 >::iterator_type const_section_iterator; 00100 00104 class const_field_iterator 00105 { 00106 private: 00108 typedef section_content::const_iterator wrapped_iterator_type; 00109 00110 public: 00111 typedef std::string value_type; 00112 typedef const value_type& reference; 00113 typedef const value_type* pointer; 00114 typedef wrapped_iterator_type::difference_type difference_type; 00115 00116 typedef wrapped_iterator_type::iterator_category iterator_category; 00117 00118 public: 00119 const_field_iterator() {} 00120 const_field_iterator( wrapped_iterator_type it ) : m_iterator(it) {} 00121 00122 bool operator==( const const_field_iterator& that ) const 00123 { 00124 return m_iterator == that.m_iterator; 00125 } // operator==() 00126 00127 bool operator!=( const const_field_iterator& that ) const 00128 { 00129 return m_iterator != that.m_iterator; 00130 } // operator!=() 00131 00132 const_field_iterator& operator++() 00133 { 00134 ++m_iterator; 00135 return *this; 00136 } // operator++() 00137 00138 const_field_iterator operator++(int) 00139 { 00140 const_field_iterator tmp(*this); 00141 ++m_iterator; 00142 return tmp; 00143 } // operator++() [post] 00144 00145 const_field_iterator& operator--() 00146 { 00147 --m_iterator; 00148 return *this; 00149 } // operator--() 00150 00151 const_field_iterator operator--(int) 00152 { 00153 const_field_iterator tmp(*this); 00154 --m_iterator; 00155 return tmp; 00156 } // operator--() [post] 00157 00158 reference operator*() const 00159 { 00160 return m_iterator->second; 00161 } // operator*() 00162 00163 pointer operator->() const 00164 { 00165 return &m_iterator->second; 00166 } // operator->() 00167 00168 private: 00170 wrapped_iterator_type m_iterator; 00171 00172 }; // class const_field_iterator 00173 00174 public: 00175 configuration_file(); 00176 configuration_file 00177 (std::istream& is, const syntax_description& syntax = syntax_description()); 00178 00179 bool open 00180 (std::istream& is, const syntax_description& syntax = syntax_description()); 00181 void save 00182 (std::ostream& os, const syntax_description& syntax = syntax_description()); 00183 00184 const std::string& 00185 operator()( const std::string& section, const std::string& field ) const; 00186 00187 const std::string& operator()( const std::string& field ) const; 00188 00189 bool has_field 00190 ( const std::string& section, const std::string& field ) const; 00191 bool has_field( const std::string& field ) const; 00192 00193 void set_value 00194 ( const std::string& section, const std::string& field, 00195 const std::string& val ); 00196 void set_value( const std::string& field, const std::string& val ); 00197 00198 void add_value 00199 ( const std::string& section, const std::string& field, 00200 const std::string& val ); 00201 void add_value( const std::string& field, const std::string& val ); 00202 00203 void clear_section( const std::string& section ); 00204 00205 const_field_iterator 00206 field_begin( const std::string& section, const std::string& field ) const; 00207 const_field_iterator 00208 field_end( const std::string& section, const std::string& field ) const; 00209 00210 const_field_iterator field_begin( const std::string& field ) const; 00211 const_field_iterator field_end( const std::string& field ) const; 00212 00213 const_section_iterator section_begin() const; 00214 const_section_iterator section_end() const; 00215 00216 const_section_iterator section_begin( const std::string& section ) const; 00217 const_section_iterator section_end( const std::string& section ) const; 00218 00219 const_file_iterator file_begin() const; 00220 const_file_iterator file_end() const; 00221 00222 private: 00223 bool get_line( std::istream& is, const syntax_description& syntax, 00224 std::string& line ) const; 00225 bool 00226 process_line( const std::string& line, const syntax_description& syntax, 00227 section_content_ptr& section ); 00228 00229 void escape_line( std::istream& is, const syntax_description& syntax, 00230 std::string& line ) const; 00231 00232 void escape_char 00233 ( char escaped, const syntax_description& syntax, std::string& str ) const; 00234 00235 void save_section_content 00236 ( const section_content& c, std::ostream& os, 00237 const syntax_description& syntax ) const; 00238 00239 private: 00241 section_content m_noname_section; 00242 00244 file_content m_sections; 00245 00247 static const std::string s_unknow_field_value; 00248 00249 }; // class configuration_file 00250 } // namespace claw 00251 00252 #endif // __CLAW_CONFIGURATION_FILE_HPP__