Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals

CfgHandler.cpp

Go to the documentation of this file.
00001 #include "SdlArs.h"
00002 
00003 #include <fstream>
00004 #include <iterator>
00005 
00006 namespace Cfg   
00007 {
00008 static deque<Handler *> CfgStacks;
00009 
00010 const bool Empty( void )
00011 {
00012         return CfgStacks.empty();
00013 }
00014 
00015 void Push( Handler *aCfg )
00016 {
00017         CfgStacks.push_back( aCfg );
00018 }
00019 
00020 Handler &Push( string aFile )
00021 {
00022         if( aFile[0] == '@' )
00023                 aFile = GetCfg().GetCfgFile( "Paths" , aFile.substr( 1 ) );
00024 
00025         Push( new Handler( aFile ) );
00026         return *CfgStacks.back();
00027 }
00028 
00029 void Pop( const Handler &aCfg )
00030 {
00031         deque<Handler *>::iterator      pos = find_if( CfgStacks.begin() , CfgStacks.end() , bind2nd( mem_fun( &Handler::IsTheFile ) , aCfg.GetFilename().c_str() ) );
00032         if( pos != CfgStacks.end() )
00033         {
00034                 delete *pos;
00035                 CfgStacks.erase( pos );
00036         }
00037 }
00038 
00039 void Pop( void )
00040 {
00041         if( !Empty() )
00042                 delete CfgStacks.back();
00043         CfgStacks.pop_back();
00044 }
00045 
00046 Handler &GetCfg( string aFile )
00047 {
00048         if( aFile[0] == '@' )
00049                 aFile = GetCfg().GetCfgFile( "Paths" , aFile.substr( 1 ) );
00050 
00051         deque<Handler *>::iterator      pos = find_if( CfgStacks.begin() , CfgStacks.end() , bind2nd( mem_fun( &Handler::IsTheFile ) , aFile.c_str() ) );
00052 
00053         if( pos == CfgStacks.end() )
00054                 return Push( aFile );
00055         return **pos;
00056 }
00057 
00059 Handler::Handler( const string &aFile )
00060 : CfgFile( aFile ) , dirty( false ) , cnt( 0 )
00061 {
00062         string::size_type       n = CfgFile.rfind( '\\' );
00063         if( n == string::npos )
00064                 n = CfgFile.rfind( '/' );
00065         if( n == string::npos )
00066                 cfgPath = "./";
00067         else
00068                 cfgPath = CfgFile.substr( 0 , n + 1 );
00069 
00070         ifstream        ifd( CfgFile.c_str() );
00071         
00072         vector<string>  e;
00073         vList.insert( make_pair( icstring( "" ) , e ) );
00074         map<icstring, vector<string> >::iterator pos = vList.find( "" );
00075 
00076         while( !ifd.fail() )
00077         {
00078                 char    buffer[4096] = "";
00079                 ifd.getline( buffer , sizeof buffer );
00080                 pos = AddLine( pos , buffer );
00081                 if( ifd.eof() )
00082                         break;
00083                 
00084         }
00085 }
00086 
00087 Handler::~Handler( void )
00088 {
00089         for( map<icstring , vector<string> >::iterator it = vList.begin() ; it != vList.end() ; ++it )
00090                 it->second.clear();
00091         vList.clear();
00092 }
00093 
00094 map<icstring, vector<string> >::iterator Handler::AddLine( map<icstring, vector<string> >::iterator pos , const string &aline )
00095 {
00096         //      If this is a section... [...]
00097         //      Creates a new section or returns the section iterator.
00098         if( aline[0] == '[' )
00099         {
00100                 string::size_type       at = aline.find( ']' );
00101                 if( at != string::npos )
00102                 {
00103                         icstring ics = aline.substr( 1 , at - 1 ).c_str();
00104                         map<icstring, vector<string> >::iterator pos2 = vList.find( ics );
00105                         if( pos2 == vList.end() )
00106                         {
00107                                 vector<string>  e;
00108                                 icstring        ics = aline.substr( 1 , at - 1 ).c_str();
00109                                 return vList.insert( make_pair( ics , e ) ).first;
00110                         }
00111                         return pos2;
00112                 }
00113         }
00114 
00115         //      We have to add a pair car = crd - otherwise this is considered as a comment...
00116         if( aline.find( "=" ) != string::npos && aline[0] != '#' && aline.substr( 0 , 2 ) != "//" )
00117         {
00118                 icstring        tmp = aline.substr( 0 , aline.find( '=' ) ).c_str();
00119                 icstring        s = Ars::strip( tmp );
00120                 for( vector<string>::iterator at = pos->second.begin() ; at != pos->second.end() ; ++at )
00121                 {
00122                         tmp = at->substr( 0 , at->find( '=' ) ).c_str();
00123                         icstring        ics = Ars::strip( tmp );
00124                         if( s == ics )
00125                         {
00126                                 *at = aline;
00127                                 return pos;
00128                         }
00129                 }
00130                 cnt += 1;
00131         }
00132 
00133         pos->second.push_back( aline );
00134         return pos;
00135 }
00136 
00137 void Handler::SetData( const string &aData )
00138 {
00139         dirty = false;
00140         vList.clear();
00141         string::size_type       n0 = 0 , n1 = aData.find( "\n" , n0 );
00142         cnt = 0;
00143 
00144         vector<string>  e;
00145         vList.insert( make_pair( icstring( "" ) , e ) );
00146         map<icstring, vector<string> >::iterator pos = vList.find( "" );
00147 
00148         while( n1 != string::npos )
00149         {
00150                 pos = AddLine( pos , string( aData.substr( n0 , n1 - n0 ) ) );
00151                 n0 = n1 + 1;
00152                 n1 = aData.find( "\n" , n0 );
00153         }
00154 }
00155 
00156 void Handler::Flush( const string &aFilename )
00157 {
00158         if( !aFilename.empty()  || dirty )
00159         {
00160                 ofstream        of( (aFilename.empty() ? CfgFile.c_str() : aFilename.c_str()) , ios::out );
00161                 for( map<icstring,vector<string> >::iterator it = vList.begin() ; it != vList.end() ; ++it )
00162                 {
00163                         if( !it->first.empty() )
00164                                 of << "[" << it->first.c_str() << "]" << endl;
00165                         copy( it->second.begin() , it->second.end() , ostream_iterator<string>( of , "\n" ) );
00166                 }
00167         }
00168         dirty = false;
00169 }
00170 
00171 string Handler::GetCdr( const icstring &aSection , const string &aId )
00172 {
00173         map<icstring, vector<string> >::iterator pos = vList.find( aSection );
00174         if( pos != vList.end() )
00175         {
00176                 for( vector<string>::iterator at = pos->second.begin() ; at != pos->second.end() ; ++at )
00177                 {
00178                         string::size_type n;
00179                         if( (n = at->find( '=' )) != string::npos )
00180                         {
00181                                 icstring        tmp = at->substr( 0 , n ).c_str();
00182                                 icstring        ics = Ars::strip( tmp );
00183                                 if( ics == icstring( aId.c_str() ) )
00184                                         return at->substr( at->find_first_not_of( ' ' , n + 1 ) );
00185 
00186                         }
00187                 }
00188         }
00189         return string( "" );
00190 }
00191 
00192 int Handler::GetCfgInt( const string &aSection , const string &aId , const int aDefaultValue )
00193 {
00194         string  s = GetCdr( icstring( aSection.c_str() ) , aId );
00195 
00196         int     val = aDefaultValue;
00197         if( s.substr( 0 , 2 ) == "0x" || s.substr( 0 , 2 ) == "0X" )
00198                 sscanf( s.substr( 2 ).c_str() , "%x" , &val );
00199         else if( !s.empty() )
00200                 sscanf( s.c_str() , "%d" , &val );
00201 
00202         return val;
00203 }
00204 
00205 int Handler::GetCfgHex( const string &aSection , const string &aId , const int aDefaultValue )
00206 {
00207         string  s = GetCdr( icstring( aSection.c_str() ) , aId );
00208 
00209         int     val = aDefaultValue;
00210         if( !s.empty() )
00211                 sscanf( s.c_str() , "%x" , &val );
00212 
00213         return val;
00214 }
00215 
00216 Ars::RGBColor Handler::GetCfgColorHex( const string &aSection , const string &aId , const Ars::RGBColor col )
00217 {
00218         unsigned long int       c = GetCfgInt( aSection , aId , (col.red << 16) + (col.green << 8) + col.blue + (col.alpha << 24) );
00219         return Ars::RGBColor( (unsigned char)( (c >> 16) & 0xff ) , (unsigned char)( (c >> 8) & 0xff ) , (unsigned char)( c & 0xff ) , (unsigned char)( c & 0xff000000 ? (c >> 24) & 0xff : 0xff ) );
00220 }
00221 
00222 double Handler::GetCfgDbl( const string &aSection , const string &aId , const double aDefaultValue )
00223 {
00224         string  s = GetCdr( icstring( aSection.c_str() ) , aId );
00225 
00226         double  val = aDefaultValue;
00227         if( !s.empty() )
00228                 sscanf( s.c_str() , "%lf" , &val );
00229 
00230         return val;
00231 }
00232 
00233 vector<double> &Handler::GetCfgDbl( const string &aSection , const string &aId , vector<double> &ans )
00234 {
00235         string  s = GetCdr( icstring( aSection.c_str() ) , aId );
00236 
00237         while( !s.empty() )
00238         {
00239                 double val = 0.0;
00240                 sscanf( s.c_str() , "%lf" , &val );
00241                 ans.push_back( val );
00242                 size_t  n = s.find_first_of( " \t\n" );
00243                 if( n != string::npos )
00244                         if( (n = s.find_first_not_of( " \t\n" , n )) != string::npos )
00245                                 s = s.substr( n );
00246                         else
00247                                 break;
00248                 else
00249                         break;
00250         }
00251         return ans;
00252 }
00253 
00254 string Handler::GetCfgString( const string &aSection , const string &aId , const string &aDefaultValue )
00255 {
00256         string  s = GetCdr( icstring( aSection.c_str() ) , aId );
00257 
00258         return (s.empty() ? aDefaultValue : s);
00259 }
00260 
00261 string Handler::GetCfgFile( const string &aSection , const string &aId , const string &aDefaultValue )
00262 {
00263         string  s = GetCdr( icstring( aSection.c_str() ) , aId );
00264 
00265         return (s.empty() ? aDefaultValue : (cfgPath + s));
00266 }
00267 
00268 void Handler::SetCfgInt( const string &aSection ,const string &aId , const int aValue )
00269 {
00270         dirty = true;
00271         char    buffer[4096];
00272         sprintf( buffer , " = %d" , aValue );
00273         AddLine( AddLine( vList.begin() , string( "[" ) + aSection + "]" ) , aId + buffer ); 
00274 }
00275 
00276 void Handler::SetCfgHex( const string &aSection ,const string &aId , const int aValue )
00277 {
00278         dirty = true;
00279         char    buffer[4096];
00280         sprintf( buffer , " = 0x%08x" , aValue );
00281         AddLine( AddLine( vList.begin() , string( "[" ) + aSection + "]" ) , aId + buffer ); 
00282 }
00283 
00284 void Handler::SetCfgDbl( const string &aSection ,const string &aId , const double aValue )
00285 {
00286         dirty = true;
00287         char    buffer[4096];
00288         sprintf( buffer , " = %f" , aValue );
00289         AddLine( AddLine( vList.begin() , string( "[" ) + aSection + "]" ) , aId + buffer ); 
00290 }
00291 
00292 void Handler::SetCfgString( const string &aSection ,const string &aId , const string &aValue )
00293 {
00294         dirty = true;
00295         AddLine( AddLine( vList.begin() , string( "[" ) + aSection + "]" ) , string( aId + " = " ) + aValue ); 
00296 }
00297 
00298 void Handler::SetCfgFile( const string &aSection ,const string &aId , const string &aValue )
00299 {
00300         string  v = aValue;
00301         string::size_type       n = v.find( cfgPath );
00302         if( n != string::npos )
00303                 v = v.substr( n + cfgPath.length() );
00304         dirty = true;
00305         AddLine( AddLine( vList.begin() , string( "[" ) + aSection + "]" ) , string( aId + " = " ) + v ); 
00306 }
00307 
00308 void Handler::SetCfgColorHex( const string &aSection , const string &aId , const Ars::RGBColor c )
00309 {
00310         dirty = true;
00311         char    buffer[4096];
00312         sprintf( buffer , " = 0x%02x%02x%02x%02x" , c.alpha , c.red , c.green , c.blue );
00313         AddLine( AddLine( vList.begin() , string( "[" ) + aSection + "]" ) , aId + buffer ); 
00314 }
00315 
00316 }
00317 

Generated on Fri Dec 5 04:05:59 2003 for Borqueror by doxygen 1.3.3