| //===-- MICmnLog.cpp --------------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| // In-house headers: |
| #include "MICmnLog.h" |
| #include "MICmnLogMediumFile.h" |
| #include "MICmnResources.h" |
| #include "MIDriverMgr.h" |
| #include "MIUtilDateTimeStd.h" |
| |
| //++ |
| //------------------------------------------------------------------------------------ |
| // Details: CMICmnLog constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmnLog::CMICmnLog() : 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() { 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() { |
| 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); |
| 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() { |
| 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() 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() { |
| 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() 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() const { |
| m_strMILastErrorDescription = CMIUtilString(""); |
| } |