BESKeys.cc

Go to the documentation of this file.
00001 // BESKeys.cc
00002 
00003 // This file is part of bes, A C++ back-end server implementation framework
00004 // for the OPeNDAP Data Access Protocol.
00005 
00006 // Copyright (c) 2004,2005 University Corporation for Atmospheric Research
00007 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 // You can contact University Corporation for Atmospheric Research at
00024 // 3080 Center Green Drive, Boulder, CO 80301
00025  
00026 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
00027 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
00028 //
00029 // Authors:
00030 //      pwest       Patrick West <pwest@ucar.edu>
00031 //      jgarcia     Jose Garcia <jgarcia@ucar.edu>
00032 
00033 #ifdef __cplusplus
00034 extern "C" {
00035 #include <sys/types.h>
00036 #include "regex.h"
00037 }
00038 #endif
00039 
00040 #include <stdio.h>
00041 #include <unistd.h>
00042 #include <iostream>
00043 
00044 using std::endl ;
00045 using std::cout ;
00046 
00047 #include "BESKeys.h"
00048 #include "BESKeysException.h"
00049 
00066 BESKeys::BESKeys( const string &keys_file_name )
00067     : _keys_file( 0 ),
00068       _keys_file_name( keys_file_name ),
00069       _the_keys( 0 )
00070 {
00071     _keys_file = new ifstream( _keys_file_name.c_str() ) ;
00072     if( !(*_keys_file) )
00073     {
00074         char path[500] ;
00075         getcwd( path, sizeof( path ) ) ;
00076         string s = string("BES: fatal, can not open initialization file ")
00077                    + _keys_file_name + "\n"
00078                    + "The current working directory is " + path + "\n" ;
00079         throw BESKeysException( s, __FILE__, __LINE__ ) ;
00080     }
00081 
00082     _the_keys = new map<string,string>;
00083     try
00084     {
00085         load_keys();
00086     }
00087     catch(BESKeysException &ex)
00088     {
00089         clean();
00090         throw;
00091     }
00092     catch(...)
00093     {
00094         clean() ;
00095         string s = (string)"Undefined exception while trying to load keys "
00096                    + "from bes configuration file " + _keys_file_name ;
00097         throw BESKeysException( s, __FILE__, __LINE__ ) ;
00098     }
00099 }
00100 
00103 BESKeys::~BESKeys()
00104 {
00105     clean() ;
00106 }
00107 
00108 void
00109 BESKeys::clean()
00110 {
00111     if( _keys_file )
00112     {
00113         _keys_file->close() ;
00114         delete _keys_file ;
00115     }
00116     if( _the_keys )
00117     {
00118         delete _the_keys ;
00119     }
00120 }
00121 
00122 inline void
00123 BESKeys::load_keys()
00124 {
00125     char buffer[255];
00126     string key,value;
00127     while(!(*_keys_file).eof())
00128     {
00129         if((*_keys_file).getline(buffer,255))
00130         {
00131             if( break_pair( buffer, key, value ) )
00132             {
00133                 (*_the_keys)[key]=value;
00134             }
00135         }
00136     }
00137 }
00138 
00139 inline bool
00140 BESKeys::break_pair(const char* b, string& key, string &value)
00141 {
00142     if((b[0]!='#') && (!only_blanks(b)))//Ignore comments a lines with only spaces
00143     {
00144         register size_t l=strlen(b);
00145         if(l>1)
00146         {
00147             register int how_many_equals=0;
00148             int pos=0;
00149             for (register size_t j=0;j<l;j++)
00150             {
00151                 if(b[j] == '=')
00152                 {
00153                     how_many_equals++;
00154                     pos=j;
00155                 }
00156             }
00157 
00158             if(how_many_equals!=1)
00159             {
00160                 char howmany[256] ;
00161                 sprintf( howmany, "%d", how_many_equals ) ;
00162                 string s = string( "BES: invalid entry " ) + b
00163                            + "; there are " + howmany
00164                            + " = characters.\n";
00165                 throw BESKeysException( s, __FILE__, __LINE__ );
00166             }
00167             else
00168             {
00169                 string s=b;
00170                 key=s.substr(0,pos);
00171                 removeLeadingAndTrailingBlanks( key ) ;
00172                 value=s.substr(pos+1,s.size());
00173                 removeLeadingAndTrailingBlanks( value ) ;
00174 
00175                 return true;
00176             }
00177         }
00178 
00179         return false;
00180     }
00181 
00182     return false;
00183 }
00184 
00185 void
00186 BESKeys::removeLeadingAndTrailingBlanks( string &key )
00187 {
00188     if( !key.empty() )
00189     {
00190         string::size_type first = key.find_first_not_of( "      " ) ;
00191         string::size_type last = key.find_last_not_of( "        " ) ;
00192         if( first == string::npos ) first = 0 ;
00193         if( last == string::npos ) last = key.length() ;
00194         string::size_type num = last - first + 1 ;
00195         key = key.substr( first, num ) ;
00196     }
00197 }
00198 
00199 bool
00200 BESKeys::only_blanks(const char *line)
00201 {
00202     int val;
00203     regex_t rx;
00204     string expr = "[^[:space:]]" ;
00205     val = regcomp( &rx, expr.c_str(), REG_ICASE ) ;
00206 
00207     if( val != 0 )
00208     {
00209         string s = (string)"Regular expression " + expr
00210                    + " did not compile correctly" ;
00211         throw BESKeysException( s, __FILE__, __LINE__ ) ;
00212     }
00213     val = regexec( &rx, line, 0, 0, REG_NOTBOL ) ;
00214     if( val == 0 )
00215     {
00216         regfree( &rx ) ;
00217         return false ;
00218     }
00219     else
00220     {
00221         if( val == REG_NOMATCH )
00222         {
00223             regfree( &rx ) ;
00224             return true ;
00225         }
00226         else if( val == REG_ESPACE )
00227         {
00228             string s = "Execution of regular expression out of space" ;
00229             throw BESKeysException( s, __FILE__, __LINE__ ) ;
00230         }
00231         else
00232         {
00233             string s = "Execution of regular expression has unknown problem" ;
00234             throw BESKeysException( s, __FILE__, __LINE__ ) ;
00235         }
00236     }
00237 }
00238 
00253 string
00254 BESKeys::set_key( const string &key, const string &val )
00255 {
00256     map< string, string >::iterator i ;
00257     i = _the_keys->find( key ) ;
00258     if( i == _the_keys->end() )
00259     {
00260         (*_the_keys)[key] = val ;
00261         return val ;
00262     }
00263     (*i).second = val ;
00264     return val ;
00265 }
00266 
00279 string
00280 BESKeys::set_key( const string &pair )
00281 {
00282     string key ;
00283     string val ;
00284     break_pair( pair.c_str(), key, val ) ;
00285     return set_key( key, val ) ;
00286 }
00287 
00299 string
00300 BESKeys::get_key( const string& s, bool &found ) 
00301 {
00302     map<string,string>::iterator i;
00303     i=_the_keys->find(s);
00304     if(i!=_the_keys->end())
00305     {
00306         found = true ;
00307         return (*i).second;
00308     }
00309     else
00310     {
00311         found = false ;
00312         return "";
00313     }
00314 }
00315 
00322 void
00323 BESKeys::dump( ostream &strm ) const
00324 {
00325     strm << BESIndent::LMarg << "BESKeys::dump - ("
00326                              << (void *)this << ")" << endl ;
00327     BESIndent::Indent() ;
00328     strm << BESIndent::LMarg << "key file:" << _keys_file_name << endl ;
00329     if( _keys_file && *_keys_file )
00330     {
00331         strm << BESIndent::LMarg << "key file is valid" << endl ;
00332     }
00333     else
00334     {
00335         strm << BESIndent::LMarg << "key file is NOT valid" << endl ;
00336     }
00337     if( _the_keys && _the_keys->size() )
00338     {
00339         strm << BESIndent::LMarg << "    keys:" << endl ;
00340         BESIndent::Indent() ;
00341         Keys_citer i = _the_keys->begin() ;
00342         Keys_citer ie = _the_keys->end() ;
00343         for( ; i != ie; i++ )
00344         {
00345             strm << BESIndent::LMarg << (*i).first << ": "
00346                                      << (*i).second << endl ;
00347         }
00348         BESIndent::UnIndent() ;
00349     }
00350     else
00351     {
00352         strm << BESIndent::LMarg << "keys: none" << endl ;
00353     }
00354     BESIndent::UnIndent() ;
00355 }
00356 

Generated on Fri Nov 30 12:06:47 2007 for OPeNDAP Back End Server (BES) by  doxygen 1.5.1