00001 #ifndef __PARMS_H__ 00002 #define __PARMS_H__ 00003 00009 #include <config.h> 00010 #include <string> 00011 #include <map> 00012 #include <sstream> 00013 #include <iostream> 00014 #include <vector> 00015 #include <set> 00016 #include <list> 00017 #include <util/forall.h> 00018 #include <QString> 00019 #include <iterator> 00020 #include <QTextStream> 00021 #include <QStringList> 00022 00023 namespace util 00024 { 00025 extern QTextStream out; 00026 extern QTextStream err; 00027 QTextStream& operator>>(QTextStream& ss, bool b); 00028 00105 class Parms { 00106 public: 00110 Parms(const QString& parmFile, int verboseLevel = 1); 00111 00112 ~Parms(); 00113 00119 void verboseLevel( int vl ) { VerboseLevel = ( vl < 0 ) ? 0 : vl; } 00120 00124 bool isLoaded() const { return loaded; } 00125 00143 template <typename T> 00144 bool operator()( const QString& section, const QString& key, T& value ); 00145 00153 bool operator()( const QString& section, const QString& key, bool& value ); 00159 bool operator()( const QString& section, const QString& key, int& value ); 00165 bool operator()( const QString& section, const QString& key, float& value ); 00171 bool operator()( const QString& section, const QString& key, double& value ); 00180 bool operator()( const QString& section, const QString& key, std::string& value ); 00181 00190 bool operator()( const QString& section, const QString& key, QString& value ); 00191 00197 template <typename T> 00198 bool operator()( const QString& section, const QString& key, T& value, const T& def ); 00199 00214 template <typename Container> 00215 bool all( const QString& section, const QString& key, Container& value ); 00216 00222 bool all( const QString& section, const QString& key, std::vector<bool>& value ); 00228 bool all( const QString& section, const QString& key, std::vector<int>& value ); 00234 bool all( const QString& section, const QString& key, std::vector<float>& value ); 00240 bool all( const QString& section, const QString& key, std::vector<double>& value ); 00246 bool all( const QString& section, const QString& key, std::vector<std::string>& value ); 00252 bool all( const QString& section, const QString& key, std::vector<QString>& value ); 00258 bool all( const QString& section, const QString& key, QStringList& value ); 00259 00260 00275 template <typename T, typename Container> 00276 bool all( const QString& section, std::map<QString, Container>& values); 00277 00283 bool all( const QString& section, std::map<QString, std::vector<bool> >& value ); 00289 bool all( const QString& section, std::map<QString, std::vector<int> >& value ); 00295 bool all( const QString& section, std::map<QString, std::vector<float> >& value ); 00301 bool all( const QString& section, std::map<QString, std::vector<double> >& value ); 00307 bool all( const QString& section, std::map<QString, std::vector<std::string> >& value ); 00313 bool all( const QString& section, std::map<QString, std::vector<QString> >& value ); 00319 bool all( const QString& section, std::map<QString, QStringList>& value ); 00320 00321 private: 00325 void init(); 00326 00332 bool extractValues( const QString& section, const QString& key, QStringList& values ); 00333 00342 bool readValue( const QString& value, bool& variable ); 00350 bool readValue( const QString& value, std::string& variable ); 00358 bool readValue( const QString& value, QString& variable ); 00367 template <typename T> 00368 bool readValue( const QString& value, std::vector<T>& variable ); 00377 template <typename T> 00378 bool readValue( const QString& value, std::list<T>& variable ); 00387 template <typename T> 00388 bool readValue( const QString& value, std::set<T>& variable ); 00397 template <typename T> 00398 bool readValue( const QString& value, T& variable ); 00399 00400 template <typename T, typename InsertIterator> 00401 bool readContainer( const QString& value, InsertIterator container); 00402 00406 QString ParmFileName; 00407 00413 bool check(QString &key); 00414 00419 std::map<QString,QStringList> Parameters; 00420 00424 QString Section; 00425 00429 int VerboseLevel; 00430 00435 bool CheckExist; 00436 00440 bool loaded; 00441 }; 00442 00443 template <typename T, typename InsertIterator> 00444 bool Parms::readContainer( const QString& value, InsertIterator it) 00445 { 00446 QString val(value); 00447 QTextStream iss(&val, QIODevice::ReadOnly); 00448 while(!iss.atEnd() and iss.status() == QTextStream::Ok) 00449 { 00450 T v; 00451 iss >> v; 00452 *it++ = v; 00453 } 00454 return true; 00455 } 00456 00457 template <typename T> 00458 bool Parms::readValue( const QString& value, std::vector<T>& variable ) 00459 { 00460 return readContainer<T>(value, std::back_insert_iterator<std::vector<T> >(variable)); 00461 } 00462 00463 template <typename T> 00464 bool Parms::readValue( const QString& value, std::list<T>& variable ) 00465 { 00466 return readContainer<T>(value, std::back_insert_iterator<std::list<T> >(variable)); 00467 } 00468 00469 template <typename T> 00470 bool Parms::readValue( const QString& value, std::set<T>& variable ) 00471 { 00472 return readContainer<T>(value, std::insert_iterator<std::set<T> >(variable, variable.end())); 00473 } 00474 00475 template <typename T> 00476 bool Parms::readValue( const QString& value, T& variable ) 00477 { 00478 QString val(value); 00479 QTextStream iss(&val, QIODevice::ReadOnly); 00480 iss >> variable; 00481 return iss.status() == QTextStream::Ok; 00482 } 00483 00484 template <typename T> 00485 bool Parms::operator()( const QString& section, const QString& key, T& value ) 00486 { 00487 QStringList values; 00488 if( !extractValues( section, key, values ) ) 00489 return false; 00490 00491 if( ( values.size() > 1 ) && ( VerboseLevel > 1 ) ) 00492 { 00493 err << "Parms::operator():Warning multiple value for key [" << section << "]" 00494 << key << ", last one used.\n" << flush; 00495 } 00496 00497 if( !readValue( values.back(), value ) ) 00498 { 00499 if( VerboseLevel > 0 ) 00500 { 00501 err << "Parms::operator():Error getting value for key [" << section << "]" << key 00502 << " value " << values.back() << "\n" << flush; 00503 } 00504 return false; 00505 } 00506 return true; 00507 } 00508 00509 template <typename T> 00510 bool Parms::operator()( const QString& section, const QString& key, T& value, const T& def ) 00511 { 00512 bool found = true; 00513 CheckExist = false; 00514 if( !( *this )( section, key, value ) ) 00515 { 00516 found = false; 00517 if( VerboseLevel > 2 ) 00518 { 00519 err << "Parms::operator()::Info key [" << section << "]" 00520 << key << " not found, using default value" << endl; 00521 } 00522 value = def; 00523 } 00524 CheckExist = true; 00525 return found; 00526 } 00527 00528 template <typename Container> 00529 bool Parms::all( const QString& section, const QString& key, Container& value ) 00530 { 00531 bool valid = true; 00532 typedef typename Container::value_type T; 00533 CheckExist = false; 00534 QStringList values; 00535 if( !extractValues( section, key, values ) ) 00536 return false; 00537 value.clear(); 00538 std::insert_iterator<Container> it(value, value.end()); 00539 forall( const QString& val, values ) 00540 { 00541 T single_value = T(); 00542 if( readValue( val, single_value ) ) 00543 { 00544 *it++ = (const T&)single_value; 00545 } 00546 else 00547 { 00548 if( VerboseLevel > 2 ) 00549 { 00550 err << "Parms::all:Error reading key [" << section << "]" << key 00551 << " with value " << val << "\n" << flush; 00552 } 00553 valid = false; 00554 } 00555 } 00556 CheckExist = true; 00557 return valid; 00558 } 00559 00560 template <typename T, typename Container> 00561 bool Parms::all( const QString& section, std::map<QString, Container>& result ) 00562 { 00563 bool valid = true; 00564 CheckExist = false; 00565 typedef std::map<QString, QStringList>::value_type value_type; 00566 result.clear(); 00567 int pos = section.size()+1; 00568 forall( const value_type& pair, Parameters) 00569 { 00570 QString sec(pair.first.mid(0, pos-1)); 00571 if(sec != section) 00572 continue; 00573 QString key(pair.first.mid(pos)); 00574 Container& value = result[key]; 00575 value.clear(); 00576 forall( const QString& val, pair.second ) 00577 { 00578 T single_value = T(); 00579 if( readValue( val, single_value ) ) 00580 { 00581 value.push_back( single_value ); 00582 } 00583 else 00584 { 00585 if( VerboseLevel > 2 ) 00586 { 00587 err << "Parms::all:Error reading key [" << section << "]" << key 00588 << " with value " << val << endl; 00589 } 00590 valid = false; 00591 } 00592 } 00593 } 00594 CheckExist = true; 00595 return valid; 00596 } 00597 00598 } 00599 00600 #endif