1 //===-- MICmnLogMediumFile.cpp ----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #include "MICmnLogMediumFile.h"
12 #include "MICmnResources.h"
15 //------------------------------------------------------------------------------------
16 // Details: CMICmnLogMediumFile constructor.
22 CMICmnLogMediumFile::CMICmnLogMediumFile()
23 : m_constThisMediumName(MIRSRC(IDS_MEDIUMFILE_NAME)),
24 m_constMediumFileNameFormat("lldb-mi-%s.log"),
25 m_strMediumFileName(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)),
26 m_strMediumFileDirectory("."),
27 m_fileNamePath(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)),
28 m_eVerbosityType(CMICmnLog::eLogVerbosity_Log),
29 m_strDate(CMIUtilDateTimeStd().GetDate()),
30 m_fileHeaderTxt(MIRSRC(IDS_MEDIUMFILE_ERR_FILE_HEADER)) {}
33 //------------------------------------------------------------------------------------
34 // Details: CMICmnLogMediumFile destructor.
40 CMICmnLogMediumFile::~CMICmnLogMediumFile() {}
43 //------------------------------------------------------------------------------------
44 // Details: Get the singleton instance of *this class.
47 // Return: CMICmnLogMediumFile - Reference to *this object.
50 CMICmnLogMediumFile &CMICmnLogMediumFile::Instance() {
51 static CMICmnLogMediumFile instance;
57 //------------------------------------------------------------------------------------
58 // Details: Initialize setup *this medium ready for use.
61 // Return: MIstatus::success - Functional succeeded.
62 // MIstatus::failure - Functional failed.
65 bool CMICmnLogMediumFile::Initialize() {
66 m_bInitialized = true;
67 return FileFormFileNamePath();
71 //------------------------------------------------------------------------------------
72 // Details: Unbind detach or release resources used by *this medium.
78 bool CMICmnLogMediumFile::Shutdown() {
80 m_bInitialized = false;
83 return MIstatus::success;
87 //------------------------------------------------------------------------------------
88 // Details: Retrieve the name of *this medium.
91 // Return: CMIUtilString - Text data.
94 const CMIUtilString &CMICmnLogMediumFile::GetName() const {
95 return m_constThisMediumName;
99 //------------------------------------------------------------------------------------
100 // Details: The callee client calls the write function on the Logger. The data
102 // written is given out to all the mediums registered. The verbosity
104 // indicates to the medium the type of data or message given to it. The
106 // modes of verbosity and depending on the verbosity set determines
108 // sent to the medium's output.
110 // Args: vData - (R) The data to write to the logger.
111 // veType - (R) Verbosity type.
112 // Return: MIstatus::success - Functional succeeded.
113 // MIstatus::failure - Functional failed.
116 bool CMICmnLogMediumFile::Write(const CMIUtilString &vData,
117 const CMICmnLog::ELogVerbosity veType) {
118 if (m_bInitialized && m_file.IsOk()) {
119 const bool bDoWrite = (m_eVerbosityType & veType);
121 bool bNewCreated = false;
122 bool bOk = m_file.CreateWrite(m_fileNamePath, bNewCreated);
125 bOk = FileWriteHeader();
126 bOk = bOk && FileWriteEnglish(MassagedData(vData, veType));
132 return MIstatus::failure;
136 //------------------------------------------------------------------------------------
137 // Details: Retrieve *this medium's last error condition.
140 // Return: CString & - Text description.
143 const CMIUtilString &CMICmnLogMediumFile::GetError() const {
144 return m_strMILastErrorDescription;
148 //------------------------------------------------------------------------------------
149 // Details: Set the verbosity mode for this medium.
151 // Args: veType - (R) Mask value.
152 // Return: MIstatus::success - Functional succeeded.
153 // MIstatus::failure - Functional failed.
156 bool CMICmnLogMediumFile::SetVerbosity(const MIuint veType) {
157 m_eVerbosityType = veType;
158 return MIstatus::success;
162 //------------------------------------------------------------------------------------
163 // Details: Get the verbosity mode for this medium.
165 // Args: veType - (R) Mask value.
166 // Return: CMICmnLog::ELogVerbosity - Mask value.
169 MIuint CMICmnLogMediumFile::GetVerbosity() const { return m_eVerbosityType; }
172 //------------------------------------------------------------------------------------
173 // Details: Write data to a file English font.
175 // Args: vData - (R) The data to write to the logger.
179 bool CMICmnLogMediumFile::FileWriteEnglish(const CMIUtilString &vData) {
180 return m_file.Write(vData);
184 //------------------------------------------------------------------------------------
185 // Details: Determine and form the medium file's directory path and name.
188 // Return: MIstatus::success - Functional succeeded.
189 // MIstatus::failure - Functional failed.
192 bool CMICmnLogMediumFile::FileFormFileNamePath() {
193 ClrErrorDescription();
195 m_fileNamePath = MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH);
197 CMIUtilDateTimeStd date;
198 m_strMediumFileName =
199 CMIUtilString::Format(m_constMediumFileNameFormat.c_str(),
200 date.GetDateTimeLogFilename().c_str());
202 #if defined(_MSC_VER)
203 m_fileNamePath = CMIUtilString::Format(
204 "%s\\%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str());
206 m_fileNamePath = CMIUtilString::Format(
207 "%s/%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str());
208 #endif // defined ( _MSC_VER )
210 return MIstatus::success;
214 //------------------------------------------------------------------------------------
215 // Details: Retrieve the medium file's directory path and name.
218 // Return: CMIUtilString & - File path.
221 const CMIUtilString &CMICmnLogMediumFile::GetFileNamePath() const {
222 return m_fileNamePath;
226 //------------------------------------------------------------------------------------
227 // Details: Retrieve the medium file's name.
230 // Return: CMIUtilString & - File name.
233 const CMIUtilString &CMICmnLogMediumFile::GetFileName() const {
234 return m_strMediumFileName;
238 //------------------------------------------------------------------------------------
239 // Details: Massage the data to behave correct when submitted to file. Insert
241 // specific text. The veType is there to allow in the future to parse
243 // filter in out specific types of message to make viewing the log more
246 // Args: vData - (R) Raw data.
247 // veType - (R) Message type.
248 // Return: CMIUtilString - Massaged data.
252 CMICmnLogMediumFile::MassagedData(const CMIUtilString &vData,
253 const CMICmnLog::ELogVerbosity veType) {
254 const CMIUtilString strCr("\n");
256 const char verbosityCode(ConvertLogVerbosityTypeToId(veType));
257 const CMIUtilString dt(CMIUtilString::Format("%s %s", m_strDate.c_str(),
258 m_dateTime.GetTime().c_str()));
260 data = CMIUtilString::Format("%c,%s,%s", verbosityCode, dt.c_str(),
262 data = ConvertCr(data);
265 const size_t pos = vData.rfind(strCr);
266 if (pos == vData.size())
269 // ... did not have an EOL so add one
270 data += GetLineReturn();
276 //------------------------------------------------------------------------------------
277 // Details: Convert the Log's verbosity type number into a single char
280 // Args: veType - (R) Message type.
281 // Return: wchar_t - A letter.
284 char CMICmnLogMediumFile::ConvertLogVerbosityTypeToId(
285 const CMICmnLog::ELogVerbosity veType) const {
289 MIuint number(veType);
290 while (1 != number) {
291 number = number >> 1;
303 //------------------------------------------------------------------------------------
304 // Details: Retrieve state of whether the file medium is ok.
307 // Return: True - file ok.
308 // False - file has a problem.
311 bool CMICmnLogMediumFile::IsOk() const { return m_file.IsOk(); }
314 //------------------------------------------------------------------------------------
315 // Details: Status on the file log medium existing already.
318 // Return: True - Exists.
319 // False - Not found.
322 bool CMICmnLogMediumFile::IsFileExist() const {
323 return m_file.IsFileExist(GetFileNamePath());
327 //------------------------------------------------------------------------------------
328 // Details: Write the header text the logger file.
330 // Args: vText - (R) Text.
331 // Return: MIstatus::success - Functional succeeded.
332 // MIstatus::failure - Functional failed.
335 bool CMICmnLogMediumFile::FileWriteHeader() {
336 return FileWriteEnglish(ConvertCr(m_fileHeaderTxt));
340 //------------------------------------------------------------------------------------
341 // Details: Convert any carriage line returns to be compatible with the platform
343 // Log file is being written to.
345 // Args: vData - (R) Text data.
346 // Return: CMIUtilString - Converted string data.
349 CMIUtilString CMICmnLogMediumFile::ConvertCr(const CMIUtilString &vData) const {
350 const CMIUtilString strCr("\n");
351 const CMIUtilString &rCrCmpat(GetLineReturn());
353 if (strCr == rCrCmpat)
356 const size_t nSizeCmpat(rCrCmpat.size());
357 const size_t nSize(strCr.size());
358 CMIUtilString strConv(vData);
359 size_t pos = strConv.find(strCr);
360 while (pos != CMIUtilString::npos) {
361 strConv.replace(pos, nSize, rCrCmpat);
362 pos = strConv.find(strCr, pos + nSizeCmpat);
369 //------------------------------------------------------------------------------------
370 // Details: Set the header text that is written to the logger file at the
373 // Args: vText - (R) Text.
374 // Return: MIstatus::success - Functional succeeded.
375 // MIstatus::failure - Functional failed.
378 bool CMICmnLogMediumFile::SetHeaderTxt(const CMIUtilString &vText) {
379 m_fileHeaderTxt = vText;
381 return MIstatus::success;
385 //------------------------------------------------------------------------------------
386 // Details: Retrieve the file current carriage line return characters used.
389 // Return: CMIUtilString & - Text.
392 const CMIUtilString &CMICmnLogMediumFile::GetLineReturn() const {
393 return m_file.GetLineReturn();
397 //------------------------------------------------------------------------------------
398 // Details: Set the directory to place the log file.
400 // Args: vPath - (R) Path to log.
401 // Return: MIstatus::success - Functional succeeded.
402 // MIstatus::failure - Functional failed.
405 bool CMICmnLogMediumFile::SetDirectory(const CMIUtilString &vPath) {
406 m_strMediumFileDirectory = vPath;
408 return FileFormFileNamePath();