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
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef PARAMMAP_C_DEFINED
00039 #define PARAMMAP_C_DEFINED
00040
00041 #include "Component/ParamMap.H"
00042
00043 #include "Util/Assert.H"
00044 #include "Util/Types.H"
00045 #include "Util/log.H"
00046
00047 #include <fstream>
00048 #include <iomanip>
00049 #include <iostream>
00050 #include <limits>
00051 #include <map>
00052 #include <sstream>
00053 #include <string>
00054 #include <vector>
00055
00056
00057 namespace dummy_namespace_to_avoid_gcc411_bug_ParamMap_C
00058 {
00059 void escapeWrite(std::ostream& ostrm, const std::string& s)
00060 {
00061 for (uint i = 0; i < s.size(); ++i)
00062 {
00063 switch (s[i])
00064 {
00065
00066
00067 case ' ' : ostrm << '\\' << ' '; break;
00068 case '\t' : ostrm << '\\' << '\t'; break;
00069 case '\n' : ostrm << '\\' << '\n'; break;
00070
00071
00072
00073 case '\\' : ostrm << '\\' << '\\'; break;
00074
00075
00076 default : ostrm << s[i]; break;
00077 }
00078 }
00079 }
00080
00081 std::string escapeRead(std::istream& istrm)
00082 {
00083
00084
00085
00086 std::vector<char> buf;
00087
00088 bool finished = false;
00089
00090
00091 istrm >> std::ws;
00092
00093 while (!finished)
00094 {
00095 const int c = char(istrm.get());
00096
00097 switch(c)
00098 {
00099
00100 case EOF:
00101 case ' ':
00102 case '\t':
00103 case '\n':
00104 finished = true;
00105 break;
00106
00107
00108 case '\\':
00109 if (istrm.peek() == EOF)
00110 {
00111
00112 LFATAL("Incomplete escape sequence before EOF!");
00113 }
00114 buf.push_back(char(istrm.get()));
00115 break;
00116
00117
00118 default:
00119 buf.push_back(char(c));
00120 break;
00121 }
00122 }
00123
00124
00125 buf.push_back('\0');
00126
00127
00128 while( istrm.peek() == '\t' || istrm.peek() == ' ' )
00129 istrm.get();
00130
00131 return std::string(&buf[0]);
00132 }
00133
00134 struct Param
00135 {
00136 Param() : str(), pmap() {}
00137
00138 Param(double v) : str(), pmap()
00139 {
00140 std::ostringstream oss;
00141 oss << std::setprecision(25) << v;
00142 str = oss.str();
00143 }
00144
00145 Param(int v) : str(), pmap()
00146 {
00147 std::ostringstream oss; oss << v; str = oss.str();
00148 }
00149
00150 Param(const std::string& s) : str(s), pmap() {}
00151
00152 Param(const rutz::shared_ptr<ParamMap>& p) : str(), pmap(p) {}
00153
00154 void put(std::ostream& ostrm, int indentlev = 0) const
00155 {
00156 if (pmap.get() != 0)
00157 {
00158 ostrm << "{\n";
00159 pmap->format(ostrm, indentlev+1);
00160 for (int i = 0; i < indentlev; ++i) ostrm << '\t';
00161 ostrm << '}';
00162 }
00163 else
00164 {
00165 escapeWrite(ostrm, str);
00166 }
00167 }
00168
00169 double getDouble() const
00170 {
00171 std::istringstream iss(str);
00172 double val;
00173 iss >> val;
00174 return val;
00175 }
00176
00177 int getInt() const
00178 {
00179 std::istringstream iss(str);
00180 int val;
00181 iss >> val;
00182 return val;
00183 }
00184
00185 rutz::shared_ptr<ParamMap> getMap() const
00186 {
00187 if (pmap.get() == 0)
00188 {
00189 LFATAL("No such parameter submap.");
00190 }
00191 return pmap;
00192 }
00193
00194 bool isLeaf() const
00195 {
00196 if (pmap.get() == 0)
00197 return true;
00198 else
00199 return false;
00200 }
00201
00202 std::string str;
00203 mutable rutz::shared_ptr<ParamMap> pmap;
00204 };
00205 }
00206
00207 using namespace dummy_namespace_to_avoid_gcc411_bug_ParamMap_C;
00208
00209
00210 struct ParamMap::Impl
00211 {
00212 typedef std::map<std::string, Param> MapType;
00213
00214 MapType itsParams;
00215 };
00216
00217
00218 struct ParamMap::key_iterator::IterRep
00219 {
00220 ParamMap::Impl::MapType::const_iterator iter;
00221 };
00222
00223
00224 ParamMap::key_iterator::key_iterator() :
00225 rep(new IterRep)
00226 {}
00227
00228
00229 ParamMap::key_iterator::~key_iterator()
00230 {
00231 delete rep;
00232 }
00233
00234
00235 ParamMap::key_iterator::key_iterator(const key_iterator& other) :
00236 rep(new IterRep)
00237 {
00238 rep->iter = other.rep->iter;
00239 }
00240
00241
00242 ParamMap::key_iterator&
00243 ParamMap::key_iterator::operator=(const key_iterator& other)
00244 {
00245 rep->iter = other.rep->iter; return *this;
00246 }
00247
00248
00249 const std::string& ParamMap::key_iterator::operator*() const
00250 {
00251 return (*(rep->iter)).first;
00252 }
00253
00254
00255 ParamMap::key_iterator&
00256 ParamMap::key_iterator::operator++()
00257 {
00258 ++(rep->iter); return *this;
00259 }
00260
00261
00262 bool ParamMap::key_iterator::operator==(const key_iterator& other) const
00263 {
00264 return rep->iter == other.rep->iter;
00265 }
00266
00267
00268 bool ParamMap::key_iterator::operator!=(const key_iterator& other) const
00269 {
00270 return rep->iter != other.rep->iter;
00271 }
00272
00273
00274 rutz::shared_ptr<ParamMap> ParamMap::loadPmapFile(const std::string& fname)
00275 {
00276 rutz::shared_ptr<ParamMap> result(new ParamMap);
00277 result->load(fname);
00278 return result;
00279 }
00280
00281
00282 rutz::shared_ptr<ParamMap> ParamMap::loadConfFile(const std::string& fname)
00283 {
00284 rutz::shared_ptr<ParamMap> pmap(new ParamMap);
00285
00286 std::ifstream inFile(fname.c_str());
00287
00288 int counter = 0;
00289 bool inComment = false;
00290 std::string instring;
00291 std::string paramName;
00292 while (inFile >> instring)
00293 {
00294 if (instring == "#")
00295 {
00296
00297 inComment = !inComment;
00298 }
00299 else if (!inComment)
00300 {
00301 if (paramName.length() == 0)
00302 {
00303 paramName.swap(instring);
00304 }
00305 else
00306 {
00307 pmap->putStringParam(paramName, instring);
00308 LINFO("%s[%d]: %s = %s",
00309 fname.c_str(), counter,
00310 paramName.c_str(), instring.c_str());
00311 paramName.clear();
00312 ++counter;
00313 }
00314 }
00315 }
00316
00317 return pmap;
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 ParamMap::ParamMap() :
00348 rep(new Impl)
00349 {}
00350
00351
00352 ParamMap::ParamMap(const std::string& fname) :
00353 rep(new Impl)
00354 {
00355 load(fname);
00356 }
00357
00358
00359 ParamMap::~ParamMap()
00360 {
00361 delete rep;
00362 }
00363
00364
00365 ParamMap::key_iterator
00366 ParamMap::keys_begin() const
00367 {
00368 key_iterator result;
00369 result.rep->iter = rep->itsParams.begin();
00370 return result;
00371 }
00372
00373
00374 ParamMap::key_iterator
00375 ParamMap::keys_end() const
00376 {
00377 key_iterator result;
00378 result.rep->iter = rep->itsParams.end();
00379 return result;
00380 }
00381
00382
00383 void ParamMap::load(std::istream& istrm)
00384 {
00385 while (istrm.peek() != EOF)
00386 {
00387 if (istrm.peek() == '#')
00388 {
00389 istrm.ignore(std::numeric_limits<int>::max(), '\n');
00390 istrm >> std::ws;
00391 continue;
00392 }
00393
00394 const std::string attribname = escapeRead(istrm);
00395
00396 if (istrm.peek() != '{')
00397 {
00398 std::string attribval;
00399 while( istrm.peek() == '\t' || istrm.peek() == ' ' )
00400 istrm.get();
00401 if ( istrm.peek() == '\n' )
00402 attribval = "";
00403 else
00404 attribval = escapeRead(istrm);
00405
00406 rep->itsParams.insert(Impl::MapType::value_type(attribname,
00407 attribval));
00408 }
00409 else
00410 {
00411 std::string attribval;
00412
00413 int bracelevel = 0;
00414
00415 do
00416 {
00417 int c = istrm.get();
00418
00419 if (c == EOF)
00420 {
00421 LFATAL("Unexpected EOF before closing brace '}'.");
00422 }
00423 switch (c)
00424 {
00425 case '{':
00426
00427 if (bracelevel++ > 0)
00428 attribval.push_back(char(c));
00429 break;
00430 case '}':
00431
00432 if (--bracelevel > 0)
00433 attribval.push_back(char(c));
00434 break;
00435 default:
00436 attribval.push_back(char(c));
00437 break;
00438 }
00439 }
00440 while (bracelevel > 0);
00441
00442 rutz::shared_ptr<ParamMap> submap(new ParamMap);
00443
00444 std::istringstream iss(attribval);
00445 submap->load(iss);
00446
00447 rep->itsParams.insert(Impl::MapType::value_type(attribname, submap));
00448 }
00449
00450 istrm >> std::ws;
00451 }
00452 }
00453
00454
00455 void ParamMap::load(const std::string& fname)
00456 {
00457 std::ifstream ifs(fname.c_str());
00458
00459 if (!ifs.is_open())
00460 {
00461 LFATAL("Couldn't open file '%s' for reading.", fname.c_str());
00462 }
00463
00464 load(ifs);
00465
00466 ifs.close();
00467 }
00468
00469
00470 void ParamMap::format(std::ostream& ostrm, int indentlev) const
00471 {
00472 for (Impl::MapType::const_iterator
00473 itr = rep->itsParams.begin(), stop = rep->itsParams.end();
00474 itr != stop;
00475 ++itr)
00476 {
00477 for (int i = 0; i < indentlev; ++i) ostrm << '\t';
00478 escapeWrite(ostrm, (*itr).first);
00479 ostrm << " ";
00480 (*itr).second.put(ostrm, indentlev);
00481 ostrm << '\n';
00482 }
00483 }
00484
00485
00486 void ParamMap::format(const std::string& fname) const
00487 {
00488 std::ofstream ofs(fname.c_str());
00489
00490 if (!ofs.is_open())
00491 {
00492 LFATAL("Couldn't open file '%s' for writing.", fname.c_str());
00493 }
00494
00495 format(ofs);
00496
00497 ofs.close();
00498 }
00499
00500
00501 bool ParamMap::hasParam(const std::string& paramname) const
00502 {
00503 Impl::MapType::const_iterator itr = rep->itsParams.find(paramname);
00504 return (itr != rep->itsParams.end());
00505 }
00506
00507
00508 bool ParamMap::isLeaf(const std::string& paramname) const
00509 {
00510 Impl::MapType::const_iterator itr = rep->itsParams.find(paramname);
00511 if (itr->second.isLeaf())
00512 return true;
00513 else
00514 return false;
00515 }
00516
00517
00518 uint ParamMap::getsize() const
00519 {
00520 return rep->itsParams.size();
00521 }
00522
00523
00524 rutz::shared_ptr<ParamMap> ParamMap::getSubpmap(const std::string& paramname) const
00525 {
00526 Impl::MapType::const_iterator itr = rep->itsParams.find(paramname);
00527 if (itr == rep->itsParams.end())
00528 {
00529 LFATAL("No parameter named '%s'.", paramname.c_str());
00530 }
00531 return (*itr).second.getMap();
00532 }
00533
00534
00535 std::string ParamMap::getStringParam(const std::string& paramname) const
00536 {
00537 Impl::MapType::const_iterator itr = rep->itsParams.find(paramname);
00538 if (itr == rep->itsParams.end())
00539 {
00540 LFATAL("No parameter named '%s'.", paramname.c_str());
00541 }
00542 return (*itr).second.str;
00543 }
00544
00545
00546 double ParamMap::getDoubleParam(const std::string& paramname) const
00547 {
00548 Impl::MapType::const_iterator itr = rep->itsParams.find(paramname);
00549 if (itr == rep->itsParams.end())
00550 {
00551 LFATAL("No parameter named '%s'.", paramname.c_str());
00552 }
00553 return (*itr).second.getDouble();
00554 }
00555
00556
00557 int ParamMap::getIntParam(const std::string& paramname) const
00558 {
00559 Impl::MapType::const_iterator itr = rep->itsParams.find(paramname);
00560 if (itr == rep->itsParams.end())
00561 {
00562 LFATAL("No parameter named '%s'.", paramname.c_str());
00563 }
00564 return (*itr).second.getInt();
00565 }
00566
00567
00568 std::string ParamMap::getStringParam(const std::string& paramname,
00569 const std::string& defval) const
00570 {
00571 std::string result = defval;
00572 queryStringParam(paramname, result);
00573 return result;
00574 }
00575
00576
00577 double ParamMap::getDoubleParam(const std::string& paramname,
00578 const double defval) const
00579 {
00580 double result = defval;
00581 queryDoubleParam(paramname, result);
00582 return result;
00583 }
00584
00585
00586 int ParamMap::getIntParam(const std::string& paramname,
00587 const int defval) const
00588 {
00589 int result = defval;
00590 queryIntParam(paramname, result);
00591 return result;
00592 }
00593
00594
00595 rutz::shared_ptr<ParamMap> ParamMap::lookupSubpmap(const std::string& paramname)
00596 {
00597 if (hasParam(paramname))
00598 return getSubpmap(paramname);
00599
00600
00601 rutz::shared_ptr<ParamMap> submap(new ParamMap);
00602 putSubpmap(paramname, submap);
00603 return submap;
00604 }
00605
00606
00607 ParamMap::ReturnCode
00608 ParamMap::queryStringParam(const std::string& paramname, std::string& result) const
00609 {
00610 Impl::MapType::const_iterator itr = rep->itsParams.find(paramname);
00611 if (itr != rep->itsParams.end())
00612 {
00613 const std::string new_val = (*itr).second.str;
00614 if (result.compare(new_val) != 0)
00615 {
00616 result = new_val;
00617 return CHANGED;
00618 }
00619 else
00620 return UNCHANGED;
00621 }
00622
00623
00624 LINFO("Parameter '%s' not found; using default value '%s'.",
00625 paramname.c_str(), result.c_str());
00626 return MISSING;
00627 }
00628
00629
00630 ParamMap::ReturnCode
00631 ParamMap::queryDoubleParam(const std::string& paramname, double& result) const
00632 {
00633 Impl::MapType::const_iterator itr = rep->itsParams.find(paramname);
00634 if (itr != rep->itsParams.end())
00635 {
00636 const double new_val = (*itr).second.getDouble();
00637 if (new_val != result)
00638 {
00639 result = new_val;
00640 return CHANGED;
00641 }
00642 else
00643 return UNCHANGED;
00644 }
00645
00646
00647 LINFO("Parameter '%s' not found; using default value '%f'.",
00648 paramname.c_str(), result);
00649 return MISSING;
00650 }
00651
00652
00653 ParamMap::ReturnCode
00654 ParamMap::queryIntParam(const std::string& paramname, int& result) const
00655 {
00656 Impl::MapType::const_iterator itr = rep->itsParams.find(paramname);
00657 if (itr != rep->itsParams.end())
00658 {
00659 const int new_val = (*itr).second.getInt();
00660 if (new_val != result)
00661 {
00662 result = new_val;
00663 return CHANGED;
00664 }
00665 else
00666 return UNCHANGED;
00667 }
00668
00669
00670 LINFO("Parameter '%s' not found; using default value '%d'.",
00671 paramname.c_str(), result);
00672 return MISSING;
00673 }
00674
00675
00676 void ParamMap::putSubpmap(const std::string& paramname, const rutz::shared_ptr<ParamMap>& val)
00677 {
00678 rep->itsParams.insert(Impl::MapType::value_type(paramname, val));
00679 }
00680
00681
00682 void ParamMap::putStringParam(const std::string& paramname, const std::string& val)
00683 {
00684 rep->itsParams.insert(Impl::MapType::value_type(paramname, val));
00685 }
00686
00687
00688 void ParamMap::putDoubleParam(const std::string& paramname, double val)
00689 {
00690 rep->itsParams.insert(Impl::MapType::value_type(paramname, val));
00691 }
00692
00693
00694 void ParamMap::putIntParam(const std::string& paramname, int val)
00695 {
00696 rep->itsParams.insert(Impl::MapType::value_type(paramname, val));
00697 }
00698
00699
00700 void ParamMap::replaceSubpmap(const std::string& paramname,
00701 const rutz::shared_ptr<ParamMap>& val)
00702 {
00703 rep->itsParams.erase(rep->itsParams.find(paramname));
00704 rep->itsParams.insert(Impl::MapType::value_type(paramname, val));
00705 }
00706
00707
00708 void ParamMap::replaceStringParam(const std::string& paramname, const std::string& val)
00709 {
00710 rep->itsParams.erase(rep->itsParams.find(paramname));
00711 rep->itsParams.insert(Impl::MapType::value_type(paramname, val));
00712 }
00713
00714
00715 void ParamMap::replaceDoubleParam(const std::string& paramname, double val)
00716 {
00717 rep->itsParams.erase(rep->itsParams.find(paramname));
00718 rep->itsParams.insert(Impl::MapType::value_type(paramname, val));
00719 }
00720
00721
00722 void ParamMap::replaceIntParam(const std::string& paramname, int val)
00723 {
00724 rep->itsParams.erase(rep->itsParams.find(paramname));
00725 rep->itsParams.insert(Impl::MapType::value_type(paramname, val));
00726 }
00727
00728
00729 void ParamMap::clear()
00730 {
00731 rep->itsParams.clear();
00732 }
00733
00734
00735 void ParamMap::erase(const std::string& paramname)
00736 {
00737
00738 rep->itsParams.erase(rep->itsParams.find(paramname));
00739 }
00740
00741
00742 void ParamMap::print(const std::string& name) const
00743 {
00744 std::cout << "--- begin " << name << " ---\n";
00745 for (Impl::MapType::const_iterator
00746 itr = rep->itsParams.begin(), stop = rep->itsParams.end();
00747 itr != stop;
00748 ++itr)
00749 {
00750 std::cout << "name: " << (*itr).first <<"****" <<std::endl;
00751 std::cout << "val: " << (*itr).second.str <<"****"<< std::endl;
00752 }
00753 std::cout << "--- end " << name << " ---\n";
00754 }
00755
00756
00757
00758
00759
00760
00761
00762 #endif // !PARAMMAP_C_DEFINED