00001
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
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
00066 buff = ss.readLine();
00067
00068 pos = buff.indexOf("//");
00069
00070 if(pos != -1)
00071 buff = buff.mid(0, pos);
00072
00073 buff = buff.trimmed();
00074
00075 if(buff.length() == 0)
00076 continue;
00077
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
00085 pos = buff.indexOf(":");
00086
00087 if(pos == -1) {
00088 if( VerboseLevel > 0 )
00089 err << "Parms::Parms:Error on line " << line << ", missing :" << endl;
00090 continue;
00091 }
00092
00093 QString key = buff.mid(0, pos).trimmed();
00094 QString value = buff.mid(pos + 1).trimmed();
00095
00096 if(key.length() == 0) {
00097 if( VerboseLevel > 0 )
00098 err << "Parms::Parms:Error on line " << line << ", missing key" << endl;
00099 continue;
00100 }
00101
00102 if(value.length() == 0) {
00103 if( VerboseLevel > 2 )
00104 err << "Parms::Parms:Warning on line "<< line << ", missing value" << endl;
00105 }
00106
00107
00108 Parameters[Section + ":" + key] << value;
00109 }
00110 #ifdef __unix__
00111
00112 flock(fd, LOCK_UN);
00113 close(fd);
00114 #endif
00115 loaded = true;
00116 }
00117
00118 Parms::~Parms()
00119 {
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
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 }