Claw  1.7.3
configuration_file.hpp
Go to the documentation of this file.
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__