1 //===-- MICmnLog.cpp --------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 #include "MICmnLogMediumFile.h"
12 #include "MICmnResources.h"
13 #include "MIDriverMgr.h"
14 #include "MIUtilDateTimeStd.h"
17 // Details: CMICmnLog constructor.
23 CMICmnLog::CMICmnLog() : m_bEnabled(false), m_bInitializingATM(false) {
24 // Do not use this constructor, use Initialize()
28 // Details: CMICmnLog destructor.
34 CMICmnLog::~CMICmnLog() { Shutdown(); }
37 // Details: Initialize resources for *this Logger.
40 // Return: MIstatus::success - Functional succeeded.
41 // MIstatus::failure - Functional failed.
44 bool CMICmnLog::Initialize() {
45 m_clientUsageRefCnt++;
48 return MIstatus::success;
50 ClrErrorDescription();
52 // Mediums set inside because explicitly initing in MIDriverMain.cpp causes
53 // compile errors with CAtlFile
54 CMICmnLogMediumFile &rFileLog(CMICmnLogMediumFile::Instance());
55 bool bOk = RegisterMedium(rFileLog);
57 // Set the Log trace file's header
58 const CMIUtilString &rCR(rFileLog.GetLineReturn());
59 CMIUtilDateTimeStd date;
61 msg = CMIUtilString::Format(
62 "%s\n", CMIDriverMgr::Instance().GetAppVersion().c_str());
63 CMIUtilString logHdr(msg);
64 msg = CMIUtilString::Format(MIRSRC(IDS_LOG_MSG_CREATION_DATE),
65 date.GetDate().c_str(), date.GetTime().c_str(),
69 CMIUtilString::Format(MIRSRC(IDS_LOG_MSG_FILE_LOGGER_PATH),
70 rFileLog.GetFileNamePath().c_str(), rCR.c_str());
73 bOk = rFileLog.SetHeaderTxt(logHdr);
75 // Note log file medium's status is not available until we write at least
76 // once to the file (so just write the title 1st line)
77 m_bInitializingATM = true;
78 CMICmnLog::WriteLog(".");
79 if (!rFileLog.IsOk()) {
80 const CMIUtilString msg(
81 CMIUtilString::Format(MIRSRC(IDS_LOG_ERR_FILE_LOGGER_DISABLED),
82 rFileLog.GetErrorDescription().c_str()));
83 CMICmnLog::WriteLog(msg);
85 m_bInitializingATM = false;
94 // Details: Release resources for *this Logger.
97 // Return: MIstatus::success - Functional succeeded.
98 // MIstatus::failure - Functional failed.
101 bool CMICmnLog::Shutdown() {
102 if (--m_clientUsageRefCnt > 0)
103 return MIstatus::success;
106 return MIstatus::success;
108 ClrErrorDescription();
110 const bool bOk = UnregisterMediumAll();
112 m_bInitialized = bOk;
118 // Details: Enabled or disable *this Logger from writing any data to registered
121 // Args: vbYes - (R) True = Logger enabled, false = disabled.
122 // Return: MIstatus::success - Functional succeeded.
123 // MIstatus::failure - Functional failed.
126 bool CMICmnLog::SetEnabled(const bool vbYes) {
129 return MIstatus::success;
133 // Details: Retrieve state whether *this Logger is enabled writing data to
134 // registered clients.
137 // Return: True = Logger enable.
141 bool CMICmnLog::GetEnabled() const { return m_bEnabled; }
144 // Details: Unregister all the Mediums registered with *this Logger.
147 // Return: MIstatus::success - Functional succeeded.
148 // MIstatus::failure - Functional failed.
151 bool CMICmnLog::UnregisterMediumAll() {
152 MapMediumToName_t::const_iterator it = m_mapMediumToName.begin();
153 for (; it != m_mapMediumToName.end(); it++) {
154 IMedium *pMedium = (*it).first;
158 m_mapMediumToName.clear();
160 return MIstatus::success;
164 // Details: Register a Medium with *this Logger.
166 // Args: vrMedium - (R) The medium to register.
167 // Return: MIstatus::success - Functional succeeded.
168 // MIstatus::failure - Functional failed.
171 bool CMICmnLog::RegisterMedium(const IMedium &vrMedium) {
172 if (HaveMediumAlready(vrMedium))
173 return MIstatus::success;
175 IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
176 if (!pMedium->Initialize()) {
177 const CMIUtilString &rStrMedName(pMedium->GetName());
178 const CMIUtilString &rStrMedErr(pMedium->GetError());
179 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_LOG_MEDIUM_ERR_INIT),
181 rStrMedErr.c_str()));
182 return MIstatus::failure;
185 MapPairMediumToName_t pr(pMedium, pMedium->GetName());
186 m_mapMediumToName.insert(pr);
188 return MIstatus::success;
192 // Details: Query the Logger to see if a medium is already registered.
194 // Args: vrMedium - (R) The medium to query.
195 // Return: True - registered.
196 // False - not registered.
199 bool CMICmnLog::HaveMediumAlready(const IMedium &vrMedium) const {
200 IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
201 const MapMediumToName_t::const_iterator it = m_mapMediumToName.find(pMedium);
202 return it != m_mapMediumToName.end();
206 // Details: Unregister a medium from the Logger.
208 // Args: vrMedium - (R) The medium to unregister.
209 // Return: MIstatus::success - Functional succeeded.
210 // MIstatus::failure - Functional failed.
213 bool CMICmnLog::UnregisterMedium(const IMedium &vrMedium) {
214 IMedium *pMedium = const_cast<IMedium *>(&vrMedium);
215 m_mapMediumToName.erase(pMedium);
217 return MIstatus::success;
221 // Details: The callee client uses this function to write to the Logger. The
223 // written is given out to all the mediums registered. The verbosity
225 // indicates to the medium(s) the type of data or message given to it.
227 // modes of verbosity and depending on the verbosity set determines
229 // go in to the logger.
230 // The logger must be initialized successfully before a write to any
232 // can be carried out.
234 // Args: vData - (R) The data to write to the logger.
235 // veType - (R) Verbosity type.
236 // Return: MIstatus::success - Functional succeeded.
237 // MIstatus::failure - Functional failed.
240 bool CMICmnLog::Write(const CMIUtilString &vData, const ELogVerbosity veType) {
241 if (!m_bInitialized && !m_bInitializingATM)
242 return MIstatus::success;
243 if (m_bRecursiveDive)
244 return MIstatus::success;
246 return MIstatus::success;
248 m_bRecursiveDive = true;
253 MapMediumToName_t::const_iterator it = m_mapMediumToName.begin();
254 while (it != m_mapMediumToName.end()) {
255 IMedium *pMedium = (*it).first;
256 const CMIUtilString &rNameMedium = (*it).second;
257 MIunused(rNameMedium);
258 if (pMedium->Write(vData, veType))
268 bool bOk = MIstatus::success;
269 const MIuint mediumCnt = m_mapMediumToName.size();
270 if ((cnt == 0) && (mediumCnt > 0)) {
271 SetErrorDescription(MIRSRC(IDS_LOG_MEDIUM_ERR_WRITE_ANY));
272 bOk = MIstatus::failure;
274 if (bOk && (cntErr != 0)) {
275 SetErrorDescription(MIRSRC(IDS_LOG_MEDIUM_ERR_WRITE_MEDIUMFAIL));
276 bOk = MIstatus::failure;
279 m_bRecursiveDive = false;
285 // Details: Short cut function call to write only to the Log file.
286 // The logger must be initialized successfully before a write to any
288 // can be carried out.
290 // Args: vData - (R) The data to write to the logger.
291 // Return: MIstatus::success - Functional succeeded.
292 // MIstatus::failure - Functional failed.
295 bool CMICmnLog::WriteLog(const CMIUtilString &vData) {
296 return CMICmnLog::Instance().Write(vData, CMICmnLog::eLogVerbosity_Log);
300 // Details: Retrieve a string detailing the last error.
303 // Return: CMIUtilString.
306 const CMIUtilString &CMICmnLog::GetErrorDescription() const {
307 return m_strMILastErrorDescription;
311 // Details: Set the internal description of the last error.
313 // Args: (R) String containing a description of the last error.
317 void CMICmnLog::SetErrorDescription(const CMIUtilString &vrTxt) const {
318 m_strMILastErrorDescription = vrTxt;
322 // Details: Clear the last error.
328 void CMICmnLog::ClrErrorDescription() const {
329 m_strMILastErrorDescription = CMIUtilString("");