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 // File: MICmnLogMediumFile.cpp
13 // Overview: CMICmnLogMediumFile implementation.
15 // Environment: Compilers: Visual C++ 12.
16 // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
17 // Libraries: See MIReadmetxt.
23 #include "MICmnLogMediumFile.h"
24 #include "MICmnResources.h"
26 #include "MIUtilSystemWindows.h"
27 #elif defined(__FreeBSD__) || defined(__linux__)
28 #include "MIUtilSystemLinux.h"
29 #elif defined(__APPLE__)
30 #include "MIUtilSystemOsx.h"
31 #endif // defined( _MSC_VER )
33 //++ ------------------------------------------------------------------------------------
34 // Details: CMICmnLogMediumFile constructor.
40 CMICmnLogMediumFile::CMICmnLogMediumFile(void)
41 : m_constThisMediumName(MIRSRC(IDS_MEDIUMFILE_NAME))
42 , m_constMediumFileName("lldb-mi-log.txt")
43 , m_fileNamePath(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH))
44 , m_eVerbosityType(CMICmnLog::eLogVerbosity_Log)
45 , m_strDate(CMIUtilDateTimeStd().GetDate())
46 , m_fileHeaderTxt(MIRSRC(IDS_MEDIUMFILE_ERR_FILE_HEADER))
50 //++ ------------------------------------------------------------------------------------
51 // Details: CMICmnLogMediumFile destructor.
57 CMICmnLogMediumFile::~CMICmnLogMediumFile(void)
61 //++ ------------------------------------------------------------------------------------
62 // Details: Get the singleton instance of *this class.
65 // Return: CMICmnLogMediumFile - Reference to *this object.
69 CMICmnLogMediumFile::Instance(void)
71 static CMICmnLogMediumFile instance;
76 //++ ------------------------------------------------------------------------------------
77 // Details: Initialize setup *this medium ready for use.
80 // Return: MIstatus::success - Functional succeeded.
81 // MIstatus::failure - Functional failed.
85 CMICmnLogMediumFile::Initialize(void)
87 m_bInitialized = FileFormFileNamePath();
89 return m_bInitialized;
92 //++ ------------------------------------------------------------------------------------
93 // Details: Unbind detach or release resources used by *this medium.
100 CMICmnLogMediumFile::Shutdown(void)
104 m_bInitialized = false;
107 return MIstatus::success;
110 //++ ------------------------------------------------------------------------------------
111 // Details: Retrieve the name of *this medium.
114 // Return: CMIUtilString - Text data.
117 const CMIUtilString &
118 CMICmnLogMediumFile::GetName(void) const
120 return m_constThisMediumName;
123 //++ ------------------------------------------------------------------------------------
124 // Details: The callee client calls the write function on the Logger. The data to be
125 // written is given out to all the mediums registered. The verbosity type parameter
126 // indicates to the medium the type of data or message given to it. The medium has
127 // modes of verbosity and depending on the verbosity set determines which data is
128 // sent to the medium's output.
130 // Args: vData - (R) The data to write to the logger.
131 // veType - (R) Verbosity type.
132 // Return: MIstatus::success - Functional succeeded.
133 // MIstatus::failure - Functional failed.
137 CMICmnLogMediumFile::Write(const CMIUtilString &vData, const CMICmnLog::ELogVerbosity veType)
139 if (m_bInitialized && m_file.IsOk())
141 const bool bDoWrite = (m_eVerbosityType & veType);
144 bool bNewCreated = false;
145 bool bOk = m_file.CreateWrite(m_fileNamePath, bNewCreated);
149 bOk = FileWriteHeader();
150 bOk = bOk && FileWriteEnglish(MassagedData(vData, veType));
156 return MIstatus::failure;
159 //++ ------------------------------------------------------------------------------------
160 // Details: Retrieve *this medium's last error condition.
163 // Return: CString & - Text description.
166 const CMIUtilString &
167 CMICmnLogMediumFile::GetError(void) const
169 return m_strMILastErrorDescription;
172 //++ ------------------------------------------------------------------------------------
173 // Details: Set the verbosity mode for this medium.
175 // Args: veType - (R) Mask value.
176 // Return: MIstatus::success - Functional succeeded.
177 // MIstatus::failure - Functional failed.
181 CMICmnLogMediumFile::SetVerbosity(const MIuint veType)
183 m_eVerbosityType = veType;
184 return MIstatus::success;
187 //++ ------------------------------------------------------------------------------------
188 // Details: Get the verbosity mode for this medium.
190 // Args: veType - (R) Mask value.
191 // Return: CMICmnLog::ELogVerbosity - Mask value.
195 CMICmnLogMediumFile::GetVerbosity(void) const
197 return m_eVerbosityType;
200 //++ ------------------------------------------------------------------------------------
201 // Details: Write data to a file English font.
203 // Args: vData - (R) The data to write to the logger.
208 CMICmnLogMediumFile::FileWriteEnglish(const CMIUtilString &vData)
210 return m_file.Write(vData);
213 //++ ------------------------------------------------------------------------------------
214 // Details: Determine and form the medium file's directory path and name.
217 // Return: MIstatus::success - Functional succeeded.
218 // MIstatus::failure - Functional failed.
222 CMICmnLogMediumFile::FileFormFileNamePath(void)
224 ClrErrorDescription();
226 m_fileNamePath = MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH);
228 CMIUtilString strPathName;
229 if (CMIUtilSystem().GetLogFilesPath(strPathName))
231 const CMIUtilString strPath = CMIUtilFileStd().StripOffFileName(strPathName);
233 // ToDo: Review this LINUX log file quick fix so not hidden
235 // Linux was creating a log file here called '.\log.txt'. The '.' on linux
236 // signifies that this file is 'hidden' and not normally visible. A quick fix
237 // is to remove the path component all together. Linux also normally uses '/'
238 // as directory separators, again leading to the problem of the hidden log.
239 #if defined(_MSC_VER)
240 m_fileNamePath = CMIUtilString::Format("%s\\%s", strPath.c_str(), m_constMediumFileName.c_str());
242 m_fileNamePath = CMIUtilString::Format("%s", m_constMediumFileName.c_str());
243 #endif // defined ( _MSC_VER )
245 return MIstatus::success;
248 SetErrorDescription(MIRSRC(IDE_MEDIUMFILE_ERR_GET_FILE_PATHNAME_SYS));
250 return MIstatus::failure;
253 //++ ------------------------------------------------------------------------------------
254 // Details: Retrieve the medium file's directory path and name.
257 // Return: CMIUtilString & - File path.
260 const CMIUtilString &
261 CMICmnLogMediumFile::GetFileNamePath(void) const
263 return m_fileNamePath;
266 //++ ------------------------------------------------------------------------------------
267 // Details: Retrieve the medium file's name.
270 // Return: CMIUtilString & - File name.
273 const CMIUtilString &
274 CMICmnLogMediumFile::GetFileName(void) const
276 return m_constMediumFileName;
279 //++ ------------------------------------------------------------------------------------
280 // Details: Massage the data to behave correct when submitted to file. Insert extra log
281 // specific text. The veType is there to allow in the future to parse the log and
282 // filter in out specific types of message to make viewing the log more manageable.
284 // Args: vData - (R) Raw data.
285 // veType - (R) Message type.
286 // Return: CMIUtilString - Massaged data.
290 CMICmnLogMediumFile::MassagedData(const CMIUtilString &vData, const CMICmnLog::ELogVerbosity veType)
292 const CMIUtilString strCr("\n");
294 const MIchar verbosityCode(ConvertLogVerbosityTypeToId(veType));
295 const CMIUtilString dt(CMIUtilString::Format("%s %s", m_strDate.c_str(), m_dateTime.GetTime().c_str()));
297 data = CMIUtilString::Format("%c,%s,%s", verbosityCode, dt.c_str(), vData.c_str());
298 data = ConvertCr(data);
301 const MIint pos = vData.rfind(strCr);
302 if (pos == (MIint)vData.size())
305 // ... did not have an EOL so add one
306 data += GetLineReturn();
311 //++ ------------------------------------------------------------------------------------
312 // Details: Convert the Log's verbosity type number into a single char character.
314 // Args: veType - (R) Message type.
315 // Return: wchar_t - A letter.
319 CMICmnLogMediumFile::ConvertLogVerbosityTypeToId(const CMICmnLog::ELogVerbosity veType) const
325 MIuint number(veType);
328 number = number >> 1;
341 //++ ------------------------------------------------------------------------------------
342 // Details: Retrieve state of whether the file medium is ok.
345 // Return: True - file ok.
346 // False - file has a problem.
350 CMICmnLogMediumFile::IsOk(void) const
352 return m_file.IsOk();
355 //++ ------------------------------------------------------------------------------------
356 // Details: Status on the file log medium existing already.
359 // Return: True - Exists.
360 // False - Not found.
364 CMICmnLogMediumFile::IsFileExist(void) const
366 return m_file.IsFileExist(GetFileNamePath());
369 //++ ------------------------------------------------------------------------------------
370 // Details: Write the header text the logger file.
372 // Args: vText - (R) Text.
373 // Return: MIstatus::success - Functional succeeded.
374 // MIstatus::failure - Functional failed.
378 CMICmnLogMediumFile::FileWriteHeader(void)
380 return FileWriteEnglish(ConvertCr(m_fileHeaderTxt));
383 //++ ------------------------------------------------------------------------------------
384 // Details: Convert any carriage line returns to be compatible with the platform the
385 // Log fiel is being written to.
387 // Args: vData - (R) Text data.
388 // Return: CMIUtilString - Converted string data.
392 CMICmnLogMediumFile::ConvertCr(const CMIUtilString &vData) const
394 const CMIUtilString strCr("\n");
395 const CMIUtilString &rCrCmpat(GetLineReturn());
397 if (strCr == rCrCmpat)
400 const MIuint nSizeCmpat(rCrCmpat.size());
401 const MIuint nSize(strCr.size());
402 CMIUtilString strConv(vData);
403 MIint pos = strConv.find(strCr);
404 while (pos != (MIint)CMIUtilString::npos)
406 strConv.replace(pos, nSize, rCrCmpat);
407 pos = strConv.find(strCr, pos + nSizeCmpat);
413 //++ ------------------------------------------------------------------------------------
414 // Details: Set the header text that is written to the logger file at the begining.
416 // Args: vText - (R) Text.
417 // Return: MIstatus::success - Functional succeeded.
418 // MIstatus::failure - Functional failed.
422 CMICmnLogMediumFile::SetHeaderTxt(const CMIUtilString &vText)
424 m_fileHeaderTxt = vText;
426 return MIstatus::success;
429 //++ ------------------------------------------------------------------------------------
430 // Details: Retrieve the file current carriage line return characters used.
433 // Return: CMIUtilString & - Text.
436 const CMIUtilString &
437 CMICmnLogMediumFile::GetLineReturn(void) const
439 return m_file.GetLineReturn();