Changeset 945

Show
Ignore:
Timestamp:
05/17/10 17:54:44 (14 years ago)
Author:
mido
Message:

patch of UI and log_levels to obtain nicer and mainly compilable source code.)

Location:
library/bdm
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • library/bdm/base/bdmbase.h

    r944 r945  
    406406//! This class stores a details that will be logged to a logger 
    407407template<class T> class log_level_template : public log_level_base<T> { 
    408 public: 
     408protected: 
     409        //! boolean flags related indicating which details will be logged to a logger 
     410        bitset<32> values; 
     411 
     412public: 
     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 
    409466        //! This method stores a vector to the proper place in registered logger  
    410467        //! 
     
    430487        //! 
    431488        //! 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_setting 
    437         //! 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.  
    438489        template<class U> void store( const enum T::log_level_enums log_level_enum, const U data, int enum_subindex = 0 ) const 
    439490        {                        
     
    443494        } 
    444495}; 
     496//UIREGISTER IS FORBIDDEN FOR THIS CLASS,  AS IT SHOULD BE LOADED ONLY THROUGH THE SPECIALIZED UI::GET(...) METHOD 
     497 
    445498 
    446499/*! 
     
    459512  \ref ui 
    460513*/ 
    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; } 
    462515 
    463516 
  • library/bdm/base/user_info.h

    r942 r945  
    229229 
    230230 
    231 //! This class stores the details which will be logged to a logger 
    232 //! 
    233 //! This is only the first part of the whole declaration, which has to be however separated into 
    234 //! two different classes for allowing the compilation of source code. For more details 
    235 //! 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 
    236 //! 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_logger 
    240         friend class logger;  
    241  
    242 protected: 
    243         //! boolean flags related indicating which details will be logged to a logger 
    244         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 enum 
    247         Vec<ivec> ids; 
    248  
    249         //! internal pointer to the logger to which this log_level is registered 
    250         //!  
    251         //! it is set to NULL at the beginning 
    252         logger * registered_logger; 
    253  
    254 public: 
    255  
    256         //! default constructor 
    257         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 element 
    281         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 element 
    300         void to_setting ( Setting &element ) const  
    301         { 
    302                 // HERE WE WANT NOT TO DELETE PREVIOUS DATA STORED BY OTHER LOG_LEVELS, SEE SPECIAL IMPLEMENTATION OF UI::GET(...) FOR THIS CLASS 
    303                 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 position 
    317         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                 else  
    329                         stream << name_with_prefix; 
    330  
    331                 // add number to name only in the case there are more registered vectors with the same log_level_enum 
    332                 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 T 
    339         const Array<string> &names() const 
    340         { 
    341                 return T::log_level_names(); 
    342         } 
    343  
    344         //! read only operator for testing individual fields of log_level 
    345         //! 
    346         //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe 
    347         bool operator [] (const enum T::log_level_enums &log_level_enum ) const 
    348         { 
    349                 return values[log_level_enum]; 
    350         } 
    351  
    352         //! operator for setting an individual field of log_level  
    353         //! 
    354         //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe 
    355         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(...) METHOD 
    361231 
    362232/*! 
  • library/bdm/bdmroot.h

    r942 r945  
    194194}; 
    195195 
     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.  
     202template<class T> class log_level_base : public root { 
     203private: 
     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 
     230protected: 
     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         
     257public:  
     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 
    196270}; //namespace 
    197271#endif // root_H