PCMConfigOptions.cpp

Go to the documentation of this file.
00001 
00002 //
00003 // This source file is a part of ParCompMark
00004 // Parallel Compositing Benchmark Framework
00005 //
00006 // for latest info see http://parcompmark.sourceforge.net
00007 
00008 //
00009 // Copyright (C) 2006 IT2 ParCompMark Dev. Team
00010 // 
00011 // This program is free software; you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License
00013 // as published by the Free Software Foundation; either version 2
00014 // of the License, or (at your option) any later version.
00015 // 
00016 // This program is distributed in the hope that it will be useful,
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 // GNU General Public License for more details.
00020 // 
00021 // You should have received a copy of the GNU General Public License
00022 // along with this program; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00024 
00025 //
00026 // Inner includes
00027 //
00028 
00029 #include "../include/PCMConfigOptions.h"
00030 
00031 #include "../include/PCMTimer.h"
00032 
00033 #include "../include/PCMFileSystemManager.h"
00034 
00035 #include "../include/PCMStringConverter.h"
00036 
00037 //
00038 // Outer includes
00039 //
00040 
00041 #include <iostream>
00042 #include <fstream>
00043 
00044 namespace ParCompMark
00045 {
00046 
00047   //
00048   // Constructors & destructor
00049   //
00050 
00051   ConfigOptions::ConfigOptions()
00052         // You have to initialize the following attributes:
00053         // - mOptions
00054         // - mInitialized
00055   {
00056         mOptions = new Container < ConfigOptions::Option, Mutex >;
00057         mInitialized = false;
00058 
00059         Logger::getInstance()->log(Logger::NOTICE, "Application option container has been created.");
00060   }
00061 
00062  /*----------------------------------------------------------------------*/
00063 
00064   ConfigOptions::~ConfigOptions()
00065   {
00066         if(mInitialized)
00067          finalize();
00068 
00069         Logger::getInstance()->log(Logger::NOTICE, "Application option container has been destroyed.");
00070   }
00071 
00072  /*----------------------------------------------------------------------*/
00073 
00074   //
00075   // Methods
00076   //
00077 
00078   void ConfigOptions::initialize()
00079   {
00080         Assert(!mInitialized, INVALID_OPERATION_ERROR, "ConfigOptions::finalize()");
00081 
00082         mInitialized = true;
00083         Logger::getInstance()->log(Logger::NOTICE, "Application option container has been initialized.");
00084   }
00085 
00086  /*----------------------------------------------------------------------*/
00087 
00088   void ConfigOptions::finalize()
00089   {
00090         Assert(mInitialized, INVALID_OPERATION_ERROR, "ConfigOptions::finalize()");
00091 
00092         mInitialized = false;
00093         Logger::getInstance()->log(Logger::NOTICE, "Application option container has been finalized.");
00094   }
00095 
00096  /*----------------------------------------------------------------------*/
00097 
00098   bool ConfigOptions::hasOption(const std::string & name)
00099   {
00100         mOptions.lock();
00101         bool r = mOptions->has(name);
00102 
00103         mOptions.unlock();
00104         return r;
00105   }
00106 
00107  /*----------------------------------------------------------------------*/
00108 
00109   std::string ConfigOptions::getString(const std::string & name)
00110   {
00111         return *static_cast < std::string * >(getValue(name, STRING)->value);
00112   }
00113 
00114  /*----------------------------------------------------------------------*/
00115 
00116   bool ConfigOptions::getBool(const std::string & name)
00117   {
00118         return *static_cast < bool * >(getValue(name, BOOL)->value);
00119   }
00120 
00121  /*----------------------------------------------------------------------*/
00122 
00123   s32 ConfigOptions::getInteger(const std::string & name)
00124   {
00125         return *static_cast < s32 * >(getValue(name, INTEGER)->value);
00126   }
00127 
00128  /*----------------------------------------------------------------------*/
00129 
00130   Real ConfigOptions::getReal(const std::string & name)
00131   {
00132         return *static_cast < Real * >(getValue(name, REAL)->value);
00133   }
00134 
00135  /*----------------------------------------------------------------------*/
00136 
00137   bool ConfigOptions::testString(const std::string & name, const std::string & value)
00138   {
00139         return hasOption(name) && getString(name) == value;
00140   }
00141 
00142  /*----------------------------------------------------------------------*/
00143 
00144   void ConfigOptions::setString(const std::string & name, const std::string & value,
00145                                 const std::string & description)
00146   {
00147         setValue(name, (void *) &value, STRING, description);
00148         Logger::getInstance()->log(Logger::DEBUG, "Option " + name + "=`" + value + "\' has been set.");
00149   }
00150 
00151  /*----------------------------------------------------------------------*/
00152 
00153   void ConfigOptions::setBool(const std::string & name, const bool & value,
00154                                 const std::string & description)
00155   {
00156         setValue(name, (void *) &value, BOOL, description);
00157         Logger::getInstance()->log(Logger::DEBUG,
00158                                  "Option " + name + "=`" + StringConverter::toString(value) + "\' has been set.");
00159   }
00160 
00161  /*----------------------------------------------------------------------*/
00162 
00163   void ConfigOptions::setInteger(const std::string & name, const s32 & value,
00164                                  const std::string & description)
00165   {
00166         setValue(name, (void *) &value, INTEGER, description);
00167         Logger::getInstance()->log(Logger::DEBUG,
00168                                  "Option " + name + "=`" + StringConverter::toString(value) + "\' has been set.");
00169   }
00170 
00171  /*----------------------------------------------------------------------*/
00172 
00173   void ConfigOptions::setReal(const std::string & name, const Real & value,
00174                                 const std::string & description)
00175   {
00176         setValue(name, (void *) &value, REAL, description);
00177         Logger::getInstance()->log(Logger::DEBUG,
00178                                  "Option " + name + "=`" + StringConverter::toString(value) + "\' has been set.");
00179   }
00180 
00181  /*----------------------------------------------------------------------*/
00182 
00183   void ConfigOptions::removeOption(const std::string & name)
00184   {
00185         Assert(hasOption(name), INVALID_NAME_ERROR, "ConfigOptions::removeOption()");
00186 
00187         mOptions.lock();
00188         mOptions->remove(name);
00189         mOptions.unlock();
00190   }
00191 
00192  /*----------------------------------------------------------------------*/
00193 
00194   void ConfigOptions::saveToIniFile(const std::string & filename)
00195   {
00196         FileSystemManager::CppFilePointer fp(FileSystemManager::getInstance()->
00197                                           openAppFileCpp(filename, FileSystemManager::WRITE));
00198 
00199         *fp.getPtr() << "# Filename: " << FileSystemManager::getInstance()->getAppDirectory() << filename << std::endl;
00200         *fp.getPtr() << "# Created at " << Timer::getTimeDateString(false) << std::endl;
00201         *fp.getPtr() << "# Autogenerated configuration options" << std::endl << std::endl;
00202 
00203         // Write config options
00204         for(Container < ConfigOptions::Option, Mutex >::Iterator i = mOptions->begin(); i != mOptions->end(); i++)
00205         {
00206          if(i->second->description.length())
00207                 *fp.getPtr() << "# " << i->second->description << std::endl;
00208          *fp.getPtr() << i->first << '=' << optionToString(i->second) << std::endl << std::endl;
00209         }
00210 
00211         // Write hint options
00212         if(!hasOption("lowLevelScriptFile"))
00213          *fp.getPtr() << "# Explicit low level script file" << std::
00214                 endl << "#lowLevelScriptFile=scripts/low-level/<script file name>" << std::endl << std::endl;
00215         if(!hasOption("dynamicScriptFile"))
00216          *fp.getPtr() << "# Second level (cluster dynamic) script file" << std::
00217                 endl << "#dynamicScriptFile=scripts/dynamic/<script file name>" << std::endl << std::endl;
00218         if(!hasOption("outputFile"))
00219          *fp.getPtr() << "# Explicit output file" << std::endl << "#outputFile=<output file name>" << std::
00220                 endl << std::endl;
00221         if(!hasOption("pcLibraryPath"))
00222          *fp.getPtr() << "# PC library path" << std::
00223                 endl << "#pcLibraryPath=<path to PC dynamic load library>" << std::endl << std::endl;
00224 
00225         FileSystemManager::getInstance()->closeFile(fp);
00226 
00227         if(Logger::getInstance())
00228          Logger::getInstance()->log(Logger::NOTICE,
00229                                    "Ini file `" + FileSystemManager::getInstance()->getAppDirectory() + filename +
00230                                    "\' created.");
00231   }
00232 
00233  /*----------------------------------------------------------------------*/
00234 
00235   void ConfigOptions::loadFromIniFile(const std::string & filename)
00236   {
00237         FileSystemManager::CppFilePointer fp(FileSystemManager::getInstance()->
00238                                           openAppFileCpp(filename, FileSystemManager::READ));
00239 
00240         const u32 lineBufSize = 1024;
00241         char lineBuf[lineBufSize];
00242 
00243         std::string line = "";
00244         u32 lineNumber = 0;
00245 
00246         while(!fp->eof())
00247         {
00248          // Read line, trim, and test comment
00249          fp->getline(lineBuf, lineBufSize);
00250          lineNumber++;
00251 
00252          line = lineBuf;
00253          StringConverter::trim(line);
00254          if(!line.length() || line[0] == '#')
00255                 continue;
00256 
00257          // Check error
00258          if(line.find('=') == std::string::npos)
00259                 Except(FILE_FORMAT_ERROR, "ConfigOptions::loadFromIniFile()",
00260                    "Error in config file `" + FileSystemManager::getInstance()->getAppDirectory() + filename +
00261                    "\':" + StringConverter::toString(lineNumber) + ": " + line);
00262 
00263          // Get name and value
00264          std::string name = line.substr(0, line.find('='));
00265          std::string value = line.substr(line.find('=') + 1);
00266 
00267          // TODO: howto handle other values 
00268          setString(name, value);
00269         }
00270 
00271         FileSystemManager::getInstance()->closeFile(fp);
00272 
00273         if(Logger::getInstance())
00274          Logger::getInstance()->log(Logger::NOTICE,
00275                                    "Ini file `" + FileSystemManager::getInstance()->getAppDirectory() + filename +
00276                                    "\' loaded.");
00277   }
00278 
00279  /*----------------------------------------------------------------------*/
00280 
00281   ConfigOptions::Option::Pointer ConfigOptions::getValue(const std::string & name,
00282                                                          const ConfigOptions::OptionType & type)
00283   {
00284         Assert(hasOption(name), INVALID_NAME_ERROR, "ConfigOptions::getValue()");
00285 
00286         mOptions.lock();
00287         Option::Pointer p(mOptions->get(name));
00288         if(p->type != type)
00289         {
00290          mOptions.unlock();
00291          Except(INVALID_CLASS_ERROR, "ConfigOptions::getValue()",
00292                  "Config option `" + name + "\' has different type.");
00293         }
00294         mOptions.unlock();
00295         return p;
00296   }
00297 
00298  /*----------------------------------------------------------------------*/
00299 
00300   void ConfigOptions::setValue(const std::string & name, const void *value,
00301                                  const ConfigOptions::OptionType & type, const std::string & description)
00302   {
00303         mOptions.lock();
00304         Option::Pointer p(new Option());
00305 
00306         // Set type
00307         p->type = type;
00308 
00309         // Copy value
00310         if(type != STRING)
00311         {
00312          u32 vSize = getOptionTypeSize(type);
00313 
00314          p->value = new u8[vSize];
00315          memcpy(p->value, value, vSize);
00316         } else
00317         {
00318          const std::string * s = new std::string(*static_cast < const std::string * >(value));
00319 
00320          p->value = (void *) s;
00321         }
00322 
00323         // Set description
00324         p->description = description;
00325 
00326         // Add to container
00327         if(mOptions->has(name))
00328         {
00329          mOptions->remove(name);
00330          mOptions->add(name, p);
00331         } else
00332          mOptions->add(name, p);
00333 
00334         mOptions.unlock();
00335   }
00336 
00337  /*----------------------------------------------------------------------*/
00338 
00339   u32 ConfigOptions::getOptionTypeSize(const ConfigOptions::OptionType & type)
00340   {
00341         switch (type)
00342         {
00343          case STRING:
00344                 return sizeof(std::string);
00345          case BOOL:
00346                 return sizeof(bool);
00347          case INTEGER:
00348                 return sizeof(s32);
00349          case REAL:
00350                 return sizeof(Real);
00351         }
00352 
00353         // To avoid warning
00354         return 1;
00355   }
00356 
00357  /*----------------------------------------------------------------------*/
00358 
00359   std::string ConfigOptions::optionToString(ConfigOptions::Option::Pointer & option)
00360   {
00361         switch (option->type)
00362         {
00363          case STRING:
00364                 return *static_cast < std::string * >(option->value);
00365          case BOOL:
00366                 return StringConverter::toString(*static_cast < bool * >(option->value));
00367          case INTEGER:
00368                 return StringConverter::toString(*static_cast < s32 * >(option->value));
00369          case REAL:
00370                 return StringConverter::toString(*static_cast < Real * >(option->value));
00371         }
00372 
00373         return "(unknown)";
00374   }
00375 
00376  /*----------------------------------------------------------------------*/
00377 
00378 }