Changeset 945
- Timestamp:
- 05/17/10 17:54:44 (15 years ago)
- Location:
- library/bdm
- Files:
-
- 3 modified
Legend:
- Unmodified
- Added
- Removed
-
library/bdm/base/bdmbase.h
r944 r945 406 406 //! This class stores a details that will be logged to a logger 407 407 template<class T> class log_level_template : public log_level_base<T> { 408 public: 408 protected: 409 //! boolean flags related indicating which details will be logged to a logger 410 bitset<32> values; 411 412 public: 413 414 //! read only operator for testing individual fields of log_level 415 //! 416 //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe 417 bool operator [] (const enum T::log_level_enums &log_level_enum ) const 418 { 419 return values[log_level_enum]; 420 } 421 422 //! operator for setting an individual field of log_level 423 //! 424 //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe 425 bitset<32>::reference operator [] (const enum T::log_level_enums &log_level_enum ) 426 { 427 return values[log_level_enum]; 428 } 429 430 //! Set log_levels according to the Setting element 431 void from_setting ( const Setting &element ) 432 { 433 string raw_log_level; 434 UI::get( raw_log_level, element ); 435 Array<string> loaded_log_level = string2Array( raw_log_level ); 436 437 values.reset(); 438 439 for( int i = 0; i < loaded_log_level.length(); i++ ) 440 for( int j = 0; j < names().length(); j++ ){ 441 if( loaded_log_level(i) == names()(j) ) 442 { 443 values[j] = true; 444 break; 445 } 446 } 447 } 448 449 //! Store log_levels into the Setting element 450 void to_setting ( Setting &element ) const 451 { 452 // HERE WE WANT NOT TO DELETE PREVIOUS DATA STORED BY OTHER LOG_LEVELS, SEE SPECIAL IMPLEMENTATION OF UI::GET(...) FOR THIS CLASS 453 string string_to_write = ( const char* ) element; 454 455 for( unsigned int i = 0; i < values.size(); i++ ) 456 if( values[i] ) 457 { 458 if( string_to_write.length() > 0 ) 459 string_to_write = string_to_write + ','; 460 string_to_write = string_to_write + names()(i); 461 } 462 463 element = string_to_write; 464 } 465 409 466 //! This method stores a vector to the proper place in registered logger 410 467 //! … … 430 487 //! 431 488 //! parameter \c enum_subindex identifies the precise position of setting in the case there is more settings registered to with this enum 432 //!433 //! If this method was not templated, we could store whole body of this class in cpp file without explicitly touching registered_logger->log_setting(...) here.434 //! (it would not be straightforward, though, still there are some enums which had to be converted into integers but it could be done without loosing type control)435 //! This way, it would not be necessary to declare log_level_base<T> class and we could declare log_level_template<T>436 //! before the logger class itself with a mere foroward declaration of logger. In our case, however, touching of registered_logger->log_setting437 //! implies that forward declaration is not enough and we are lost in a circle. And just by cutting this circle we obtains log_level_base<T> class.438 489 template<class U> void store( const enum T::log_level_enums log_level_enum, const U data, int enum_subindex = 0 ) const 439 490 { … … 443 494 } 444 495 }; 496 //UIREGISTER IS FORBIDDEN FOR THIS CLASS, AS IT SHOULD BE LOADED ONLY THROUGH THE SPECIALIZED UI::GET(...) METHOD 497 445 498 446 499 /*! … … 459 512 \ref ui 460 513 */ 461 #define LOG_LEVEL(classname,...) public: enum log_level_enums { __VA_ARGS__ }; log_level_template<classname> log_level; private: friend class log_level_ template<classname>; friend class log_level_base<classname>; static const Array<string> &log_level_names() { static const Array<string> log_level_names = log_level_base<classname>::string2Array( #__VA_ARGS__ ); return log_level_names; }514 #define LOG_LEVEL(classname,...) public: enum log_level_enums { __VA_ARGS__ }; log_level_template<classname> log_level; private: friend class log_level_base<classname>; static const Array<string> &log_level_names() { static const Array<string> log_level_names = log_level_template<classname>::string2Array( #__VA_ARGS__ ); return log_level_names; } 462 515 463 516 -
library/bdm/base/user_info.h
r942 r945 229 229 230 230 231 //! This class stores the details which will be logged to a logger232 //!233 //! This is only the first part of the whole declaration, which has to be however separated into234 //! two different classes for allowing the compilation of source code. For more details235 //! see logger::add_setting(...) method and mainly log_level_template<T>::template<class U> void store( const enum T::log_level_enums log_level_enum, const U data ) const236 //! method. For the reason the second one is templated, it was necessary to declare this whole class.237 template<class T> class log_level_base : public root {238 private:239 //! this is necessary to allow logger to set ids vector appropriately and also to set registered_logger240 friend class logger;241 242 protected:243 //! boolean flags related indicating which details will be logged to a logger244 bitset<32> values;245 246 //! vector of vectors of log IDs - one element for each entry and multiple entries can be stored on the position of one enum247 Vec<ivec> ids;248 249 //! internal pointer to the logger to which this log_level is registered250 //!251 //! it is set to NULL at the beginning252 logger * registered_logger;253 254 public:255 256 //! default constructor257 log_level_base( ) {258 registered_logger = NULL;259 int len = names().length();260 ids.set_size( len );261 for( int i = 0; i<len; i++ )262 {263 ids(i).set_size ( 1 );264 ids(i) = -1;265 }266 }267 268 //! a general utility transforming a comma-separated sequence of strings into an instance of Array<strings>269 static Array<string> string2Array( const string &input )270 {271 string result = input;272 string::size_type loc;273 while( loc = result.find( ',' ), loc != string::npos )274 result[loc] = ' ';275 return Array<string>("{ " + result + " }" );276 }277 278 279 280 //! Set log_levels according to the Setting element281 void from_setting ( const Setting &element )282 {283 string raw_log_level;284 UI::get( raw_log_level, element );285 Array<string> loaded_log_level = log_level_base::string2Array( raw_log_level );286 287 values.reset();288 289 for( int i = 0; i < loaded_log_level.length(); i++ )290 for( int j = 0; j < names().length(); j++ ){291 if( loaded_log_level(i) == names()(j) )292 {293 values[j] = true;294 break;295 }296 }297 }298 299 //! Store log_levels into the Setting element300 void to_setting ( Setting &element ) const301 {302 // HERE WE WANT NOT TO DELETE PREVIOUS DATA STORED BY OTHER LOG_LEVELS, SEE SPECIAL IMPLEMENTATION OF UI::GET(...) FOR THIS CLASS303 string string_to_write = ( const char* ) element;304 305 for( unsigned int i = 0; i < values.size(); i++ )306 if( values[i] )307 {308 if( string_to_write.length() > 0 )309 string_to_write = string_to_write + ',';310 string_to_write = string_to_write + names()(i);311 }312 313 element = string_to_write;314 }315 316 //! this method adds new id to its proper position and return the name of this position317 string store_id_and_give_name( enum T::log_level_enums const log_level_enum, int enum_subindex, int id ) {318 if( ids(log_level_enum).length() <= enum_subindex )319 ids(log_level_enum).set_size( enum_subindex+1, true );320 ids(log_level_enum)(enum_subindex) = id;321 322 // here we remove a "log" prefix from name, i.e., for instance it transforms "logevidence" to "evidence"323 ostringstream stream;324 string name_with_prefix = names()(log_level_enum);325 string possible_log_prefix = name_with_prefix.substr(0,3);326 if( possible_log_prefix == "log" )327 stream << name_with_prefix.substr(3,name_with_prefix.length()-3);328 else329 stream << name_with_prefix;330 331 // add number to name only in the case there are more registered vectors with the same log_level_enum332 if( ids(log_level_enum).length() > 1 )333 stream << "*" << enum_subindex;334 335 return stream.str();336 }337 338 //! string equivalents of the used enumerations which are filled with a help of #LOG_LEVEL macro within class T339 const Array<string> &names() const340 {341 return T::log_level_names();342 }343 344 //! read only operator for testing individual fields of log_level345 //!346 //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe347 bool operator [] (const enum T::log_level_enums &log_level_enum ) const348 {349 return values[log_level_enum];350 }351 352 //! operator for setting an individual field of log_level353 //!354 //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe355 bitset<32>::reference operator [] (const enum T::log_level_enums &log_level_enum )356 {357 return values[log_level_enum];358 }359 };360 //UIREGISTER IS FORBIDDEN FOR THIS CLASS, AS IT SHOULD BE LOADED ONLY THROUGH THE SPECIALIZED UI::GET(...) METHOD361 231 362 232 /*! -
library/bdm/bdmroot.h
r942 r945 194 194 }; 195 195 196 //! This class stores the details which will be logged to a logger 197 //! 198 //! This is only the first part of the whole declaration, which has to be however separated into 199 //! two different classes for allowing the compilation of source code. For more details 200 //! see logger::add_setting(...) method and mainly log_level_template<T>::template<class U> void store( const enum T::log_level_enums log_level_enum, const U data ) const 201 //! method. For the reason the second one is templated, it was necessary to declare this whole class. 202 template<class T> class log_level_base : public root { 203 private: 204 //! this is necessary to allow logger to set ids vector appropriately and also to set registered_logger 205 friend class logger; 206 207 208 //! this method adds new id to its proper position and return the name of this position 209 string store_id_and_give_name( enum T::log_level_enums const log_level_enum, int enum_subindex, int id ) { 210 if( ids(log_level_enum).length() <= enum_subindex ) 211 ids(log_level_enum).set_size( enum_subindex+1, true ); 212 ids(log_level_enum)(enum_subindex) = id; 213 214 // here we remove a "log" prefix from name, i.e., for instance it transforms "logevidence" to "evidence" 215 ostringstream stream; 216 string name_with_prefix = names()(log_level_enum); 217 string possible_log_prefix = name_with_prefix.substr(0,3); 218 if( possible_log_prefix == "log" ) 219 stream << name_with_prefix.substr(3,name_with_prefix.length()-3); 220 else 221 stream << name_with_prefix; 222 223 // add number to name only in the case there are more registered vectors with the same log_level_enum 224 if( ids(log_level_enum).length() > 1 ) 225 stream << "*" << enum_subindex; 226 227 return stream.str(); 228 } 229 230 protected: 231 //! internal pointer to the logger to which this log_level is registered 232 //! 233 //! it is set to NULL at the beginning 234 logger * registered_logger; 235 236 //! vector of vectors of log IDs - one element for each entry and multiple entries can be stored on the position of one enum 237 Vec<ivec> ids; 238 239 //! string equivalents of the used enumerations which are filled with a help of #LOG_LEVEL macro within class T 240 const Array<string> &names() const 241 { 242 return T::log_level_names(); 243 } 244 245 //! default constructor�which is intentionaly declared as protected 246 log_level_base( ) { 247 registered_logger = NULL; 248 int len = names().length(); 249 ids.set_size( len ); 250 for( int i = 0; i<len; i++ ) 251 { 252 ids(i).set_size ( 1 ); 253 ids(i) = -1; 254 } 255 } 256 257 public: 258 //! a general utility transforming a comma-separated sequence of strings into an instance of Array<strings> 259 static Array<string> string2Array( const string &input ) 260 { 261 string result = input; 262 string::size_type loc; 263 while( loc = result.find( ',' ), loc != string::npos ) 264 result[loc] = ' '; 265 return Array<string>("{ " + result + " }" ); 266 } 267 }; 268 //UIREGISTER IS FORBIDDEN FOR THIS CLASS, AS IT SHOULD BE LOADED ONLY THROUGH THE SPECIALIZED UI::GET(...) METHOD 269 196 270 }; //namespace 197 271 #endif // root_H