CLAW Library (a C++ Library Absolutely Wonderful) 1.5.5
|
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-2010 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@yahoo.fr 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 { 00042 class configuration_file 00043 { 00044 public: 00046 struct syntax_description 00047 { 00048 public: 00050 typedef std::pair<char, char> paired_symbol; 00051 00052 public: 00053 syntax_description(); 00054 00055 std::string make_comment( const std::string& value ) const; 00056 std::string make_assignment 00057 ( const std::string& key, const std::string& value ) const; 00058 std::string make_section_name( const std::string& name ) const; 00059 00060 public: 00062 char comment; 00063 00065 char assignment; 00066 00068 paired_symbol section_name; 00069 00070 }; // struct syntax_descritpion 00071 00072 private: 00074 typedef std::multimap<std::string, std::string> section_content; 00075 00077 typedef std::map<std::string, section_content> file_content; 00078 00080 typedef section_content* section_content_ptr; 00081 00082 public: 00084 typedef claw::wrapped_iterator 00085 < const file_content::key_type, 00086 file_content::const_iterator, 00087 const_pair_first<file_content::value_type> 00088 >::iterator_type const_file_iterator; 00089 00091 typedef claw::wrapped_iterator 00092 < const section_content::key_type, 00093 section_content::const_iterator, 00094 const_pair_first<section_content::value_type> 00095 >::iterator_type const_section_iterator; 00096 00100 class const_field_iterator 00101 { 00102 private: 00104 typedef section_content::const_iterator wrapped_iterator_type; 00105 00106 public: 00107 typedef std::string value_type; 00108 typedef const value_type& reference; 00109 typedef const value_type* pointer; 00110 typedef wrapped_iterator_type::difference_type difference_type; 00111 00112 typedef wrapped_iterator_type::iterator_category iterator_category; 00113 00114 public: 00115 const_field_iterator() {} 00116 const_field_iterator( wrapped_iterator_type it ) : m_iterator(it) {} 00117 00118 bool operator==( const const_field_iterator& that ) const 00119 { 00120 return m_iterator == that.m_iterator; 00121 } // operator==() 00122 00123 bool operator!=( const const_field_iterator& that ) const 00124 { 00125 return m_iterator != that.m_iterator; 00126 } // operator!=() 00127 00128 const_field_iterator& operator++() 00129 { 00130 ++m_iterator; 00131 return *this; 00132 } // operator++() 00133 00134 const_field_iterator operator++(int) 00135 { 00136 const_field_iterator tmp(*this); 00137 ++m_iterator; 00138 return tmp; 00139 } // operator++() [post] 00140 00141 const_field_iterator& operator--() 00142 { 00143 --m_iterator; 00144 return *this; 00145 } // operator--() 00146 00147 const_field_iterator operator--(int) 00148 { 00149 const_field_iterator tmp(*this); 00150 --m_iterator; 00151 return tmp; 00152 } // operator--() [post] 00153 00154 reference operator*() const 00155 { 00156 return m_iterator->second; 00157 } // operator*() 00158 00159 pointer operator->() const 00160 { 00161 return &m_iterator->second; 00162 } // operator->() 00163 00164 private: 00166 wrapped_iterator_type m_iterator; 00167 00168 }; // class const_field_iterator 00169 00170 public: 00171 configuration_file(); 00172 configuration_file 00173 (std::istream& is, const syntax_description& syntax = syntax_description()); 00174 00175 bool open 00176 (std::istream& is, const syntax_description& syntax = syntax_description()); 00177 void save 00178 (std::ostream& os, const syntax_description& syntax = syntax_description()); 00179 00180 const std::string& 00181 operator()( const std::string& section, const std::string& field ) const; 00182 00183 const std::string& operator()( const std::string& field ) const; 00184 00185 bool has_field 00186 ( const std::string& section, const std::string& field ) const; 00187 bool has_field( const std::string& field ) const; 00188 00189 void set_value 00190 ( const std::string& section, const std::string& field, 00191 const std::string& val ); 00192 void set_value( const std::string& field, const std::string& val ); 00193 00194 void add_value 00195 ( const std::string& section, const std::string& field, 00196 const std::string& val ); 00197 void add_value( const std::string& field, const std::string& val ); 00198 00199 void clear_section( const std::string& section ); 00200 00201 const_field_iterator 00202 field_begin( const std::string& section, const std::string& field ) const; 00203 const_field_iterator 00204 field_end( const std::string& section, const std::string& field ) const; 00205 00206 const_field_iterator field_begin( const std::string& field ) const; 00207 const_field_iterator field_end( const std::string& field ) const; 00208 00209 const_section_iterator section_begin() const; 00210 const_section_iterator section_end() const; 00211 00212 const_section_iterator section_begin( const std::string& section ) const; 00213 const_section_iterator section_end( const std::string& section ) const; 00214 00215 const_file_iterator file_begin() const; 00216 const_file_iterator file_end() const; 00217 00218 private: 00219 bool get_line( std::istream& is, const syntax_description& syntax, 00220 std::string& line ) const; 00221 bool 00222 process_line( const std::string& line, const syntax_description& syntax, 00223 section_content_ptr& section ); 00224 00225 void escape_line( std::istream& is, const syntax_description& syntax, 00226 std::string& line ) const; 00227 00228 void escape_char 00229 ( char escaped, const syntax_description& syntax, std::string& str ) const; 00230 00231 void save_section_content 00232 ( const section_content& c, std::ostream& os, 00233 const syntax_description& syntax ) const; 00234 00235 private: 00237 section_content m_noname_section; 00238 00240 file_content m_sections; 00241 00243 static const std::string s_unknow_field_value; 00244 00245 }; // class configuration_file 00246 } // namespace claw 00247 00248 #endif // __CLAW_CONFIGURATION_FILE_HPP__