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"
14 #include "MIUtilSystemWindows.h"
15 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__linux__)
16 #include "MIUtilSystemLinux.h"
17 #elif defined(__APPLE__)
18 #include "MIUtilSystemOsx.h"
19 #endif // defined( _MSC_VER )
21 //++ ------------------------------------------------------------------------------------
22 // Details: CMICmnLogMediumFile constructor.
28 CMICmnLogMediumFile::CMICmnLogMediumFile(void)
29 : m_constThisMediumName(MIRSRC(IDS_MEDIUMFILE_NAME))
30 , m_constMediumFileNameFormat("lldb-mi-%s.log")
31 , m_strMediumFileName(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH))
32 , m_strMediumFileDirectory(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH))
33 , m_fileNamePath(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH))
34 , m_eVerbosityType(CMICmnLog::eLogVerbosity_Log)
35 , m_strDate(CMIUtilDateTimeStd().GetDate())
36 , m_fileHeaderTxt(MIRSRC(IDS_MEDIUMFILE_ERR_FILE_HEADER))
40 //++ ------------------------------------------------------------------------------------
41 // Details: CMICmnLogMediumFile destructor.
47 CMICmnLogMediumFile::~CMICmnLogMediumFile(void)
51 //++ ------------------------------------------------------------------------------------
52 // Details: Get the singleton instance of *this class.
55 // Return: CMICmnLogMediumFile - Reference to *this object.
59 CMICmnLogMediumFile::Instance(void)
61 static CMICmnLogMediumFile instance;
66 //++ ------------------------------------------------------------------------------------
67 // Details: Initialize setup *this medium ready for use.
70 // Return: MIstatus::success - Functional succeeded.
71 // MIstatus::failure - Functional failed.
75 CMICmnLogMediumFile::Initialize(void)
77 m_bInitialized = CMIUtilSystem().GetLogFilesPath(m_strMediumFileDirectory);
78 m_bInitialized &= FileFormFileNamePath();
80 return m_bInitialized;
83 //++ ------------------------------------------------------------------------------------
84 // Details: Unbind detach or release resources used by *this medium.
91 CMICmnLogMediumFile::Shutdown(void)
95 m_bInitialized = false;
98 return MIstatus::success;
101 //++ ------------------------------------------------------------------------------------
102 // Details: Retrieve the name of *this medium.
105 // Return: CMIUtilString - Text data.
108 const CMIUtilString &
109 CMICmnLogMediumFile::GetName(void) const
111 return m_constThisMediumName;
114 //++ ------------------------------------------------------------------------------------
115 // Details: The callee client calls the write function on the Logger. The data to be
116 // written is given out to all the mediums registered. The verbosity type parameter
117 // indicates to the medium the type of data or message given to it. The medium has
118 // modes of verbosity and depending on the verbosity set determines which data is
119 // sent to the medium's output.
121 // Args: vData - (R) The data to write to the logger.
122 // veType - (R) Verbosity type.
123 // Return: MIstatus::success - Functional succeeded.
124 // MIstatus::failure - Functional failed.
128 CMICmnLogMediumFile::Write(const CMIUtilString &vData, const CMICmnLog::ELogVerbosity veType)
130 if (m_bInitialized && m_file.IsOk())
132 const bool bDoWrite = (m_eVerbosityType & veType);
135 bool bNewCreated = false;
136 bool bOk = m_file.CreateWrite(m_fileNamePath, bNewCreated);
140 bOk = FileWriteHeader();
141 bOk = bOk && FileWriteEnglish(MassagedData(vData, veType));
147 return MIstatus::failure;
150 //++ ------------------------------------------------------------------------------------
151 // Details: Retrieve *this medium's last error condition.
154 // Return: CString & - Text description.
157 const CMIUtilString &
158 CMICmnLogMediumFile::GetError(void) const
160 return m_strMILastErrorDescription;
163 //++ ------------------------------------------------------------------------------------
164 // Details: Set the verbosity mode for this medium.
166 // Args: veType - (R) Mask value.
167 // Return: MIstatus::success - Functional succeeded.
168 // MIstatus::failure - Functional failed.
172 CMICmnLogMediumFile::SetVerbosity(const MIuint veType)
174 m_eVerbosityType = veType;
175 return MIstatus::success;
178 //++ ------------------------------------------------------------------------------------
179 // Details: Get the verbosity mode for this medium.
181 // Args: veType - (R) Mask value.
182 // Return: CMICmnLog::ELogVerbosity - Mask value.
186 CMICmnLogMediumFile::GetVerbosity(void) const
188 return m_eVerbosityType;
191 //++ ------------------------------------------------------------------------------------
192 // Details: Write data to a file English font.
194 // Args: vData - (R) The data to write to the logger.
199 CMICmnLogMediumFile::FileWriteEnglish(const CMIUtilString &vData)
201 return m_file.Write(vData);
204 //++ ------------------------------------------------------------------------------------
205 // Details: Determine and form the medium file's directory path and name.
208 // Return: MIstatus::success - Functional succeeded.
209 // MIstatus::failure - Functional failed.
213 CMICmnLogMediumFile::FileFormFileNamePath(void)
215 ClrErrorDescription();
217 m_fileNamePath = MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH);
219 if (m_strMediumFileDirectory.compare(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)) != 0)
221 CMIUtilDateTimeStd date;
222 m_strMediumFileName = CMIUtilString::Format(m_constMediumFileNameFormat.c_str(), date.GetDateTimeLogFilename().c_str());
224 #if defined(_MSC_VER)
225 m_fileNamePath = CMIUtilString::Format("%s\\%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str());
227 m_fileNamePath = CMIUtilString::Format("%s/%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str());
228 #endif // defined ( _MSC_VER )
230 return MIstatus::success;
233 SetErrorDescription(MIRSRC(IDE_MEDIUMFILE_ERR_GET_FILE_PATHNAME_SYS));
235 return MIstatus::failure;
238 //++ ------------------------------------------------------------------------------------
239 // Details: Retrieve the medium file's directory path and name.
242 // Return: CMIUtilString & - File path.
245 const CMIUtilString &
246 CMICmnLogMediumFile::GetFileNamePath(void) const
248 return m_fileNamePath;
251 //++ ------------------------------------------------------------------------------------
252 // Details: Retrieve the medium file's name.
255 // Return: CMIUtilString & - File name.
258 const CMIUtilString &
259 CMICmnLogMediumFile::GetFileName(void) const
261 return m_strMediumFileName;
264 //++ ------------------------------------------------------------------------------------
265 // Details: Massage the data to behave correct when submitted to file. Insert extra log
266 // specific text. The veType is there to allow in the future to parse the log and
267 // filter in out specific types of message to make viewing the log more manageable.
269 // Args: vData - (R) Raw data.
270 // veType - (R) Message type.
271 // Return: CMIUtilString - Massaged data.
275 CMICmnLogMediumFile::MassagedData(const CMIUtilString &vData, const CMICmnLog::ELogVerbosity veType)
277 const CMIUtilString strCr("\n");
279 const char verbosityCode(ConvertLogVerbosityTypeToId(veType));
280 const CMIUtilString dt(CMIUtilString::Format("%s %s", m_strDate.c_str(), m_dateTime.GetTime().c_str()));
282 data = CMIUtilString::Format("%c,%s,%s", verbosityCode, dt.c_str(), vData.c_str());
283 data = ConvertCr(data);
286 const size_t pos = vData.rfind(strCr);
287 if (pos == vData.size())
290 // ... did not have an EOL so add one
291 data += GetLineReturn();
296 //++ ------------------------------------------------------------------------------------
297 // Details: Convert the Log's verbosity type number into a single char character.
299 // Args: veType - (R) Message type.
300 // Return: wchar_t - A letter.
304 CMICmnLogMediumFile::ConvertLogVerbosityTypeToId(const CMICmnLog::ELogVerbosity veType) const
310 MIuint number(veType);
313 number = number >> 1;
326 //++ ------------------------------------------------------------------------------------
327 // Details: Retrieve state of whether the file medium is ok.
330 // Return: True - file ok.
331 // False - file has a problem.
335 CMICmnLogMediumFile::IsOk(void) const
337 return m_file.IsOk();
340 //++ ------------------------------------------------------------------------------------
341 // Details: Status on the file log medium existing already.
344 // Return: True - Exists.
345 // False - Not found.
349 CMICmnLogMediumFile::IsFileExist(void) const
351 return m_file.IsFileExist(GetFileNamePath());
354 //++ ------------------------------------------------------------------------------------
355 // Details: Write the header text the logger file.
357 // Args: vText - (R) Text.
358 // Return: MIstatus::success - Functional succeeded.
359 // MIstatus::failure - Functional failed.
363 CMICmnLogMediumFile::FileWriteHeader(void)
365 return FileWriteEnglish(ConvertCr(m_fileHeaderTxt));
368 //++ ------------------------------------------------------------------------------------
369 // Details: Convert any carriage line returns to be compatible with the platform the
370 // Log fiel is being written to.
372 // Args: vData - (R) Text data.
373 // Return: CMIUtilString - Converted string data.
377 CMICmnLogMediumFile::ConvertCr(const CMIUtilString &vData) const
379 const CMIUtilString strCr("\n");
380 const CMIUtilString &rCrCmpat(GetLineReturn());
382 if (strCr == rCrCmpat)
385 const size_t nSizeCmpat(rCrCmpat.size());
386 const size_t nSize(strCr.size());
387 CMIUtilString strConv(vData);
388 size_t pos = strConv.find(strCr);
389 while (pos != CMIUtilString::npos)
391 strConv.replace(pos, nSize, rCrCmpat);
392 pos = strConv.find(strCr, pos + nSizeCmpat);
398 //++ ------------------------------------------------------------------------------------
399 // Details: Set the header text that is written to the logger file at the beginning.
401 // Args: vText - (R) Text.
402 // Return: MIstatus::success - Functional succeeded.
403 // MIstatus::failure - Functional failed.
407 CMICmnLogMediumFile::SetHeaderTxt(const CMIUtilString &vText)
409 m_fileHeaderTxt = vText;
411 return MIstatus::success;
414 //++ ------------------------------------------------------------------------------------
415 // Details: Retrieve the file current carriage line return characters used.
418 // Return: CMIUtilString & - Text.
421 const CMIUtilString &
422 CMICmnLogMediumFile::GetLineReturn(void) const
424 return m_file.GetLineReturn();
427 //++ ------------------------------------------------------------------------------------
428 // Details: Set the directory to place the log file.
430 // Args: vPath - (R) Path to log.
431 // Return: MIstatus::success - Functional succeeded.
432 // MIstatus::failure - Functional failed.
436 CMICmnLogMediumFile::SetDirectory(const CMIUtilString &vPath)
438 m_strMediumFileDirectory = vPath;
440 return FileFormFileNamePath();