openModeller
Version 1.4.0
|
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