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 #include "Exception.hpp"
00026 namespace indri
00027 {
00028 namespace api
00029 {
00030
00036 class Parameters {
00037 public:
00039 struct parameter_value {
00040 typedef std::map<std::string, parameter_value*> MValue;
00042 MValue table;
00043 typedef std::vector<parameter_value*> VValue;
00045 std::vector<parameter_value*> array;
00047 std::string value;
00048
00049 public:
00051 parameter_value() {}
00054 parameter_value( const parameter_value& other ) {
00055 value = other.value;
00056
00057 for( size_t i=0; i<other.array.size(); i++ )
00058 array.push_back( new parameter_value( *other.array[i] ) );
00059
00060 for( MValue::const_iterator iter = other.table.begin();
00061 iter != other.table.end();
00062 iter++ )
00063 {
00064 table.insert( std::make_pair( iter->first,
00065 new parameter_value( *(iter->second) ) ) );
00066 }
00067 }
00069 ~parameter_value() {
00070 clear();
00071 }
00072
00074 void clear() {
00075 for( std::map<std::string, parameter_value*>::iterator iter = table.begin();
00076 iter != table.end();
00077 iter++ )
00078 {
00079 delete iter->second;
00080 }
00081 table.clear();
00082
00083 indri::utility::delete_vector_contents<parameter_value*>(array);
00084 value = "";
00085 }
00086
00088 void convertToArray() {
00089 if( !array.size() && ( table.size() || value.size() ) ) {
00090 parameter_value* child = new parameter_value;
00091
00092 child->table = table;
00093 child->value = value;
00094
00095 table.clear();
00096 value = "";
00097
00098 array.push_back(child);
00099 }
00100 }
00104 const std::string& getValue() {
00105 if( !array.size() )
00106 return value;
00107 else
00108 return array[0]->value;
00109 }
00110
00111 };
00112
00113 protected:
00114 parameter_value* _collection;
00115 bool _owned;
00116
00117 parameter_value* _getRoot();
00118 parameter_value* _getPath( const std::string& path, Parameters::parameter_value* last, int offset = 0 );
00119 parameter_value* _createPath( const std::string& path );
00120 void _parseNextSegment( std::string& segment, int& arrayIndex, int& endOffset, const std::string& path, int beginOffset );
00121 parameter_value* _getSegment( const std::string& segment, int arrayIndex, Parameters::parameter_value* from );
00122
00123 void _loadXML( class indri::xml::XMLNode* node );
00124 void _fillXML( class indri::xml::XMLNode* node );
00125
00126 INT64 _multiplier( const std::string& value ) {
00127 if( !value.length() )
00128 return 1;
00129
00130 char suffix = value[ value.length()-1 ];
00131
00132 switch( suffix ) {
00133 case 'K':
00134 case 'k':
00135 return 1000;
00136
00137 case 'M':
00138 case 'm':
00139 return 1000000;
00140
00141 case 'G':
00142 case 'g':
00143 return 1000000000;
00144 }
00145
00146 return 1;
00147 }
00148
00149 bool _isBoolean( const std::string& value ) {
00150 if( !value.length() )
00151 return false;
00152
00153 char first = value[0];
00154
00155 switch(first) {
00156 case 'Y':
00157 case 'y':
00158 case 'N':
00159 case 'n':
00160 case 'T':
00161 case 't':
00162 case 'F':
00163 case 'f':
00164 return true;
00165 }
00166
00167 return false;
00168 }
00169
00170 bool _asBoolean( const std::string& value ) {
00171 char first = value[0];
00172
00173 switch(first) {
00174 case 'Y':
00175 case 'y':
00176 case 'T':
00177 case 't':
00178 case '1':
00179 return true;
00180
00181 case 'F':
00182 case 'f':
00183 case 'N':
00184 case 'n':
00185 case '0':
00186 return false;
00187 }
00188
00189 return false;
00190 }
00191
00192 public:
00194 Parameters();
00197 Parameters( const Parameters& other );
00200 Parameters( parameter_value* value );
00204 Parameters( const std::string& path, parameter_value* value );
00206 ~Parameters();
00208 operator double () {
00209 const std::string& value = _getRoot()->getValue();
00210 return atof( value.c_str() );
00211 }
00212
00213 operator bool () {
00214 const std::string& value = _getRoot()->getValue();
00215 return _asBoolean(value);
00216 }
00217
00222 operator int () {
00223 const std::string& value = _getRoot()->getValue();
00224 if (value.length() == 0)
00225 LEMUR_THROW(LEMUR_BAD_PARAMETER_ERROR, "Empty parameter text" );
00226 if( _isBoolean(value) )
00227 return _asBoolean(value);
00228
00229 int multiplier = (int) _multiplier( value );
00230
00231 if( multiplier > 1 ) {
00232 std::string prefix = value.substr( 0, value.length() - 1 );
00233 return multiplier * atoi( prefix.c_str() );
00234 }
00235
00236 return atoi( value.c_str() );
00237 }
00238
00243 operator INT64 () {
00244 const std::string& value = _getRoot()->getValue();
00245 INT64 multiplier = _multiplier( value );
00246
00247 if( _isBoolean(value) )
00248 return _asBoolean(value);
00249
00250 if( multiplier > 1 ) {
00251 std::string prefix = value.substr( 0, value.length() - 1);
00252 return multiplier * string_to_i64( prefix.c_str() );
00253 }
00254
00255 return string_to_i64( value );
00256 }
00257
00259 operator std::string () {
00260 std::string value = _getRoot()->getValue();
00261 return value;
00262 }
00263
00267 const Parameters& operator= ( const Parameters& other ) {
00268 _collection->value = other._collection->value;
00269
00270 indri::utility::delete_vector_contents( _collection->array );
00271 indri::utility::delete_map_contents( _collection->table );
00272
00273 for( size_t i=0; i<other._collection->array.size(); i++ ) {
00274 _collection->array.push_back( new parameter_value( *other._collection->array[i] ) );
00275 }
00276
00277 parameter_value::MValue::iterator iter;
00278
00279 for( iter = other._collection->table.begin();
00280 iter != other._collection->table.end();
00281 iter++ ) {
00282 _collection->table.insert( std::make_pair( iter->first,
00283 new parameter_value( *iter->second ) ) );
00284 }
00285
00286 return *this;
00287 }
00288
00292 Parameters get( size_t index );
00296 Parameters get( const std::string& name );
00300 Parameters get( const char* name );
00301
00302 bool get( const std::string& name, bool def );
00308 int get( const std::string& name, int def );
00314 double get( const std::string& name, double def );
00320 INT64 get( const std::string& name, INT64 def );
00321 std::string get( const std::string& name, const char* def );
00327 std::string get( const std::string& name, const std::string& def );
00328
00332 Parameters operator[] ( size_t index );
00336 Parameters operator[] ( const std::string& path );
00340 Parameters operator[] ( const char* path );
00344 Parameters append( const std::string& path );
00348 void remove( const std::string& path );
00349
00350 void set( const std::string& name, bool value );
00351 void set( const std::string& name, const char* value );
00355 void set( const std::string& name, const std::string& value );
00359 void set( const std::string& name, int value );
00363 void set( const std::string& name, UINT64 value );
00367 void set( const std::string& name, INT64 value );
00371 void set( const std::string& name, double value );
00374 void set( const std::string& value );
00375
00377 void clear();
00378
00380 size_t size();
00383 bool exists( size_t index );
00386 bool exists( const std::string& name );
00387
00390 indri::xml::XMLNode* toXML();
00391
00393 static Parameters& instance();
00394
00397 void load( const std::string& text );
00400 void loadFile( const std::string& filename );
00404 void loadCommandLine( int argc, char** argv );
00407 void write( std::string& text );
00410 void writeFile( const std::string& filename );
00411 };
00412 }
00413 }
00414
00415 #endif // INDRI_PARAMETERS_HPP