//===-- MICmnLogMediumFile.cpp ----------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // In-house headers: #include "MICmnLogMediumFile.h" #include "MICmnResources.h" #if defined(_MSC_VER) #include "MIUtilSystemWindows.h" #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__linux__) #include "MIUtilSystemLinux.h" #elif defined(__APPLE__) #include "MIUtilSystemOsx.h" #endif // defined( _MSC_VER ) //++ ------------------------------------------------------------------------------------ // Details: CMICmnLogMediumFile constructor. // Type: Method. // Args: None. // Return: None. // Throws: None. //-- CMICmnLogMediumFile::CMICmnLogMediumFile(void) : m_constThisMediumName(MIRSRC(IDS_MEDIUMFILE_NAME)) , m_constMediumFileNameFormat("lldb-mi-%s.log") , m_strMediumFileName(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)) , m_strMediumFileDirectory(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)) , m_fileNamePath(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)) , m_eVerbosityType(CMICmnLog::eLogVerbosity_Log) , m_strDate(CMIUtilDateTimeStd().GetDate()) , m_fileHeaderTxt(MIRSRC(IDS_MEDIUMFILE_ERR_FILE_HEADER)) { } //++ ------------------------------------------------------------------------------------ // Details: CMICmnLogMediumFile destructor. // Type: Overridden. // Args: None. // Return: None. // Throws: None. //-- CMICmnLogMediumFile::~CMICmnLogMediumFile(void) { } //++ ------------------------------------------------------------------------------------ // Details: Get the singleton instance of *this class. // Type: Static. // Args: None. // Return: CMICmnLogMediumFile - Reference to *this object. // Throws: None. //-- CMICmnLogMediumFile & CMICmnLogMediumFile::Instance(void) { static CMICmnLogMediumFile instance; return instance; } //++ ------------------------------------------------------------------------------------ // Details: Initialize setup *this medium ready for use. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLogMediumFile::Initialize(void) { m_bInitialized = CMIUtilSystem().GetLogFilesPath(m_strMediumFileDirectory); m_bInitialized &= FileFormFileNamePath(); return m_bInitialized; } //++ ------------------------------------------------------------------------------------ // Details: Unbind detach or release resources used by *this medium. // Type: Method. // Args: None. // Return: None. // Throws: None. //-- bool CMICmnLogMediumFile::Shutdown(void) { if (m_bInitialized) { m_bInitialized = false; m_file.Close(); } return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the name of *this medium. // Type: Overridden. // Args: None. // Return: CMIUtilString - Text data. // Throws: None. //-- const CMIUtilString & CMICmnLogMediumFile::GetName(void) const { return m_constThisMediumName; } //++ ------------------------------------------------------------------------------------ // Details: The callee client calls the write function on the Logger. The data to be // written is given out to all the mediums registered. The verbosity type parameter // indicates to the medium the type of data or message given to it. The medium has // modes of verbosity and depending on the verbosity set determines which data is // sent to the medium's output. // Type: Method. // Args: vData - (R) The data to write to the logger. // veType - (R) Verbosity type. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLogMediumFile::Write(const CMIUtilString &vData, const CMICmnLog::ELogVerbosity veType) { if (m_bInitialized && m_file.IsOk()) { const bool bDoWrite = (m_eVerbosityType & veType); if (bDoWrite) { bool bNewCreated = false; bool bOk = m_file.CreateWrite(m_fileNamePath, bNewCreated); if (bOk) { if (bNewCreated) bOk = FileWriteHeader(); bOk = bOk && FileWriteEnglish(MassagedData(vData, veType)); } return bOk; } } return MIstatus::failure; } //++ ------------------------------------------------------------------------------------ // Details: Retrieve *this medium's last error condition. // Type: Method. // Args: None. // Return: CString & - Text description. // Throws: None. //-- const CMIUtilString & CMICmnLogMediumFile::GetError(void) const { return m_strMILastErrorDescription; } //++ ------------------------------------------------------------------------------------ // Details: Set the verbosity mode for this medium. // Type: Method. // Args: veType - (R) Mask value. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLogMediumFile::SetVerbosity(const MIuint veType) { m_eVerbosityType = veType; return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: Get the verbosity mode for this medium. // Type: Method. // Args: veType - (R) Mask value. // Return: CMICmnLog::ELogVerbosity - Mask value. // Throws: None. //-- MIuint CMICmnLogMediumFile::GetVerbosity(void) const { return m_eVerbosityType; } //++ ------------------------------------------------------------------------------------ // Details: Write data to a file English font. // Type: Method. // Args: vData - (R) The data to write to the logger. // Return: None. // Throws: None. //-- bool CMICmnLogMediumFile::FileWriteEnglish(const CMIUtilString &vData) { return m_file.Write(vData); } //++ ------------------------------------------------------------------------------------ // Details: Determine and form the medium file's directory path and name. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLogMediumFile::FileFormFileNamePath(void) { ClrErrorDescription(); m_fileNamePath = MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH); if (m_strMediumFileDirectory.compare(MIRSRC(IDS_MEDIUMFILE_ERR_INVALID_PATH)) != 0) { CMIUtilDateTimeStd date; m_strMediumFileName = CMIUtilString::Format(m_constMediumFileNameFormat.c_str(), date.GetDateTimeLogFilename().c_str()); #if defined(_MSC_VER) m_fileNamePath = CMIUtilString::Format("%s\\%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str()); #else m_fileNamePath = CMIUtilString::Format("%s/%s", m_strMediumFileDirectory.c_str(), m_strMediumFileName.c_str()); #endif // defined ( _MSC_VER ) return MIstatus::success; } SetErrorDescription(MIRSRC(IDE_MEDIUMFILE_ERR_GET_FILE_PATHNAME_SYS)); return MIstatus::failure; } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the medium file's directory path and name. // Type: Method. // Args: None. // Return: CMIUtilString & - File path. // Throws: None. //-- const CMIUtilString & CMICmnLogMediumFile::GetFileNamePath(void) const { return m_fileNamePath; } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the medium file's name. // Type: Method. // Args: None. // Return: CMIUtilString & - File name. // Throws: None. //-- const CMIUtilString & CMICmnLogMediumFile::GetFileName(void) const { return m_strMediumFileName; } //++ ------------------------------------------------------------------------------------ // Details: Massage the data to behave correct when submitted to file. Insert extra log // specific text. The veType is there to allow in the future to parse the log and // filter in out specific types of message to make viewing the log more manageable. // Type: Method. // Args: vData - (R) Raw data. // veType - (R) Message type. // Return: CMIUtilString - Massaged data. // Throws: None. //-- CMIUtilString CMICmnLogMediumFile::MassagedData(const CMIUtilString &vData, const CMICmnLog::ELogVerbosity veType) { const CMIUtilString strCr("\n"); CMIUtilString data; const char verbosityCode(ConvertLogVerbosityTypeToId(veType)); const CMIUtilString dt(CMIUtilString::Format("%s %s", m_strDate.c_str(), m_dateTime.GetTime().c_str())); data = CMIUtilString::Format("%c,%s,%s", verbosityCode, dt.c_str(), vData.c_str()); data = ConvertCr(data); // Look for EOL... const size_t pos = vData.rfind(strCr); if (pos == vData.size()) return data; // ... did not have an EOL so add one data += GetLineReturn(); return data; } //++ ------------------------------------------------------------------------------------ // Details: Convert the Log's verbosity type number into a single char character. // Type: Method. // Args: veType - (R) Message type. // Return: wchar_t - A letter. // Throws: None. //-- char CMICmnLogMediumFile::ConvertLogVerbosityTypeToId(const CMICmnLog::ELogVerbosity veType) const { char c = 0; if (veType != 0) { MIuint cnt = 0; MIuint number(veType); while (1 != number) { number = number >> 1; ++cnt; } c = 'A' + cnt; } else { c = '*'; } return c; } //++ ------------------------------------------------------------------------------------ // Details: Retrieve state of whether the file medium is ok. // Type: Method. // Args: None. // Return: True - file ok. // False - file has a problem. // Throws: None. //-- bool CMICmnLogMediumFile::IsOk(void) const { return m_file.IsOk(); } //++ ------------------------------------------------------------------------------------ // Details: Status on the file log medium existing already. // Type: Method. // Args: None. // Return: True - Exists. // False - Not found. // Throws: None. //-- bool CMICmnLogMediumFile::IsFileExist(void) const { return m_file.IsFileExist(GetFileNamePath()); } //++ ------------------------------------------------------------------------------------ // Details: Write the header text the logger file. // Type: Method. // Args: vText - (R) Text. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLogMediumFile::FileWriteHeader(void) { return FileWriteEnglish(ConvertCr(m_fileHeaderTxt)); } //++ ------------------------------------------------------------------------------------ // Details: Convert any carriage line returns to be compatible with the platform the // Log fiel is being written to. // Type: Method. // Args: vData - (R) Text data. // Return: CMIUtilString - Converted string data. // Throws: None. //-- CMIUtilString CMICmnLogMediumFile::ConvertCr(const CMIUtilString &vData) const { const CMIUtilString strCr("\n"); const CMIUtilString &rCrCmpat(GetLineReturn()); if (strCr == rCrCmpat) return vData; const size_t nSizeCmpat(rCrCmpat.size()); const size_t nSize(strCr.size()); CMIUtilString strConv(vData); size_t pos = strConv.find(strCr); while (pos != CMIUtilString::npos) { strConv.replace(pos, nSize, rCrCmpat); pos = strConv.find(strCr, pos + nSizeCmpat); } return strConv; } //++ ------------------------------------------------------------------------------------ // Details: Set the header text that is written to the logger file at the begining. // Type: Method. // Args: vText - (R) Text. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLogMediumFile::SetHeaderTxt(const CMIUtilString &vText) { m_fileHeaderTxt = vText; return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the file current carriage line return characters used. // Type: Method. // Args: None. // Return: CMIUtilString & - Text. // Throws: None. //-- const CMIUtilString & CMICmnLogMediumFile::GetLineReturn(void) const { return m_file.GetLineReturn(); } //++ ------------------------------------------------------------------------------------ // Details: Set the diretory to place the log file. // Type: Method. // Args: vPath - (R) Path to log. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmnLogMediumFile::SetDirectory(const CMIUtilString &vPath) { m_strMediumFileDirectory = vPath; return FileFormFileNamePath(); }