Go to the documentation of this file.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 #include "rviz/config.h"
00031
00032 #include <fstream>
00033 #include <sstream>
00034
00035 namespace rviz
00036 {
00037
00038 bool Config::readFromFile( const std::string& filename )
00039 {
00040 std::ifstream in( filename.c_str() );
00041 if( in )
00042 {
00043 read( in );
00044 return true;
00045 }
00046 else
00047 {
00048 std::cerr << "Config file '" << filename << "' could not be opened for reading." << std::endl;
00049 return false;
00050 }
00051 }
00052
00053 bool Config::writeToFile( const std::string& filename )
00054 {
00055 std::ofstream out( filename.c_str() );
00056 if( out )
00057 {
00058 write( out );
00059 return true;
00060 }
00061 else
00062 {
00063 std::cerr << "Config file '" << filename << "' could not be opened for writing." << std::endl;
00064 return false;
00065 }
00066 }
00067
00068 void Config::read( std::istream& input )
00069 {
00070 size_t equals_sign_index;
00071 std::string line;
00072 std::string current_dir;
00073 std::string key, value;
00074
00075
00076 while( !input.eof() && !input.fail() )
00077 {
00078
00079 line.clear();
00080 std::getline( input, line );
00081
00082 if( line.size() > 0 )
00083 {
00084 if( line[0] == '[' )
00085 {
00086 current_dir = line.substr( 1, line.size() - 2 );
00087 }
00088 else
00089 {
00090
00091 equals_sign_index = line.find_first_of( '=' );
00092 key = line.substr( 0, equals_sign_index );
00093 key = unescapeKey( key );
00094 value = line.substr( equals_sign_index + 1 );
00095
00096
00097 if( key.size() > 0 )
00098 {
00099 if( current_dir.size() > 0 )
00100 {
00101 key = current_dir + '/' + key;
00102 }
00103 set( key, value );
00104 }
00105 }
00106 }
00107 }
00108 }
00109
00110 void Config::write( std::ostream& output )
00111 {
00112 std::string last_prefix;
00113 std::string key_tail;
00114 std::string key_prefix;
00115
00116 for( Iterator it = begin(); it != end(); it++ )
00117 {
00118 const std::string& key = (*it).first;
00119 const std::string& value = (*it).second;
00120 size_t last_slash_index = key.find_last_of( '/' );
00121 if( last_slash_index == std::string::npos )
00122 {
00123 key_tail = key;
00124 key_prefix = "";
00125 }
00126 else
00127 {
00128 key_tail = key.substr( last_slash_index + 1 );
00129 key_prefix = key.substr( 0, last_slash_index );
00130 }
00131 if( key_prefix != last_prefix )
00132 {
00133 writeDirectory( output, key_prefix, last_prefix );
00134 }
00135 key_tail = escapeKey( key_tail );
00136 output << key_tail << "=" << value << std::endl;
00137 last_prefix = key_prefix;
00138 }
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 void Config::writeDirectory( std::ostream& output, const std::string& new_dir, const std::string& prev_dir )
00166 {
00167
00168 size_t min_size = new_dir.size() < prev_dir.size() ? new_dir.size() : prev_dir.size();
00169
00170 size_t index = 0;
00171 for( ; index < min_size; index++ )
00172 {
00173 if( new_dir[ index ] != prev_dir[ index ] )
00174 {
00175 break;
00176 }
00177 }
00178
00179
00180 if( index < new_dir.size() && new_dir[ index ] == '/' )
00181 {
00182 index++;
00183 }
00184
00185
00186
00187 bool done = false;
00188 while( !done )
00189 {
00190 index = new_dir.find_first_of( '/', index );
00191 if( index == std::string::npos )
00192 {
00193 index = new_dir.size();
00194 done = true;
00195 }
00196 output << '[' << new_dir.substr( 0, index ) << ']' << std::endl;
00197 index++;
00198 }
00199 }
00200
00201 std::string Config::escapeKey( const std::string& raw_key )
00202 {
00203 std::istringstream in( raw_key );
00204 std::ostringstream out;
00205 char c;
00206 while( in.good() )
00207 {
00208 c = in.get();
00209 if( in )
00210 {
00211 switch( c )
00212 {
00213 case ':':
00214 case ' ':
00215 case '\\':
00216 out << '\\';
00217 }
00218 out << c;
00219 }
00220 }
00221 return out.str();
00222 }
00223
00224 std::string Config::unescapeKey( const std::string& cooked_key )
00225 {
00226 std::istringstream in( cooked_key );
00227 std::ostringstream out;
00228 char c;
00229 while( in.good() )
00230 {
00231 c = in.get();
00232 if( in.good() )
00233 {
00234 if( c == '\\' )
00235 {
00236 c = in.get();
00237 if( in.good() )
00238 {
00239 out << c;
00240 }
00241 }
00242 else
00243 {
00244 out << c;
00245 }
00246 }
00247 }
00248 return out.str();
00249 }
00250
00251 void Config::set( const std::string& key, float value )
00252 {
00253 std::stringstream ss;
00254 ss << value;
00255 map_[ stripFirstSlash( key )] = ss.str();
00256 }
00257
00258 void Config::set( const std::string& key, int value )
00259 {
00260 std::stringstream ss;
00261 ss << value;
00262 map_[ stripFirstSlash( key )] = ss.str();
00263 }
00264
00265 bool Config::get( const std::string& key, std::string* output, const std::string& default_value )
00266 {
00267 Iterator it = map_.find( stripFirstSlash( key ));
00268 if( it != map_.end() )
00269 {
00270 *output = (*it).second;
00271 return true;
00272 }
00273 *output = default_value;
00274 return false;
00275 }
00276
00277 bool Config::get( const std::string& key, float* output, float default_value )
00278 {
00279 Iterator it = map_.find( stripFirstSlash( key ));
00280 if( it != map_.end() )
00281 {
00282 std::istringstream iss;
00283 iss.str( (*it).second );
00284 iss >> *output;
00285 if( !iss.fail() )
00286 {
00287 return true;
00288 }
00289 }
00290 *output = default_value;
00291 return false;
00292 }
00293
00294 bool Config::get( const std::string& key, int* output, int default_value )
00295 {
00296 Iterator it = map_.find( stripFirstSlash( key ));
00297 if( it != map_.end() )
00298 {
00299 std::istringstream iss;
00300 iss.str( (*it).second );
00301 iss >> *output;
00302 if( !iss.fail() )
00303 {
00304 return true;
00305 }
00306 }
00307 *output = default_value;
00308 return false;
00309 }
00310
00311 const std::string Config::stripFirstSlash( const std::string& str )
00312 {
00313 if( str[0] == '/' )
00314 {
00315 return str.substr( 1 );
00316 }
00317 else
00318 {
00319 return str;
00320 }
00321 }
00322
00323 bool Config::DirectoryCompare::operator() (const std::string& lhs, const std::string& rhs) const
00324 {
00325 int start = 0;
00326 int count;
00327 int rhs_count;
00328 size_t l_slash_index, r_slash_index;
00329 bool l_on_last, r_on_last;
00330
00331
00332
00333
00334
00335 while( true )
00336 {
00337
00338 l_slash_index = lhs.find_first_of( '/', start );
00339 r_slash_index = rhs.find_first_of( '/', start );
00340 l_on_last = ( l_slash_index == std::string::npos );
00341 if( l_on_last )
00342 {
00343 l_slash_index = lhs.size();
00344 }
00345 r_on_last = ( r_slash_index == std::string::npos );
00346 if( r_on_last )
00347 {
00348 r_slash_index = rhs.size();
00349 }
00350
00351
00352
00353
00354
00355 if( !l_on_last && r_on_last )
00356 {
00357 return false;
00358 }
00359 if( l_on_last && !r_on_last )
00360 {
00361 return true;
00362 }
00363
00364
00365 count = l_slash_index - start;
00366 rhs_count = r_slash_index - start;
00367
00368
00369 int result = lhs.compare( start, count, rhs, start, rhs_count );
00370
00371
00372
00373 if( result != 0 )
00374 {
00375 return result < 0;
00376 }
00377
00378
00379
00380 if( start + rhs_count >= (int)rhs.size() )
00381 {
00382 return false;
00383 }
00384
00385
00386
00387 start += count + 1;
00388
00389
00390
00391 if( start > (int)lhs.size() )
00392 {
00393 return true;
00394 }
00395 }
00396 }
00397
00398 }