openModeller  Version 1.4.0
Configuration.cpp
Go to the documentation of this file.
00001 
00028 #include <openmodeller/Configuration.hh>
00029 
00030 #include <iostream>
00031 #include <functional>
00032 #include <algorithm>
00033 #include <sstream>
00034 #include <iterator>
00035 
00036 #include <openmodeller/Sample.hh>
00037 #include <openmodeller/Exceptions.hh>
00038 
00039 using namespace std;
00040 
00041 /***********************************************************************************
00042  *
00043  * Helper code for this module
00044  *
00045  **********************************************************************************/
00046 
00047 // Functor to test attribute name
00048 class AttributeNameTest {
00049 public:
00050   AttributeNameTest( const string& name ) :
00051     name( name )
00052   {}
00053   bool operator()( const Configuration::attribute & a ) {
00054     std::string cmp_name = a.first;
00055     size_t prefix_pos = cmp_name.find(":");
00056     if ( prefix_pos != string::npos ) {
00057       // if there is a namespace prefix, remove it
00058       cmp_name = cmp_name.substr( prefix_pos+1 );
00059     }
00060     return name == cmp_name;
00061   }
00062   string name;
00063 };
00064 
00065 // Functor to test a configuration's name.
00066 class ConfigurationNameTest {
00067 public:
00068   ConfigurationNameTest( const string& name ) :
00069     name( name )
00070   {}
00071   bool operator()( const ConfigurationPtr &config ) {
00072     return name == config->getName();
00073   }
00074   string name;
00075 };
00076       
00077 // Trim characters from front and back of a string.
00078 static void trim( string& str, char const* delims = "\t\r\n ") {
00079   
00080   string::size_type index = str.find_last_not_of(delims);
00081   if( index != string::npos )
00082     str.erase(++index);
00083 
00084   index = str.find_first_not_of( delims );
00085   if( index != string::npos )
00086     str.erase(0,index);
00087   else
00088     str.erase();
00089 }
00090 
00091 // Method to get integer from string
00092 int ConfigurationImpl::getInt( const string& str, int defaultValue ) {
00093   int returnValue = defaultValue;
00094   sscanf( str.c_str(), "%d", &returnValue);
00095   return returnValue;
00096 }
00097 
00098 // Method to get double from string
00099 double ConfigurationImpl::getDouble( const string& str, double defaultValue ) {
00100   double returnValue = defaultValue;
00101   sscanf( str.c_str(), "%lf", &returnValue );
00102   return returnValue;
00103 }
00104 
00105 // Method to get Sample from string
00106 Sample ConfigurationImpl::getSample( const string& str ) {
00107   stringstream ss( str, ios::in );
00108   Sample s;
00109   ss >> s;
00110   return s;
00111 }
00112 
00113 /***********************************************************************************
00114  *
00115  * ConfigurationImpl methods.
00116  *
00117  **********************************************************************************/
00118 ConfigurationImpl::ConfigurationImpl() :
00119   ReferenceCountedObject(),
00120   name(),
00121   value(),
00122   subsections(),
00123   attributes()
00124 {}
00125 
00126 ConfigurationImpl::ConfigurationImpl( char const * name ) :
00127   ReferenceCountedObject(),
00128   name( name ),
00129   value(),
00130   subsections(),
00131   attributes()
00132 {}
00133 
00134 ConfigurationImpl::~ConfigurationImpl()
00135 {}
00136 
00137 string
00138 ConfigurationImpl::getName() const {
00139 
00140   size_t prefix_pos = name.find(":");
00141 
00142   if ( prefix_pos != string::npos ) {
00143 
00144     // if there is a namespace prefix, remove it
00145     return name.substr( prefix_pos+1 );
00146   }
00147 
00148   return name;
00149 }
00150 
00151 void
00152 ConfigurationImpl::setValue( const string& val )
00153 {
00154   value = val;
00155   trim( value );
00156 }
00157 
00158 string
00159 ConfigurationImpl::getValue() const {
00160   return this->value;
00161 }
00162 
00163 ConstConfigurationPtr
00164 ConfigurationImpl::getSubsection( const string & name, bool throws ) const
00165 {
00166   ConfigurationNameTest tester(name);
00167   Configuration::subsection_list::const_iterator c = find_if( subsections.begin(), subsections.end(), tester );
00168 
00169   // Subsection found.
00170   if ( c != subsections.end() ) {
00171 
00172     return ConstConfigurationPtr( *c );
00173   }
00174 
00175   // Subsection not found
00176   if ( throws ) {
00177  
00178    throw SubsectionNotFound( name );
00179   }
00180 
00181   return ConstConfigurationPtr();
00182 }
00183 
00184 ConfigurationPtr
00185 ConfigurationImpl::getSubsection( const string & name, bool throws )
00186 {
00187   ConfigurationNameTest tester(name);
00188   Configuration::subsection_list::iterator c = find_if( subsections.begin(), subsections.end(), tester );
00189 
00190   // Subsection found.
00191   if ( c != subsections.end() ) {
00192 
00193     return ConstConfigurationPtr( *c );
00194   }
00195 
00196   // Subsection not found
00197   if ( throws ) {
00198     throw SubsectionNotFound( name );
00199   }
00200 
00201   return ConstConfigurationPtr();
00202 }
00203 
00204 void
00205 ConfigurationImpl::addSubsection( const ConfigurationPtr & config )
00206 {
00207   subsections.push_back( config );
00208 }
00209 
00210 string
00211 ConfigurationImpl::getAttribute( const string & name ) const
00212 {
00213   AttributeNameTest tester( name );
00214   Configuration::attribute_list::const_iterator nv = find_if( attributes.begin(), attributes.end(), tester );
00215 
00216   if ( nv == attributes.end() ) {
00217 
00218     throw AttributeNotFound( name );
00219   }
00220 
00221   return nv->second;
00222 }
00223 
00224 string
00225 ConfigurationImpl::getAttribute( const string & name, const string& defaultValue ) const
00226 {
00227   AttributeNameTest tester( name );
00228   Configuration::attribute_list::const_iterator nv = find_if( attributes.begin(), attributes.end(), tester );
00229 
00230   if ( nv == attributes.end() ) {
00231 
00232     return defaultValue;
00233   }
00234 
00235   return nv->second;
00236 }
00237 
00238 template<typename T>
00239 vector<T>
00240 ConfigurationImpl::getAttributeAsVec( const string & name ) const {
00241 
00242   string val = getAttribute( name );
00243   
00244   stringstream ss( val, ios::in );
00245 
00246   vector<T> v;
00247 
00248   istream_iterator<T> end;
00249   for ( istream_iterator<T> is_it(ss); is_it != end; is_it ++ ) {
00250 
00251     v.push_back( *is_it );
00252   }
00253 
00254   return v;
00255 }
00256 
00257 int
00258 ConfigurationImpl::getAttributeAsInt( const string & name, int defaultvalue ) const {
00259 
00260   string val = getAttribute( name, "" );
00261 
00262   int returnValue = defaultvalue;
00263 
00264   sscanf( val.c_str(), "%d", &returnValue );
00265 
00266   return returnValue;
00267 }
00268 
00269 double
00270 ConfigurationImpl::getAttributeAsDouble( const string & name, double defaultvalue ) const {
00271   string val = getAttribute( name, "" );
00272 
00273   double returnValue = defaultvalue;
00274 
00275   sscanf( val.c_str(), "%lf", &returnValue );
00276   
00277   return returnValue;
00278 }
00279 
00280 vector<double>
00281 ConfigurationImpl::getAttributeAsVecDouble( const string & name ) const {
00282 
00283   string val = getAttribute( name );
00284   
00285   stringstream ss( val, ios::in );
00286 
00287   vector<double> v;
00288 
00289   istream_iterator<double> end;
00290   for ( istream_iterator<double> is_it(ss);
00291   is_it != end;
00292   is_it ++ ) {
00293 
00294     v.push_back( *is_it );
00295   }
00296 
00297   return v;
00298 }
00299 
00300 void
00301 ConfigurationImpl::getAttributeAsDoubleArray( const string & name, double **arry, int *dim ) const {
00302 
00303   vector<double> vec = getAttributeAsVecDouble( name );
00304 
00305   if ( dim ) {
00306 
00307     *dim = vec.size();
00308   }
00309 
00310   if ( arry ) {
00311 
00312     int end = vec.size();
00313 
00314     *arry = new double[ end ];
00315 
00316     for (int i=0; i<end; i++ ) {
00317       (*arry)[i] = vec[i];
00318     }
00319   }
00320 }
00321 
00322 vector<int>
00323 ConfigurationImpl::getAttributeAsVecInt( const string & name ) const {
00324 
00325   string val = getAttribute( name );
00326   
00327   stringstream ss( val, ios::in );
00328 
00329   vector<int> v;
00330 
00331   istream_iterator<int> end;
00332   for ( istream_iterator<int> is_it(ss); is_it != end; is_it ++ ) {
00333 
00334     v.push_back( *is_it );
00335   }
00336 
00337   return v;
00338 }
00339 
00340 void
00341 ConfigurationImpl::getAttributeAsIntArray( const string & name, int **arry, int *dim ) const {
00342 
00343   vector<int> vec = getAttributeAsVecInt( name );
00344 
00345   if ( dim ) {
00346 
00347     *dim = vec.size();
00348   }
00349 
00350   if ( arry ) {
00351 
00352     int end = vec.size();
00353 
00354     *arry = new int[ end ];
00355 
00356     for ( int i=0; i<end; i++ ) {
00357 
00358       (*arry)[i] = vec[i];
00359     }
00360   }
00361 }
00362 
00363 Sample
00364 ConfigurationImpl::getAttributeAsSample( const string & name ) const {
00365 
00366   string v = getAttribute( name );
00367 
00368   stringstream is(v, ios::in );
00369 
00370   Sample sample;
00371 
00372   is >> sample;
00373 
00374   return sample;
00375 }
00376 
00377 void
00378 ConfigurationImpl::getAttributeAsByteArray( const string & name, unsigned char **arry, int *dim ) const {
00379 
00380   vector<int> vec = getAttributeAsVec<int>( name );
00381 
00382   if ( dim ) {
00383 
00384     *dim = vec.size();
00385   }
00386 
00387   if ( arry ) {
00388 
00389     int end = vec.size();
00390 
00391     *arry = new unsigned char[ end ];
00392 
00393     for ( int i=0; i<end; i++ ) {
00394 
00395       (*arry)[i] = (unsigned char) (vec[i] & 0x00FF) ;
00396     }
00397   }
00398 }
00399 
00400 void
00401 ConfigurationImpl::addNameValue( const string & name, const string & value ) {
00402 
00403   string theval = value;
00404   trim(theval);
00405 
00406   attributes.push_back( make_pair( name, theval ) );
00407 }
00408 
00409 void
00410 ConfigurationImpl::addNameValue( const string & name, char const *value ) {
00411   
00412   string sval( (value)? value: "");
00413 
00414   addNameValue( name, sval );
00415 }
00416 
00417 void
00418 ConfigurationImpl::addNameValue( const string & name, int value ) {
00419 
00420   stringstream ss(ios::out);
00421 
00422   ss << value;
00423 
00424   addNameValue( name, ss.str() );
00425 }
00426 
00427 void
00428 ConfigurationImpl::addNameValue( const string & name, double value, int precision ) {
00429 
00430   stringstream ss(ios::out);
00431   ss.precision(precision);
00432 
00433   ss << value;
00434 
00435   addNameValue( name, ss.str() );
00436 }
00437 
00438 void
00439 ConfigurationImpl::addNameValue( const string & name, double const *values, int count, int precision ) {
00440 
00441   stringstream ss(ios::out);
00442   ss.precision(precision);
00443 
00444   for ( int i=0; i<count; i++ ) {
00445     ss << *values++ << " ";
00446   }
00447 
00448   addNameValue( name, ss.str() );
00449 }
00450 
00451 void
00452 ConfigurationImpl::addNameValue( const string & name, int const *values, int count ) {
00453 
00454   stringstream ss(ios::out);
00455 
00456   for ( int i=0; i<count; i++ ) {
00457     ss << *values++ << " ";
00458   }
00459 
00460   addNameValue( name, ss.str() );
00461 }
00462 
00463 void
00464 ConfigurationImpl::addNameValue( const string & name, const Sample& value ) {
00465 
00466   stringstream ss(ios::out);
00467 
00468   ss << value;
00469 
00470   addNameValue( name, ss.str() );
00471 }
00472 
00473 void
00474 ConfigurationImpl::addNameValue( const string & name, unsigned char const *values, int count ) {
00475 
00476   stringstream ss(ios::out);
00477 
00478   for ( int i=0; i<count; i++ ) {
00479 
00480     ss << (int)*values++ << " ";
00481   }
00482 
00483   addNameValue( name, ss.str() );
00484 }
00485