00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef INDRI_PARAMETERS_HPP
00020 #define INDRI_PARAMETERS_HPP
00021
00022 #include <string>
00023 #include "indri/XMLNode.hpp"
00024 #include "indri/delete_range.hpp"
00025
00031 class Parameters {
00032 public:
00034 struct parameter_value {
00035 typedef std::map<std::string, parameter_value*> MValue;
00037 MValue table;
00038 typedef std::vector<parameter_value*> VValue;
00040 std::vector<parameter_value*> array;
00042 std::string value;
00043
00044 public:
00046 parameter_value() {}
00049 parameter_value( const parameter_value& other ) {
00050 value = other.value;
00051
00052 for( size_t i=0; i<other.array.size(); i++ )
00053 array.push_back( new parameter_value( *other.array[i] ) );
00054
00055 for( MValue::const_iterator iter = other.table.begin();
00056 iter != other.table.end();
00057 iter++ )
00058 {
00059 table.insert( std::make_pair( iter->first,
00060 new parameter_value( *(iter->second) ) ) );
00061 }
00062 }
00064 ~parameter_value() {
00065 for( std::map<std::string, parameter_value*>::iterator iter = table.begin();
00066 iter != table.end();
00067 iter++ )
00068 {
00069 delete iter->second;
00070 }
00071
00072 delete_vector_contents<parameter_value*>(array);
00073 }
00075 void convertToArray() {
00076 if( !array.size() && ( table.size() || value.size() ) ) {
00077 parameter_value* child = new parameter_value;
00078
00079 child->table = table;
00080 child->value = value;
00081
00082 table.clear();
00083 value = "";
00084
00085 array.push_back(child);
00086 }
00087 }
00091 const std::string& getValue() {
00092 if( !array.size() )
00093 return value;
00094 else
00095 return array[0]->value;
00096 }
00097
00098 };
00099
00100 protected:
00101 parameter_value* _collection;
00102 bool _owned;
00103
00104 parameter_value* _getRoot();
00105 parameter_value* _getPath( const std::string& path, Parameters::parameter_value* last, int offset = 0 );
00106 parameter_value* _createPath( const std::string& path );
00107 void _parseNextSegment( std::string& segment, int& arrayIndex, int& endOffset, const std::string& path, int beginOffset );
00108 parameter_value* _getSegment( const std::string& segment, int arrayIndex, Parameters::parameter_value* from );
00109
00110 void _loadXML( class XMLNode* node );
00111 void _fillXML( class XMLNode* node );
00112
00113 INT64 _multiplier( const std::string& value ) {
00114 if( !value.length() )
00115 return 1;
00116
00117 char suffix = value[ value.length()-1 ];
00118
00119 switch( suffix ) {
00120 case 'K':
00121 case 'k':
00122 return 1000;
00123
00124 case 'M':
00125 case 'm':
00126 return 1000000;
00127
00128 case 'G':
00129 case 'g':
00130 return 1000000000;
00131 }
00132
00133 return 1;
00134 }
00135
00136 bool _isBoolean( const std::string& value ) {
00137 if( !value.length() )
00138 return false;
00139
00140 char first = value[0];
00141
00142 switch(first) {
00143 case 'Y':
00144 case 'y':
00145 case 'N':
00146 case 'n':
00147 case 'T':
00148 case 't':
00149 case 'F':
00150 case 'f':
00151 return true;
00152 }
00153
00154 return false;
00155 }
00156
00157 bool _asBoolean( const std::string& value ) {
00158 char first = value[0];
00159
00160 switch(first) {
00161 case 'Y':
00162 case 'y':
00163 case 'T':
00164 case 't':
00165 return true;
00166 }
00167
00168 return false;
00169 }
00170
00171 public:
00173 Parameters();
00176 Parameters( const Parameters& other );
00179 Parameters( parameter_value* value );
00183 Parameters( const std::string& path, parameter_value* value );
00185 ~Parameters();
00187 operator double () {
00188 const std::string& value = _getRoot()->getValue();
00189 return atof( value.c_str() );
00190 }
00191
00192 operator bool () {
00193 const std::string& value = _getRoot()->getValue();
00194 return _asBoolean(value);
00195 }
00196
00201 operator int () {
00202 const std::string& value = _getRoot()->getValue();
00203
00204 if( _isBoolean(value) )
00205 return _asBoolean(value);
00206
00207 int multiplier = (int) _multiplier( value );
00208
00209 if( multiplier > 1 ) {
00210 std::string prefix = value.substr( 0, value.length() );
00211 return multiplier * atoi( prefix.c_str() );
00212 }
00213
00214 return atoi( value.c_str() );
00215 }
00216
00221 operator INT64 () {
00222 const std::string& value = _getRoot()->getValue();
00223 INT64 multiplier = _multiplier( value );
00224
00225 if( _isBoolean(value) )
00226 return _asBoolean(value);
00227
00228 if( multiplier > 1 ) {
00229 std::string prefix = value.substr( 0, value.length() );
00230 return multiplier * string_to_i64( prefix.c_str() );
00231 }
00232
00233 return string_to_i64( value );
00234 }
00235
00237 operator std::string () {
00238 std::string value = _getRoot()->getValue();
00239 return value;
00240 }
00241
00245 const Parameters& operator= ( const Parameters& other ) {
00246 _collection->value = other._collection->value;
00247
00248 delete_vector_contents( _collection->array );
00249 delete_map_contents( _collection->table );
00250
00251 for( size_t i=0; i<other._collection->array.size(); i++ ) {
00252 _collection->array.push_back( new parameter_value( *other._collection->array[i] ) );
00253 }
00254
00255 parameter_value::MValue::iterator iter;
00256
00257 for( iter = other._collection->table.begin();
00258 iter != other._collection->table.end();
00259 iter++ ) {
00260 _collection->table.insert( std::make_pair( iter->first,
00261 new parameter_value( *iter->second ) ) );
00262 }
00263
00264 return *this;
00265 }
00266
00270 Parameters get( int index );
00274 Parameters get( const std::string& name );
00278 Parameters get( const char* name );
00279
00280 bool get( const std::string& name, bool def );
00286 int get( const std::string& name, int def );
00292 double get( const std::string& name, double def );
00298 INT64 get( const std::string& name, INT64 def );
00299 std::string get( const std::string& name, const char* def );
00305 std::string get( const std::string& name, const std::string& def );
00306
00310 Parameters operator[] ( int index );
00314 Parameters operator[] ( const std::string& path );
00318 Parameters operator[] ( const char* path );
00322 Parameters append( const std::string& path );
00326 void remove( const std::string& path );
00327
00328 void set( const std::string& name, bool value );
00329 void set( const std::string& name, const char* value );
00333 void set( const std::string& name, const std::string& value );
00337 void set( const std::string& name, int value );
00341 void set( const std::string& name, UINT64 value );
00345 void set( const std::string& name, double value );
00348 void set( const std::string& value );
00349
00351 size_t size();
00354 bool exists( int index );
00357 bool exists( const std::string& name );
00358
00361 XMLNode* toXML();
00362
00364 static Parameters& instance();
00365
00368 void load( const std::string& text );
00371 void loadFile( const std::string& filename );
00375 void loadCommandLine( int argc, char** argv );
00378 void write( std::string& text );
00381 void writeFile( const std::string& filename );
00382 };
00383
00384 #endif // INDRI_PARAMETERS_HPP