Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

PisaPhnxParv1.C

Go to the documentation of this file.
00001 #include "PisaPhnxParv1.h"
00002 
00003 ClassImp(PisaPhnxParv1)
00004 
00005 ClassImp(PisaPhnxSubParv1)
00006 
00007 //_____________________________________________________________________________
00008 void 
00009 split(const std::string& path, 
00010       std::vector<std::string>& paths,
00011       char sep)
00012 {
00013   // Given a path e.g. /Cut##/OK/C#/V#, will return 
00014   // a vector of string with Cut#, 
00015 
00016   paths.clear();
00017 
00018   std::string str = path;
00019 
00020   if ( str.empty() )
00021     {
00022       return;
00023     }
00024 
00025   std::vector<size_t> sep_pos;
00026 
00027   if ( str[0] != sep ) 
00028     { 
00029       str.insert(str.begin(),sep);
00030     }
00031 
00032   if ( str[str.size()-1] != sep ) 
00033     {
00034       str.push_back(sep);
00035     }
00036 
00037   for (size_t i = 0 ; i < str.size() ; i++) 
00038     {
00039       if ( str[i] == sep ) 
00040         { 
00041           sep_pos.push_back(i);
00042         }
00043     }
00044 
00045   if ( sep_pos.size() > 0 ) 
00046     {
00047       for (size_t i = 0 ; i < sep_pos.size()-1 ; i++) 
00048         {
00049           paths.push_back(str.substr(sep_pos[i]+1,
00050                                      sep_pos[i+1]-sep_pos[i]-1));
00051         }
00052     }  
00053 }
00054 
00055 //_____________________________________________________________________________
00056 std::string 
00057 trim(const std::string& source, const std::string& ws)
00058 {
00059   std::string str;
00060 
00061   for ( size_t j = 0; j < source.size(); ++j )
00062     {
00063       bool ok = true;
00064       for ( size_t i = 0; i < ws.size() && ok == true ; ++i )
00065         {
00066           if ( ws[i] == source[j] )
00067             {
00068               ok = false;
00069             }
00070         }
00071       if ( ok )
00072         {
00073           str += source[j];
00074         }
00075     }
00076   return str;
00077 }
00078 
00079 
00080 //_____________________________________________________________________________
00081 void
00082 PisaPhnxParv1::closeParameter(const std::string& subsystem,
00083                           const std::string& parameter,
00084                           const std::string& value)
00085 {
00086   if (!parameter.empty())
00087     {
00088       bool isboolean = false;
00089       bool isinteger = false;
00090       bool isdouble = false;
00091       bool isstring = false;
00092 
00093       if ( value.find(".TRUE") < value.size() ||
00094            value.find(".FALSE.") < value.size() )
00095         {
00096           isboolean=true;
00097         }
00098       else if ( value.find('\'') < value.size() )
00099         {
00100           isstring=true;
00101         }
00102       else if ( value.find('.') < value.size() )
00103         {
00104           isdouble=true;
00105         }
00106       else
00107         {
00108           isinteger=true;
00109         }
00110 
00111       // Split the value field.
00112       std::vector<std::string> parts;
00113       split(value,parts,',');
00114       
00115 #ifdef DEBUG
00116       std::cout << "subsystem:" << subsystem
00117                 << " parameter:" << parameter;
00118       if ( isboolean ) std::cout << "(boolean)";
00119       if ( isinteger ) std::cout << "(integer)";
00120       if ( isstring ) std::cout << "(string)";
00121       if ( isdouble ) std::cout << "(double)";
00122 #endif
00123 
00124       // Take care of multiplier qualifier '*'
00125       std::vector<std::string> mparts;
00126 
00127       for ( size_t i = 0; i < parts.size(); ++i )
00128         {   
00129           if ( parts[i].find('*') < parts[i].size() )
00130             {
00131               // Multiplicator sign found. Duplicate entries as needed.
00132               std::vector<std::string> tmp;
00133               split(parts[i],tmp,'*');
00134               assert(tmp.size()==2);
00135               int n = atoi(tmp[0].c_str());
00136               while ( n-- )
00137                 {
00138                   mparts.push_back(tmp[1]);
00139                 }
00140             }
00141           else
00142             {
00143               mparts.push_back(parts[i]);
00144             }
00145         }
00146 
00147       PisaPhnxSubParv1& par = fMap[subsystem];
00148 
00149       for ( size_t i = 0; i < mparts.size(); ++i )
00150         {     
00151           std::string value = mparts[i];
00152 
00153 #ifdef DEBUG
00154           std::cout << " : " << value;
00155 #endif
00156           if (isboolean)
00157             {
00158               std::transform(value.begin(), value.end(), value.begin(), 
00159                              (int(*)(int))std::toupper);
00160 
00161               if ( value.find("TRUE") < value.size() )
00162                 {
00163                   par.appendBoolean(parameter.c_str(),true);
00164                 }
00165               else if ( value.find("FALSE") < value.size() )
00166                 {
00167                   par.appendBoolean(parameter.c_str(),false);
00168                 }
00169               else
00170                 {
00171                   assert(0==1);
00172                 }
00173             }
00174           else if ( isinteger )
00175             {
00176               par.appendInt(parameter.c_str(),atoi(value.c_str()));
00177             }
00178           else if ( isdouble ) 
00179             {
00180               par.appendDouble(parameter.c_str(),atof(value.c_str()));
00181             }
00182           else if ( isstring )
00183             {
00184               assert(value.size()-2>0);
00185               par.appendString(parameter.c_str(),
00186                                value.substr(1,value.size()-2).c_str());
00187               // remove leading and trailing '
00188             }
00189           else
00190             {
00191               assert(0==1);
00192             }
00193         }
00194 #ifdef DEBUG
00195       std::cout << std::endl;
00196 #endif
00197     }
00198 }
00199 
00200 //_____________________________________________________________________________
00201 PisaPhnxParv1::PisaPhnxParv1(const char* file)
00202 {
00203   std::ifstream in(file);
00204 
00205   if (!in) throw;
00206 
00207   std::string line;
00208   std::string subsystem = "";
00209   std::string parameter = "";
00210   std::string value = "";
00211 
00212   while ( std::getline(in,line) )
00213     {
00214       if ( line[0] != ' ' && line[0] != '\t' )
00215         {
00216           // comment line
00217           continue;
00218         }
00219 
00220       if ( line.find('$') < line.size() )
00221         {
00222           if ( line.find("$end") < line.size() )
00223             {
00224               // end of subsystem. Close current parameter.
00225               closeParameter(subsystem,parameter,value);
00226               parameter = "";
00227             }
00228           subsystem = trim(line," \t"); // remove whitespaces
00229           subsystem = subsystem.substr(1,subsystem.size()-1); // remove leading $
00230           continue;
00231         }
00232 
00233       if ( line.find('=') < line.size() )
00234         {        
00235           // New parameter. First close the current one, if any.
00236           closeParameter(subsystem,parameter,value);
00237           
00238           std::vector<std::string> parts;
00239           split(line,parts,'=');
00240           parameter = trim(parts[0]," \t");
00241           value = trim(parts[1]," \t");
00242         }
00243       else
00244         {
00245           // continuation line of the same parameter.
00246           value += trim(line," \t");
00247         }
00248     }
00249 
00250   in.close();
00251 
00252 }
00253 
00254 //_____________________________________________________________________________
00255 bool
00256 PisaPhnxParv1::has(const char* subsystem) const
00257 {
00258   return fMap.find(subsystem) != fMap.end();
00259 }
00260 
00261 //_____________________________________________________________________________
00262 void
00263 PisaPhnxParv1::print(std::ostream& os) const
00264 {
00265   TMAP::const_iterator it;
00266 
00267   for ( it = fMap.begin(); it != fMap.end(); ++it )
00268     {
00269       os << std::string(80,'-') << std::endl;
00270       os << "Subsystem " << it->first << " parameters:" << std::endl;
00271       os << it->second << std::endl;
00272     }
00273 }
00274 
00275 //_____________________________________________________________________________
00276 const PisaPhnxSubParv1*
00277 PisaPhnxParv1::get(const char* subsystem) const
00278 {
00279   if ( has(subsystem) )
00280     {
00281       return &fMap.find(subsystem)->second;
00282     }
00283   else
00284     {
00285       std::cerr << __FILE__ << ":" << __LINE__
00286                 << "Do not know this subsystem=" 
00287                 << subsystem
00288                 << std::endl;
00289       return 0;
00290     }
00291 }