configuration_file.cpp

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-2008 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 #include <claw/configuration_file.hpp>
00031 #include <claw/assert.hpp>
00032 #include <claw/string_algorithm.hpp>
00033 
00034 /*----------------------------------------------------------------------------*/
00038 claw::configuration_file::syntax_description::syntax_description()
00039   : comment('#'), assignment('='), section_name('[', ']')
00040 {
00041 
00042 } // configuration_file::syntax_description::syntax_description()
00043 
00044 
00045 
00046 /*----------------------------------------------------------------------------*/
00047 // empty string
00048 const std::string claw::configuration_file::s_unknow_field_value;
00049 
00050 /*----------------------------------------------------------------------------*/
00054 claw::configuration_file::configuration_file()
00055 {
00056   // nothing to do
00057 } // configuration_file::configuration_file()
00058 
00059 /*----------------------------------------------------------------------------*/
00065 claw::configuration_file::configuration_file
00066 ( std::istream& is, const syntax_description& syntax )
00067 {
00068   open(is, syntax);
00069 } // configuration_file::configuration_file()
00070 
00071 /*----------------------------------------------------------------------------*/
00077 bool claw::configuration_file::open
00078 ( std::istream& is, const syntax_description& syntax )
00079 {
00080   std::string line;
00081   bool ok = true;
00082   section_content_ptr current_section = &m_noname_section;
00083 
00084   while ( get_line(is, syntax, line) && ok )
00085     {
00086       text::trim_right(line, " \t");
00087 
00088       if ( !line.empty() )
00089         ok = process_line( line, syntax, current_section );
00090     }
00091 
00092   return ok;
00093 } // configuration_file::open()
00094 
00095 /*----------------------------------------------------------------------------*/
00101 const std::string& claw::configuration_file::operator()
00102   ( const std::string& section, const std::string& field ) const
00103 {
00104   file_content::const_iterator sect = m_sections.find(section);
00105 
00106   if ( sect == m_sections.end() )
00107     return s_unknow_field_value;
00108   else
00109     {
00110       section_content::const_iterator fld = sect->second.find(field);
00111 
00112       if ( fld == sect->second.end() )
00113         return s_unknow_field_value;
00114       else
00115         return fld->second;
00116     }
00117 } // configuration_file::operator()()
00118 
00119 /*----------------------------------------------------------------------------*/
00126 const std::string&
00127 claw::configuration_file::operator()( const std::string& field ) const
00128 {
00129   section_content::const_iterator fld = m_noname_section.find(field);
00130 
00131   if ( fld == m_noname_section.end() )
00132     return s_unknow_field_value;
00133   else
00134     return fld->second;
00135 } // configuration_file::operator()()
00136 
00137 /*----------------------------------------------------------------------------*/
00143 claw::configuration_file::const_field_iterator
00144 claw::configuration_file::field_begin
00145 ( const std::string& section, const std::string& field ) const
00146 {
00147   file_content::const_iterator it = m_sections.find(section);
00148 
00149   if (it == m_sections.end())
00150     return const_field_iterator();
00151   else
00152     return const_field_iterator( it->second.lower_bound(field) );
00153 } // configuration_file::field_begin()
00154 
00155 /*----------------------------------------------------------------------------*/
00161 claw::configuration_file::const_field_iterator
00162 claw::configuration_file::field_end
00163 ( const std::string& section, const std::string& field ) const
00164 {
00165   file_content::const_iterator it = m_sections.find(section);
00166 
00167   if (it == m_sections.end())
00168     return const_field_iterator();
00169   else
00170     return const_field_iterator( it->second.upper_bound(field) );
00171 } // configuration_file::field_end()
00172 
00173 /*----------------------------------------------------------------------------*/
00180 claw::configuration_file::const_field_iterator
00181 claw::configuration_file::field_begin( const std::string& field ) const
00182 {
00183   return const_field_iterator( m_noname_section.lower_bound(field) );
00184 } // configuration_file::field_begin()
00185 
00186 /*----------------------------------------------------------------------------*/
00193 claw::configuration_file::const_field_iterator
00194 claw::configuration_file::field_end( const std::string& field ) const
00195 {
00196   return const_field_iterator( m_noname_section.upper_bound(field) );
00197 } // configuration_file::field_end()
00198 
00199 /*----------------------------------------------------------------------------*/
00206 bool claw::configuration_file::get_line
00207 ( std::istream& is, const syntax_description& syntax, std::string& line ) const
00208 {
00209   bool result = text::getline(is, line);
00210 
00211   if ( result )
00212     {
00213       text::trim_left(line, " \t");
00214       escape_line(is, syntax, line);
00215     }
00216 
00217   return result;
00218 } // configuration_file::get_line()
00219 
00220 /*----------------------------------------------------------------------------*/
00227 bool claw::configuration_file::process_line
00228 ( const std::string& line, const syntax_description& syntax,
00229   section_content_ptr& section )
00230 {
00231   CLAW_PRECOND( !line.empty() );
00232 
00233   bool result = true;
00234 
00235   if ( (line.size() >= 2)
00236        && (line[0] == syntax.section_name.first)
00237        && ( *(--line.end()) == syntax.section_name.second) )
00238     {
00239       std::string section_name( line.substr(1, line.length()-2) );
00240       text::trim( section_name, " \t" );
00241       section = &m_sections[section_name];
00242     }
00243   else
00244     {
00245       std::string::size_type pos = line.find_first_of(syntax.assignment);
00246 
00247       if (pos != std::string::npos)
00248         {
00249           std::string field( line.substr(0, pos) );
00250           std::string value;
00251 
00252           if ( (pos+1) != line.length() )
00253             {
00254               value = ( line.substr(pos+1) );
00255               text::trim(value, " \t");
00256             }
00257 
00258           text::trim(field, " \t");
00259           section->insert( section_content::value_type(field, value) );
00260         }
00261       else
00262         result = false;
00263     }
00264 
00265   return result;
00266 } // configuration_file::process_line()
00267 
00268 /*----------------------------------------------------------------------------*/
00275 void claw::configuration_file::escape_line
00276 ( std::istream& is, const syntax_description& syntax, std::string& line ) const
00277 {
00278   std::string input_line(line);
00279   std::string::iterator it, last;
00280   bool stop = false;
00281 
00282   line = "";
00283   last = input_line.begin();
00284 
00285   for (it = last; (it!=input_line.end()) && !stop; )
00286     if (*it == syntax.comment)
00287       stop = true;
00288     else if (*it == '\\')
00289       {
00290         line += std::string(last, it);
00291         ++it;
00292 
00293         if ( it == input_line.end() )
00294           {
00295             std::string remaining;
00296             get_line(is, syntax, remaining);
00297             line += remaining;
00298           }
00299         else
00300           {
00301             escape_char(*it, syntax, line);
00302             ++it;
00303           }
00304 
00305         last = it;
00306       }
00307     else
00308       ++it;
00309 
00310   line += std::string(last, it);
00311 } // configuration_file::escape_line()
00312 
00313 /*----------------------------------------------------------------------------*/
00320 void claw::configuration_file::escape_char
00321 ( char escaped, const syntax_description& syntax, std::string& str ) const
00322 {
00323   switch (escaped)
00324     {
00325     case '\'' : str += "\'"; break;
00326     case '\"' : str += "\""; break;
00327     case '\\' : str += "\\"; break;
00328     case 'a' : str += "\a"; break;
00329     case 'b' : str += "\b"; break;
00330     case 'f' : str += "\f"; break;
00331     case 'n' : str += "\n"; break;
00332     case 'r' : str += "\r"; break;
00333     case 't' : str += "\t"; break;
00334     case 'v' : str += "\v"; break;
00335     default :
00336       if ( escaped == syntax.comment )
00337         str += syntax.comment;
00338       else
00339         (str += "\\") += escaped;
00340     }
00341 } // configuration_file::escape_char()

Generated on 9 Nov 2009 for CLAW Library (a C++ Library Absolutely Wonderful) by  doxygen 1.6.1