00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
00039
00040
00041 #include <iostream>
00042 #include <fstream>
00043
00044 namespace ParCompMark
00045 {
00046
00047
00048
00049
00050
00051 ConfigOptions::ConfigOptions()
00052
00053
00054
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
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
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
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
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
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
00264 std::string name = line.substr(0, line.find('='));
00265 std::string value = line.substr(line.find('=') + 1);
00266
00267
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
00307 p->type = type;
00308
00309
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
00324 p->description = description;
00325
00326
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
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 }