1 //===-- MICmnLogMediumFile.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 //===----------------------------------------------------------------------===//
10 #include "MICmnLogMediumFile.h"
11 #include "MICmnResources.h"
14 // Details: CMICmnLogMediumFile constructor.
20 CMICmnLogMediumFile::CMICmnLogMediumFile()
21 : m_constThisMediumName(MIRSRC(IDS_MEDIUMFILE_NAME)),
22 m_constMediumFileNameFormat("lldb-mi-%s.log"),
23 m_strMediumFileName(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)),
24 m_strMediumFileDirectory("."),
25 m_fileNamePath(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)),
26 m_eVerbosityType(CMICmnLog::eLogVerbosity_Log),
27 m_strDate(CMIUtilDateTimeStd().GetDate()),
28 m_fileHeaderTxt(MIRSRC(IDS_MEDIUMFILE_ERR_FILE_HEADER)) {}
31 // Details: CMICmnLogMediumFile destructor.
37 CMICmnLogMediumFile::~CMICmnLogMediumFile() {}
40 // Details: Get the singleton instance of *this class.
43 // Return: CMICmnLogMediumFile - Reference to *this object.
46 CMICmnLogMediumFile &CMICmnLogMediumFile::Instance() {
47 static CMICmnLogMediumFile instance;
53 // Details: Initialize setup *this medium ready for use.
56 // Return: MIstatus::success - Functional succeeded.
57 // MIstatus::failure - Functional failed.
60 bool CMICmnLogMediumFile::Initialize() {
61 m_bInitialized = true;
62 return FileFormFileNamePath();
66 // Details: Unbind detach or release resources used by *this medium.
72 bool CMICmnLogMediumFile::Shutdown() {
74 m_bInitialized = false;
77 return MIstatus::success;
81 // Details: Retrieve the name of *this medium.
84 // Return: CMIUtilString - Text data.
87 const CMIUtilString &CMICmnLogMediumFile::GetName() const {
88 return m_constThisMediumName;
92 // Details: The callee client calls the write function on the Logger. The data
94 // written is given out to all the mediums registered. The verbosity
96 // indicates to the medium the type of data or message given to it. The
98 // modes of verbosity and depending on the verbosity set determines
100 // sent to the medium's output.
102 // Args: vData - (R) The data to write to the logger.
103 // veType - (R) Verbosity type.
104 // Return: MIstatus::success - Functional succeeded.
105 // MIstatus::failure - Functional failed.
108 bool CMICmnLogMediumFile::Write(const CMIUtilString &vData,
109 const CMICmnLog::ELogVerbosity veType) {
110 if (m_bInitialized && m_file.IsOk()) {
111 const bool bDoWrite = (m_eVerbosityType & veType);
113 bool bNewCreated = false;
114 bool bOk = m_file.CreateWrite(m_fileNamePath, bNewCreated);
117 bOk = FileWriteHeader();
118 bOk = bOk && FileWriteEnglish(MassagedData(vData, veType));
124 return MIstatus::failure;
128 // Details: Retrieve *this medium's last error condition.
131 // Return: CString & - Text description.
134 const CMIUtilString &CMICmnLogMediumFile::GetError() const {
135 return m_strMILastErrorDescription;
139 // Details: Set the verbosity mode for this medium.
141 // Args: veType - (R) Mask value.
142 // Return: MIstatus::success - Functional succeeded.
143 // MIstatus::failure - Functional failed.
146 bool CMICmnLogMediumFile::SetVerbosity(const MIuint veType) {
147 m_eVerbosityType = veType;
148 return MIstatus::success;
152 // Details: Get the verbosity mode for this medium.
154 // Args: veType - (R) Mask value.
155 // Return: CMICmnLog::ELogVerbosity - Mask value.
158 MIuint CMICmnLogMediumFile::GetVerbosity() const { return m_eVerbosityType; }
161 // Details: Write data to a file English font.
163 // Args: vData - (R) The data to write to the logger.
167 bool CMICmnLogMediumFile::FileWriteEnglish(const CMIUtilString &vData) {
168 return m_file.Write(vData);
172 // Details: Determine and form the medium file's directory path and name.
175 // Return: MIstatus::success - Functional succeeded.
176 // MIstatus::failure - Functional failed.
179 bool CMICmnLogMediumFile::FileFormFileNamePath() {
180 ClrErrorDescription();
182 m_fileNamePath = MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH);
184 CMIUtilDateTimeStd date;
185 m_strMediumFileName =
186 CMIUtilString::Format(m_constMediumFileNameFormat.c_str(),
187 date.GetDateTimeLogFilename().c_str());
189 #if defined(_MSC_VER)
190 m_fileNamePath = CMIUtilString::Format(
191 "%s\\%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str());
193 m_fileNamePath = CMIUtilString::Format(
194 "%s/%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str());
195 #endif // defined ( _MSC_VER )
197 return MIstatus::success;
201 // Details: Retrieve the medium file's directory path and name.
204 // Return: CMIUtilString & - File path.
207 const CMIUtilString &CMICmnLogMediumFile::GetFileNamePath() const {
208 return m_fileNamePath;
212 // Details: Retrieve the medium file's name.
215 // Return: CMIUtilString & - File name.
218 const CMIUtilString &CMICmnLogMediumFile::GetFileName() const {
219 return m_strMediumFileName;
223 // Details: Massage the data to behave correct when submitted to file. Insert
225 // specific text. The veType is there to allow in the future to parse
227 // filter in out specific types of message to make viewing the log more
230 // Args: vData - (R) Raw data.
231 // veType - (R) Message type.
232 // Return: CMIUtilString - Massaged data.
236 CMICmnLogMediumFile::MassagedData(const CMIUtilString &vData,
237 const CMICmnLog::ELogVerbosity veType) {
238 const CMIUtilString strCr("\n");
240 const char verbosityCode(ConvertLogVerbosityTypeToId(veType));
241 const CMIUtilString dt(CMIUtilString::Format("%s %s", m_strDate.c_str(),
242 m_dateTime.GetTime().c_str()));
244 data = CMIUtilString::Format("%c,%s,%s", verbosityCode, dt.c_str(),
246 data = ConvertCr(data);
249 const size_t pos = vData.rfind(strCr);
250 if (pos == vData.size())
253 // ... did not have an EOL so add one
254 data += GetLineReturn();
260 // Details: Convert the Log's verbosity type number into a single char
263 // Args: veType - (R) Message type.
264 // Return: wchar_t - A letter.
267 char CMICmnLogMediumFile::ConvertLogVerbosityTypeToId(
268 const CMICmnLog::ELogVerbosity veType) const {
272 MIuint number(veType);
273 while (1 != number) {
274 number = number >> 1;
286 // Details: Retrieve state of whether the file medium is ok.
289 // Return: True - file ok.
290 // False - file has a problem.
293 bool CMICmnLogMediumFile::IsOk() const { return m_file.IsOk(); }
296 // Details: Status on the file log medium existing already.
299 // Return: True - Exists.
300 // False - Not found.
303 bool CMICmnLogMediumFile::IsFileExist() const {
304 return m_file.IsFileExist(GetFileNamePath());
308 // Details: Write the header text the logger file.
310 // Args: vText - (R) Text.
311 // Return: MIstatus::success - Functional succeeded.
312 // MIstatus::failure - Functional failed.
315 bool CMICmnLogMediumFile::FileWriteHeader() {
316 return FileWriteEnglish(ConvertCr(m_fileHeaderTxt));
320 // Details: Convert any carriage line returns to be compatible with the platform
322 // Log file is being written to.
324 // Args: vData - (R) Text data.
325 // Return: CMIUtilString - Converted string data.
328 CMIUtilString CMICmnLogMediumFile::ConvertCr(const CMIUtilString &vData) const {
329 const CMIUtilString strCr("\n");
330 const CMIUtilString &rCrCmpat(GetLineReturn());
332 if (strCr == rCrCmpat)
335 const size_t nSizeCmpat(rCrCmpat.size());
336 const size_t nSize(strCr.size());
337 CMIUtilString strConv(vData);
338 size_t pos = strConv.find(strCr);
339 while (pos != CMIUtilString::npos) {
340 strConv.replace(pos, nSize, rCrCmpat);
341 pos = strConv.find(strCr, pos + nSizeCmpat);
348 // Details: Set the header text that is written to the logger file at the
351 // Args: vText - (R) Text.
352 // Return: MIstatus::success - Functional succeeded.
353 // MIstatus::failure - Functional failed.
356 bool CMICmnLogMediumFile::SetHeaderTxt(const CMIUtilString &vText) {
357 m_fileHeaderTxt = vText;
359 return MIstatus::success;
363 // Details: Retrieve the file current carriage line return characters used.
366 // Return: CMIUtilString & - Text.
369 const CMIUtilString &CMICmnLogMediumFile::GetLineReturn() const {
370 return m_file.GetLineReturn();
374 // Details: Set the directory to place the log file.
376 // Args: vPath - (R) Path to log.
377 // Return: MIstatus::success - Functional succeeded.
378 // MIstatus::failure - Functional failed.
381 bool CMICmnLogMediumFile::SetDirectory(const CMIUtilString &vPath) {
382 m_strMediumFileDirectory = vPath;
384 return FileFormFileNamePath();