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
00031
00032
00033
00034
00035
00036 #ifndef ENV_PARAM_PARAM_DB_H
00037 #define ENV_PARAM_PARAM_DB_H
00038
00039 #include "Env/Param/ParamXMLTree.h"
00040
00041 namespace Onikiri
00042 {
00043
00044 class ParamDB
00045 {
00046 protected:
00047 typedef ParamXMLTree::Node XMLNode;
00048 typedef ParamXMLTree::NodePtr XMLNodePtr;
00049 typedef ParamXMLTree::NodeArray XMLNodeArray;
00050 typedef ParamXMLTree::ChildMap XMLChildMap;
00051 typedef ParamXMLTree::AttributeMap XMLAttributeMap;
00052
00053 String m_initialPath;
00054 ParamXMLTree m_tree;
00055 bool m_isLoaded;
00056 bool m_initialized;
00057 bool m_userParamPassed;
00058
00059 String CompletePath( const String& target, const String& basePath );
00060 String RemoveFileName( const String& path );
00061
00062 void AddExternalParameterToList( const String& name, const String& value );
00063
00064 template <class T>
00065 String ToString( const ParamXMLPath& path, const T& param )
00066 {
00067 return boost::lexical_cast<std::string>(param);
00068 };
00069
00070 template <class T>
00071 void ToParamRaw( T* dst, const ParamXMLPath& path, const String& str )
00072 {
00073 try{
00074 *dst = boost::lexical_cast<T>(str);
00075 }
00076 catch(boost::bad_lexical_cast& e){
00077 THROW_RUNTIME_ERROR(
00078 "ParamDB parameter conversion failed.\n"
00079 "Could not convert '%s' to user defined value.\n%s",
00080 path.ToString().c_str(), e.what()
00081 );
00082 }
00083 }
00084
00085 template <class T>
00086 void ToParam( T* dst, const ParamXMLPath& path, const String& str )
00087 {
00088 boost::bad_lexical_cast orgExc;
00089 try{
00090 *dst = boost::lexical_cast<T>(str);
00091 return;
00092 }
00093 catch(boost::bad_lexical_cast& e){
00094 orgExc = e;
00095 }
00096
00097 try{
00098 if(str.length() < 2){
00099 throw orgExc;
00100 }
00101
00102 char suffix = str.at(str.length() - 1);
00103 T base =
00104 boost::lexical_cast<T>(
00105 str.substr(0, str.length() - 1) );
00106
00107 switch(suffix){
00108 case 'k': case 'K':
00109 *dst = base*1000;
00110 break;
00111 case 'm': case 'M':
00112 *dst = base*1000000;
00113 break;
00114 case 'g': case 'G':
00115 *dst = base*1000000000;
00116 break;
00117 default:
00118 throw orgExc;
00119 break;
00120 }
00121
00122 }
00123 catch(boost::bad_lexical_cast&){
00124 THROW_RUNTIME_ERROR(
00125 "ParamDB parameter conversion failed.\n"
00126 "Could not convert '%s' to user defined value.\n%s",
00127 path.ToString().c_str(), orgExc.what()
00128 );
00129 }
00130
00131 };
00132
00133
00134
00135 void ToParam( bool* dst, const ParamXMLPath& path, const String& str );
00136 void ToParam( String* dst, const ParamXMLPath& path, const String& str );
00137 void ToParam( std::string* dst, const ParamXMLPath& path, const String& str );
00138
00139
00140 void CheckResultXML( const String& path, XMLNodePtr node, int* warningCount );
00141
00142
00143
00144 bool FilterResultXML( const String& path, XMLNodePtr node, const std::vector<String>& filterList );
00145
00146
00147 bool MatchFilterList( const String& str, const std::vector<String>& filterList ) const;
00148
00149
00150 public:
00151 ParamDB();
00152 ~ParamDB();
00153
00154 bool Initialize( const String& initialPath );
00155 void Finalize();
00156 const std::vector<ParamXMLTree::InputInfo>& GetXMLFileNames();
00157
00158
00159
00160 void LoadXMLFile(const String&);
00161
00162
00163 void LoadParameters(const std::vector<String>&);
00164
00165
00166
00167 void AddParameter(const String& paramExp);
00168
00169
00170 void AddUserDefaultParam(const String& xmlString);
00171
00172
00173 String DumpResultXML( const String& level, const String& filter );
00174
00175
00176 bool GetSourceXMLFile(const ParamXMLPath& parameterPath, String& sourceFile);
00177
00178
00179 size_t GetElementCount(const ParamXMLPath& path);
00180
00181
00182 ParamXMLTree& GetXMLTree();
00183
00184
00185 template <typename ValueType>
00186 struct Binding
00187 {
00188 const char* str;
00189 ValueType value;
00190 };
00191
00192
00193
00194
00195
00196
00197 void Set(const ParamXMLPath& path, const String&);
00198
00199
00200 template <class T>
00201 void Set(const ParamXMLPath& path, const T& param)
00202 {
00203 T orgParam = T();
00204 if( !Get( path, &orgParam ) || orgParam != param ){
00205
00206
00207
00208 Set( path, ToString( path, param ) );
00209 }
00210 }
00211
00212
00213 template <class T, int N>
00214 void Set(const ParamXMLPath& path, const T (&val)[N])
00215 {
00216 String str;
00217 for(int i = 0; i < N; i++){
00218 if(i != 0) str += ",";
00219 str += ToString(path, val[i]);
00220 }
00221 Set( path, str );
00222 }
00223
00224
00225 template <class T>
00226 void Set(const ParamXMLPath& path, const std::vector<T>& val )
00227 {
00228 String str;
00229 for(size_t i = 0; i < val.size(); i++){
00230 if(i != 0) str += ",";
00231 str += ToString(path, val[i]);
00232 }
00233 Set( path, str );
00234 }
00235
00236
00237 template <class T>
00238 void Set( const ParamXMLPath& path, const T& param, const Binding<T>* bindings, int bindingsSize )
00239 {
00240 String str;
00241 for( int i = 0; i < bindingsSize; i++ ){
00242 if( param == bindings[i].value ){
00243 str = bindings[i].str;
00244 }
00245 }
00246 Set( path, str );
00247 }
00248
00249
00250
00251
00252
00253
00254 bool Get(const ParamXMLPath& path, String* val, bool required = true);
00255
00256
00257 template <class T>
00258 bool Get(const ParamXMLPath& path, T* val, bool required = true)
00259 {
00260 String str;
00261 if( Get( path, &str, required ) ){
00262 ToParam( val, path, str );
00263 return true;
00264 }
00265 else{
00266 return false;
00267 }
00268 }
00269
00270
00271 template < class T, int N >
00272 bool Get(const ParamXMLPath& path, T (*val)[N], bool required = true)
00273 {
00274 String str;
00275 if( Get(path, &str, required) ){
00276 std::vector<String> valStrList = str.split(", \n\t");
00277 for(size_t i = 0; i < valStrList.size(); i++){
00278 if(i >= N){
00279 THROW_RUNTIME_ERROR(
00280 "ParamDB parameter conversion failed.\n"
00281 "'%s' is out of range.",
00282 path.ToString().c_str()
00283 );
00284 }
00285 ToParam<T>( &val[i], path, valStrList[i] );
00286 }
00287 return true;
00288 }
00289 else{
00290 return false;
00291 }
00292 }
00293
00294
00295 template <class T>
00296 bool Get(const ParamXMLPath& path, std::vector<T>* val, bool required = true)
00297 {
00298 String str;
00299 if( Get( path, &str, required ) ){
00300 std::vector<String> valList = str.split(", \n\t");
00301 val->resize( valList.size() );
00302 for(size_t i = 0; i < valList.size(); i++){
00303 ToParam( &(*val)[i], path, valList[i] );
00304 }
00305 return true;
00306 }
00307 else{
00308 return false;
00309 }
00310 }
00311
00312
00313 template <class T>
00314 bool Get(const ParamXMLPath& path, T* val, const Binding<T>* bindings, int bindingsSize, bool required = true)
00315 {
00316 String str;
00317 if( Get(path, &str, required) ){
00318 bool converted = false;
00319 for( int i = 0; i < bindingsSize; i++ ){
00320 if( str == bindings[i].str ){
00321 *val = bindings[i].value;
00322 converted = true;
00323 }
00324 }
00325 if( !converted ){
00326 String msg = "[";
00327 for( int i = 0; i < bindingsSize; i++ ){
00328 msg += bindings[i].str;
00329 if( i < bindingsSize - 1 ){
00330 msg += ", ";
00331 }
00332 }
00333 msg += "]";
00334
00335 THROW_RUNTIME_ERROR(
00336 "'%s' is not a valid parameter. '%s' must be one of the following strings: %s",
00337 str.c_str(),
00338 path.ToString().c_str(),
00339 msg.c_str()
00340 );
00341 }
00342 return true;
00343 }
00344 else{
00345 return false;
00346 }
00347 }
00348
00349 };
00350
00351
00352
00353 extern ParamDB g_paramDB;
00354
00355 }
00356
00357 #endif // ENV_PARAM_PARAM_DB_H
00358
00359