00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00030 #ifndef __CLAW_CONFIGURATION_FILE_HPP__
00031 #define __CLAW_CONFIGURATION_FILE_HPP__
00032
00033 #include <iostream>
00034 #include <map>
00035 #include <string>
00036
00037 namespace claw
00038 {
00039 class configuration_file
00040 {
00041 public:
00043 struct syntax_description
00044 {
00045 public:
00047 typedef std::pair<char, char> paired_symbol;
00048
00049 public:
00050 syntax_description();
00051
00053 char comment;
00054
00056 char assignment;
00057
00059 paired_symbol section_name;
00060
00061 };
00062
00063 private:
00065 typedef std::multimap<std::string, std::string> section_content;
00066
00068 typedef std::map<std::string, section_content> file_content;
00069
00071 typedef section_content* section_content_ptr;
00072
00073 public:
00077 class const_field_iterator
00078 {
00079 private:
00081 typedef section_content::const_iterator wrapped_iterator_type;
00082
00083 public:
00084 typedef std::string value_type;
00085 typedef const value_type& reference;
00086 typedef const value_type* pointer;
00087 typedef wrapped_iterator_type::difference_type difference_type;
00088
00089 typedef wrapped_iterator_type::iterator_category iterator_category;
00090
00091 public:
00092 const_field_iterator() {}
00093 const_field_iterator( wrapped_iterator_type it ) : m_iterator(it) {}
00094
00095 bool operator==( const const_field_iterator& that ) const
00096 {
00097 return m_iterator == that.m_iterator;
00098 }
00099
00100 bool operator!=( const const_field_iterator& that ) const
00101 {
00102 return m_iterator != that.m_iterator;
00103 }
00104
00105 const_field_iterator& operator++()
00106 {
00107 ++m_iterator;
00108 return *this;
00109 }
00110
00111 const_field_iterator operator++(int)
00112 {
00113 const_field_iterator tmp(*this);
00114 ++m_iterator;
00115 return tmp;
00116 }
00117
00118 const_field_iterator& operator--()
00119 {
00120 --m_iterator;
00121 return *this;
00122 }
00123
00124 const_field_iterator operator--(int)
00125 {
00126 const_field_iterator tmp(*this);
00127 --m_iterator;
00128 return tmp;
00129 }
00130
00131 reference operator*() const
00132 {
00133 return m_iterator->second;
00134 }
00135
00136 pointer operator->() const
00137 {
00138 return &m_iterator->second;
00139 }
00140
00141 private:
00143 wrapped_iterator_type m_iterator;
00144
00145 };
00146
00147 public:
00148 configuration_file();
00149 configuration_file
00150 (std::istream& is, const syntax_description& syntax = syntax_description());
00151
00152 bool open
00153 (std::istream& is, const syntax_description& syntax = syntax_description());
00154
00155 const std::string&
00156 operator()( const std::string& section, const std::string& field ) const;
00157
00158 const std::string& operator()( const std::string& field ) const;
00159
00160 const_field_iterator
00161 field_begin( const std::string& section, const std::string& field ) const;
00162 const_field_iterator
00163 field_end( const std::string& section, const std::string& field ) const;
00164
00165 const_field_iterator field_begin( const std::string& field ) const;
00166 const_field_iterator field_end( const std::string& field ) const;
00167
00168 private:
00169 bool get_line( std::istream& is, const syntax_description& syntax,
00170 std::string& line ) const;
00171 bool
00172 process_line( const std::string& line, const syntax_description& syntax,
00173 section_content_ptr& section );
00174
00175 void escape_line( std::istream& is, const syntax_description& syntax,
00176 std::string& line ) const;
00177
00178 void escape_char
00179 ( char escaped, const syntax_description& syntax, std::string& str ) const;
00180
00181 private:
00183 section_content m_noname_section;
00184
00186 file_content m_sections;
00187
00189 static const std::string s_unknow_field_value;
00190
00191 };
00192 }
00193
00194 #endif // __CLAW_CONFIGURATION_FILE_HPP__