| //===-- MICmnLog.cpp --------------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| //++ |
| // File: MICmnLog.cpp |
| // |
| // Overview: CMICmnLog implementation. |
| // |
| // Environment: Compilers: Visual C++ 12. |
| // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 |
| // Libraries: See MIReadmetxt. |
| // |
| // Copyright: None. |
| //-- |
| |
| // In-house headers: |
| #include "MICmnConfig.h" |
| #include "MICmnLog.h" |
| #include "MICmnLogMediumFile.h" |
| #include "MIDriverMgr.h" |
| #include "MICmnResources.h" |
| #include "MIUtilDateTimeStd.h" |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmnLog constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmnLog::CMICmnLog( void ) |
| : m_bEnabled( false ) |
| , m_bInitializingATM( false ) |
| { |
| // Do not use this constructor, use Initialize() |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmnLog destructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmnLog::~CMICmnLog( void ) |
| { |
| Shutdown(); |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Initialize resources for *this Logger. |
| // Type: Method. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLog::Initialize( void ) |
| { |
| m_clientUsageRefCnt++; |
| |
| if( m_bInitialized ) |
| return MIstatus::success; |
| |
| ClrErrorDescription(); |
| |
| // Mediums set inside because explicitly initing in MIDriverMain.cpp causes compile errors with CAtlFile |
| CMICmnLogMediumFile & rFileLog( CMICmnLogMediumFile::Instance() ); |
| bool bOk = RegisterMedium( rFileLog ); |
| bOk = bOk && SetEnabled( true ); |
| if( bOk ) |
| { |
| // Set the Log trace file's header |
| const CMIUtilString & rCR( rFileLog.GetLineReturn() ); |
| CMIUtilDateTimeStd date; |
| CMIUtilString msg; |
| msg = CMIUtilString::Format( "%s\n", CMIDriverMgr::Instance().GetAppVersion().c_str() ); |
| CMIUtilString logHdr( msg ); |
| msg = CMIUtilString::Format( MIRSRC( IDS_LOG_MSG_CREATION_DATE ), date.GetDate().c_str(), date.GetTime().c_str(), rCR.c_str() ); |
| logHdr += msg; |
| msg = CMIUtilString::Format( MIRSRC( IDS_LOG_MSG_FILE_LOGGER_PATH ), rFileLog.GetFileNamePath().c_str(), rCR.c_str() ); |
| logHdr += msg; |
| |
| bOk = rFileLog.SetHeaderTxt( logHdr ); |
| |
| // Note log file medium's status is not available until we write at least once to the file (so just write the title 1st line) |
| m_bInitializingATM = true; |
| CMICmnLog::WriteLog( "." ); |
| if( !rFileLog.IsOk() ) |
| { |
| const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_LOG_ERR_FILE_LOGGER_DISABLED ), rFileLog.GetErrorDescription().c_str() ) ); |
| CMICmnLog::WriteLog( msg ); |
| } |
| m_bInitializingATM = false; |
| } |
| |
| m_bInitialized = bOk; |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Release resources for *this Logger. |
| // Type: Method. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLog::Shutdown( void ) |
| { |
| if( --m_clientUsageRefCnt > 0 ) |
| return MIstatus::success; |
| |
| if( !m_bInitialized ) |
| return MIstatus::success; |
| |
| ClrErrorDescription(); |
| |
| const bool bOk = UnregisterMediumAll(); |
| |
| m_bInitialized = bOk; |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Enabled or disable *this Logger from writing any data to registered clients. |
| // Type: Method. |
| // Args: vbYes - (R) True = Logger enabled, false = disabled. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLog::SetEnabled( const bool vbYes ) |
| { |
| m_bEnabled = vbYes; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Retrieve state whether *this Logger is enabled writing data to registered clients. |
| // Type: Method. |
| // Args: None. |
| // Return: True = Logger enable. |
| // False = disabled. |
| // Throws: None. |
| //-- |
| bool CMICmnLog::GetEnabled( void ) const |
| { |
| return m_bEnabled; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Unregister all the Mediums registered with *this Logger. |
| // Type: Method. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLog::UnregisterMediumAll( void ) |
| { |
| MapMediumToName_t::const_iterator it = m_mapMediumToName.begin(); |
| for( ; it != m_mapMediumToName.end( ); it++ ) |
| { |
| IMedium * pMedium = (*it).first; |
| pMedium->Shutdown(); |
| } |
| |
| m_mapMediumToName.clear(); |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Register a Medium with *this Logger. |
| // Type: Method. |
| // Args: vrMedium - (R) The medium to register. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLog::RegisterMedium( const IMedium & vrMedium ) |
| { |
| if( HaveMediumAlready( vrMedium ) ) |
| return MIstatus::success; |
| |
| IMedium * pMedium = const_cast< IMedium * >( &vrMedium ); |
| if( !pMedium->Initialize() ) |
| { |
| const CMIUtilString & rStrMedName( pMedium->GetName() ); |
| const CMIUtilString & rStrMedErr( pMedium->GetError() ); |
| SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LOG_MEDIUM_ERR_INIT ), rStrMedName.c_str(), rStrMedErr.c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| MapPairMediumToName_t pr( pMedium, pMedium->GetName() ); |
| m_mapMediumToName.insert( pr ); |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Query the Logger to see if a medium is already registered. |
| // Type: Method. |
| // Args: vrMedium - (R) The medium to query. |
| // Return: True - registered. |
| // False - not registered. |
| // Throws: None. |
| //-- |
| bool CMICmnLog::HaveMediumAlready( const IMedium & vrMedium ) const |
| { |
| IMedium * pMedium = const_cast< IMedium * >( &vrMedium ); |
| const MapMediumToName_t::const_iterator it = m_mapMediumToName.find( pMedium ); |
| if( it != m_mapMediumToName.end() ) |
| return true; |
| |
| return false; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Unregister a medium from the Logger. |
| // Type: Method. |
| // Args: vrMedium - (R) The medium to unregister. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLog::UnregisterMedium( const IMedium & vrMedium ) |
| { |
| IMedium * pMedium = const_cast< IMedium * >( &vrMedium ); |
| m_mapMediumToName.erase( pMedium ); |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The callee client uses this function to write to the Logger. The data to be |
| // written is given out to all the mediums registered. The verbosity type parameter |
| // indicates to the medium(s) the type of data or message given to it. The medium has |
| // modes of verbosity and depending on the verbosity set determines which writes |
| // go in to the logger. |
| // The logger must be initialized successfully before a write to any registered |
| // can be carried out. |
| // Type: Method. |
| // Args: vData - (R) The data to write to the logger. |
| // veType - (R) Verbosity type. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLog::Write( const CMIUtilString & vData, const ELogVerbosity veType ) |
| { |
| if( !m_bInitialized && !m_bInitializingATM ) |
| return MIstatus::success; |
| if( m_bRecursiveDive ) |
| return MIstatus::success; |
| if( !m_bEnabled ) |
| return MIstatus::success; |
| |
| m_bRecursiveDive = true; |
| |
| MIuint cnt = 0; |
| MIuint cntErr = 0; |
| { |
| MapMediumToName_t::const_iterator it = m_mapMediumToName.begin(); |
| while( it != m_mapMediumToName.end() ) |
| { |
| IMedium * pMedium = (*it).first; |
| const CMIUtilString & rNameMedium = (*it).second; MIunused( rNameMedium ); |
| if( pMedium->Write( vData, veType ) ) |
| cnt++; |
| else |
| cntErr++; |
| |
| // Next |
| ++it; |
| } |
| } |
| |
| bool bOk = MIstatus::success; |
| const MIuint mediumCnt = m_mapMediumToName.size(); |
| if( (cnt == 0) && (mediumCnt > 0) ) |
| { |
| SetErrorDescription( MIRSRC( IDS_LOG_MEDIUM_ERR_WRITE_ANY ) ); |
| bOk = MIstatus::failure; |
| } |
| if( bOk && (cntErr != 0) ) |
| { |
| SetErrorDescription( MIRSRC( IDS_LOG_MEDIUM_ERR_WRITE_MEDIUMFAIL ) ); |
| bOk = MIstatus::failure; |
| } |
| |
| m_bRecursiveDive = false; |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Short cut function call to write only to the Log file. |
| // The logger must be initialized successfully before a write to any registered |
| // can be carried out. |
| // Type: Static. |
| // Args: vData - (R) The data to write to the logger. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLog::WriteLog( const CMIUtilString & vData ) |
| { |
| return CMICmnLog::Instance().Write( vData, CMICmnLog::eLogVerbosity_Log ); |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Retrieve a string detailing the last error. |
| // Type: Method. |
| // Args: None, |
| // Return: CMIUtilString. |
| // Throws: None. |
| //-- |
| const CMIUtilString & CMICmnLog::GetErrorDescription( void ) const |
| { |
| return m_strMILastErrorDescription; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Set the internal description of the last error. |
| // Type: Method. |
| // Args: (R) String containing a description of the last error. |
| // Return: None. |
| // Throws: None. |
| //-- |
| void CMICmnLog::SetErrorDescription( const CMIUtilString & vrTxt ) const |
| { |
| m_strMILastErrorDescription = vrTxt; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Clear the last error. |
| // Type: None. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| void CMICmnLog::ClrErrorDescription( void ) const |
| { |
| m_strMILastErrorDescription = CMIUtilString( "" ); |
| } |