parms.cpp

00001 // Parameter reader class
00002 #include <fstream>
00003 #include <iostream>
00004 #include <sstream>
00005 #include <map>
00006 #include <cctype>
00007 #include <algorithm>
00008 #include <iterator>
00009 #include "parms.h"
00010 #include <qdir.h>
00011 
00012 #ifdef __unix__
00013 #  include <fcntl.h>
00014 #  include <sys/file.h>
00015 #  include <sys/stat.h>
00016 #endif
00017 
00018 namespace util
00019 {
00020   QTextStream out(stdout);
00021   QTextStream err(stderr);
00022 
00023   using std::map;
00024   using std::ostream_iterator;
00025   using std::copy;
00026 
00027   Parms::Parms(const QString& parmFile, int vl )
00028     : ParmFileName( parmFile )
00029   {
00030     verboseLevel( vl );
00031     init();
00032   }
00033 
00034   void Parms::init()
00035   {
00036     CheckExist =true;
00037     loaded=false;
00038 #ifdef __unix__
00039     // First, obtain the lock
00040     QByteArray ba = ParmFileName.toLocal8Bit();
00041     int fd = open(ba.data(), O_RDONLY);
00042     struct stat stats;
00043     while(1)
00044     {
00045       fstat(fd, &stats);
00046       if(stats.st_size != 0)
00047         break;
00048       usleep(1);
00049     }
00050     flock(fd, LOCK_SH);
00051 #endif
00052     QFile fIn(ParmFileName);
00053     if(!fIn.open(QIODevice::ReadOnly))
00054     {
00055       if( VerboseLevel > 0 )
00056         err << "Parms::Parms:Error opening " << ParmFileName << endl;
00057       return;
00058     }
00059     QTextStream ss(&fIn);
00060     unsigned int line = 0;
00061     int pos;
00062     QString buff;
00063     while(!ss.atEnd() and ss.status() == QTextStream::Ok) {
00064       line++;
00065       // read in line
00066       buff = ss.readLine();
00067       // find C++ style comments
00068       pos = buff.indexOf("//");
00069       // and remove to end of line
00070       if(pos != -1)
00071         buff = buff.mid(0, pos);
00072       // remove leading and trailing whitespace
00073       buff = buff.trimmed();
00074       // skip line if blank
00075       if(buff.length() == 0)
00076         continue;
00077       // Look for section
00078       if(buff[0] == '[' && buff.right(1)[0] == ']') {
00079         Section = buff.mid(1, buff.length() - 2);
00080         if(( Section.length() == 0) && ( VerboseLevel > 0 ) )
00081           err << "Parms::Parms:Error on line " << line << ", []" << endl;
00082         continue;
00083       }
00084       // split key and value
00085       pos = buff.indexOf(":");
00086       // error if no : delimiter
00087       if(pos == -1) {
00088         if( VerboseLevel > 0 )
00089           err << "Parms::Parms:Error on line " << line << ", missing :" << endl;
00090         continue;
00091       }
00092       // get key and value and remove leading/trailing blanks
00093       QString key = buff.mid(0, pos).trimmed();
00094       QString value = buff.mid(pos + 1).trimmed();
00095       // error if no key
00096       if(key.length() == 0) {
00097         if( VerboseLevel > 0 )
00098           err << "Parms::Parms:Error on line " << line << ", missing key" << endl;
00099         continue;
00100       }
00101       // error if no value
00102       if(value.length() == 0) {
00103         if( VerboseLevel > 2 )
00104           err << "Parms::Parms:Warning on line "<< line << ", missing value" << endl;
00105       }
00106 
00107       // Now we have key and value, add to map
00108       Parameters[Section + ":" + key] << value;
00109     }
00110 #ifdef __unix__
00111     // At last, release the lock
00112     flock(fd, LOCK_UN);
00113     close(fd);
00114 #endif
00115     loaded = true;
00116   }
00117 
00118   Parms::~Parms()
00119   {
00120   }
00121 
00122   /*
00123   void removeWhitespace(string &s)
00124   {
00125     size_t pos = s.find_first_not_of(" \t\r\n");
00126     if(pos == string::npos)
00127       s = "";
00128     else {
00129       s = s.substr(pos, string::npos);
00130       pos = s.find_last_not_of(" \t\r\n");
00131       if(pos != string::npos)
00132         s = s.substr(0, pos + 1);
00133     }
00134   }
00135   */
00136 
00137   // Check if parm exists
00138   bool Parms::check(QString &key)
00139   {
00140     return ( Parameters.find( key ) != Parameters.end() );
00141   }
00142 
00143   bool Parms::operator()( const QString& section, const QString& key, bool& value )
00144   {
00145     return operator()<bool>( section, key, value );
00146   }
00147 
00148   bool Parms::operator()( const QString& section, const QString& key, int& value )
00149   {
00150     return operator()<int>( section, key, value );
00151   }
00152 
00153   bool Parms::operator()( const QString& section, const QString& key, float& value )
00154   {
00155     return operator()<float>( section, key, value );
00156   }
00157 
00158   bool Parms::operator()( const QString& section, const QString& key, double& value )
00159   {
00160     return operator()<double>( section, key, value );
00161   }
00162 
00163   bool Parms::operator()( const QString& section, const QString& key, std::string& value )
00164   {
00165     return operator()<std::string>( section, key, value );
00166   }
00167 
00168   bool Parms::operator()( const QString& section, const QString& key, QString& value )
00169   {
00170     return operator()<QString>( section, key, value );
00171   }
00172 
00173   bool Parms::all( const QString& section, const QString& key, std::vector<bool>& value )
00174   {
00175     return all<std::vector<bool> >( section, key, value );
00176   }
00177 
00178   bool Parms::all( const QString& section, const QString& key, std::vector<int>& value )
00179   {
00180     return all<std::vector<int> >( section, key, value );
00181   }
00182 
00183   bool Parms::all( const QString& section, const QString& key, std::vector<float>& value )
00184   {
00185     return all<std::vector<float> >( section, key, value );
00186   }
00187 
00188   bool Parms::all( const QString& section, const QString& key, std::vector<double>& value )
00189   {
00190     return all<std::vector<double> >( section, key, value );
00191   }
00192 
00193   bool Parms::all( const QString& section, const QString& key, std::vector<QString>& value )
00194   {
00195     return all<std::vector<QString> >( section, key, value );
00196   }
00197 
00198   bool Parms::all( const QString& section, const QString& key, QStringList& value )
00199   {
00200     return all<QStringList>( section, key, value );
00201   }
00202 
00203   bool Parms::all( const QString& section, std::map<QString, std::vector<bool> >& value )
00204   {
00205     return all<bool>( section, value );
00206   }
00207 
00208   bool Parms::all( const QString& section, std::map<QString, std::vector<int> >& value )
00209   {
00210     return all<int>( section, value );
00211   }
00212 
00213   bool Parms::all( const QString& section, std::map<QString, std::vector<float> >& value )
00214   {
00215     return all<float>( section, value );
00216   }
00217 
00218   bool Parms::all( const QString& section, std::map<QString, std::vector<double> >& value )
00219   {
00220     return all<double>( section, value );
00221   }
00222 
00223   bool Parms::all( const QString& section, std::map<QString, std::vector<QString> >& value )
00224   {
00225     return all<QString>( section, value );
00226   }
00227 
00228   bool Parms::all( const QString& section, std::map<QString, QStringList>& value )
00229   {
00230     return all<QString>( section, value );
00231   }
00232 
00233   bool Parms::readValue( const QString& raw_value, bool& variable )
00234   {
00235     QString value = raw_value.toLower();
00236     if( value == "true" )
00237     {
00238       variable = true;
00239       return true;
00240     }
00241     else if( value == "false" )
00242     {
00243       variable = false;
00244       return true;
00245     }
00246     return false;
00247   }
00248 
00249   bool Parms::readValue( const QString& value, QString& variable )
00250   {
00251     variable = value;
00252     return true;
00253   }
00254 
00255   bool Parms::readValue( const QString& value, std::string& variable )
00256   {
00257     variable = value.toStdString();
00258     return true;
00259   }
00260 
00261   bool Parms::extractValues( const QString& section, const QString& key, QStringList& values )
00262   {
00263     QString real_key = section + ":" + key;
00264 
00265     if(check(real_key))
00266     {
00267       values = Parameters[real_key];
00268 
00269       if( VerboseLevel > 3 )
00270       {
00271         err << "Parms::extractValues:Debug strings for key [" << section << "]" << key << ": -"
00272             << values.join("-") << endl;
00273       }
00274       return true;
00275     }
00276 
00277     if( CheckExist && ( VerboseLevel > 0 ) )
00278       err << "Parms::operator():Error key not found [" << section << "]"
00279         << key << endl;
00280     return false;
00281   }
00282 
00283   QTextStream& operator>>(QTextStream& ss, bool b)
00284   {
00285     QString val;
00286     ss >> val;
00287     val.toLower();
00288     b = (val == "true");
00289     return ss;
00290   }
00291 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Fri May 31 15:37:53 2013 for VVE by  doxygen 1.6.3