292 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			292 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- MIUtilFileStd.cpp ---------------------------------------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| // Third party headers
 | |
| #include <assert.h>
 | |
| #include <cerrno>
 | |
| #include <stdio.h>
 | |
| #include <string.h> // For strerror()
 | |
| 
 | |
| // In-house headers:
 | |
| #include "MICmnResources.h"
 | |
| #include "MIUtilFileStd.h"
 | |
| #include "lldb/Host/FileSystem.h"
 | |
| 
 | |
| #include "llvm/Support/ConvertUTF.h"
 | |
| 
 | |
| //++
 | |
| //------------------------------------------------------------------------------------
 | |
| // Details: CMIUtilFileStd constructor.
 | |
| // Type:    Method.
 | |
| // Args:    None.
 | |
| // Return:  None.
 | |
| // Throws:  None.
 | |
| //--
 | |
| CMIUtilFileStd::CMIUtilFileStd()
 | |
|     : m_fileNamePath(CMIUtilString()), m_pFileHandle(nullptr)
 | |
| #if defined(_MSC_VER)
 | |
|       ,
 | |
|       m_constCharNewLine("\r\n")
 | |
| #else
 | |
|       ,
 | |
|       m_constCharNewLine("\n")
 | |
| #endif // #if defined( _MSC_VER )
 | |
|       ,
 | |
|       m_bFileError(false) {
 | |
| }
 | |
| 
 | |
| //++
 | |
| //------------------------------------------------------------------------------------
 | |
| // Details: CMIUtilFileStd destructor.
 | |
| // Type:    Method.
 | |
| // Args:    None.
 | |
| // Return:  None.
 | |
| // Throws:  None.
 | |
| //--
 | |
| CMIUtilFileStd::~CMIUtilFileStd() { Close(); }
 | |
| 
 | |
| //++
 | |
| //------------------------------------------------------------------------------------
 | |
| // Details: Open file for writing. On the first call to this function after
 | |
| // *this object
 | |
| //          is created the file is either created or replace, from then on open
 | |
| //          only opens
 | |
| //          an existing file.
 | |
| // Type:    Method.
 | |
| // Args:    vFileNamePath   - (R) File name path.
 | |
| //          vwrbNewCreated  - (W) True - file recreated, false - file appended
 | |
| //          too.
 | |
| // Return:  MIstatus::success - Functional succeeded.
 | |
| //          MIstatus::failure - Functional failed.
 | |
| // Throws:  None.
 | |
| //--
 | |
| bool CMIUtilFileStd::CreateWrite(const CMIUtilString &vFileNamePath,
 | |
|                                  bool &vwrbNewCreated) {
 | |
|   // Reset
 | |
|   m_bFileError = false;
 | |
|   vwrbNewCreated = false;
 | |
| 
 | |
|   if (vFileNamePath.empty()) {
 | |
|     m_bFileError = true;
 | |
|     SetErrorDescription(MIRSRC(IDS_UTIL_FILE_ERR_INVALID_PATHNAME));
 | |
|     return MIstatus::failure;
 | |
|   }
 | |
| 
 | |
|   // File is already open so exit
 | |
|   if (m_pFileHandle != nullptr)
 | |
|     return MIstatus::success;
 | |
| 
 | |
| #if !defined(_MSC_VER)
 | |
|   // Open with 'write' and 'binary' mode
 | |
|   m_pFileHandle = ::fopen(vFileNamePath.c_str(), "wb");
 | |
| #else
 | |
|   // Open a file with exclusive write and shared read permissions
 | |
|   std::wstring path;
 | |
|   if (llvm::ConvertUTF8toWide(vFileNamePath.c_str(), path))
 | |
|     m_pFileHandle = ::_wfsopen(path.c_str(), L"wb", _SH_DENYWR);
 | |
|   else {
 | |
|     errno = EINVAL;
 | |
|     m_pFileHandle = nullptr;
 | |
|   }
 | |
| #endif // !defined( _MSC_VER )
 | |
| 
 | |
|   if (m_pFileHandle == nullptr) {
 | |
|     m_bFileError = true;
 | |
|     SetErrorDescriptionn(MIRSRC(IDS_UTIL_FILE_ERR_OPENING_FILE),
 | |
|                          strerror(errno), vFileNamePath.c_str());
 | |
|     return MIstatus::failure;
 | |
|   }
 | |
| 
 | |
|   vwrbNewCreated = true;
 | |
|   m_fileNamePath = vFileNamePath;
 | |
| 
 | |
|   return MIstatus::success;
 | |
| }
 | |
| 
 | |
| //++
 | |
| //------------------------------------------------------------------------------------
 | |
| // Details: Write data to existing opened file.
 | |
| // Type:    Method.
 | |
| // Args:    vData - (R) Text data.
 | |
| // Return:  MIstatus::success - Functional succeeded.
 | |
| //          MIstatus::failure - Functional failed.
 | |
| // Throws:  None.
 | |
| //--
 | |
| bool CMIUtilFileStd::Write(const CMIUtilString &vData) {
 | |
|   if (vData.size() == 0)
 | |
|     return MIstatus::success;
 | |
| 
 | |
|   if (m_bFileError)
 | |
|     return MIstatus::failure;
 | |
| 
 | |
|   if (m_pFileHandle == nullptr) {
 | |
|     m_bFileError = true;
 | |
|     SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_NOTOPEN),
 | |
|                          m_fileNamePath.c_str());
 | |
|     return MIstatus::failure;
 | |
|   }
 | |
| 
 | |
|   // Get the string size
 | |
|   MIuint size = vData.size();
 | |
|   if (::fwrite(vData.c_str(), 1, size, m_pFileHandle) == size) {
 | |
|     // Flush the data to the file
 | |
|     ::fflush(m_pFileHandle);
 | |
|     return MIstatus::success;
 | |
|   }
 | |
| 
 | |
|   // Not all of the data has been transferred
 | |
|   m_bFileError = true;
 | |
|   SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_FILE),
 | |
|                        m_fileNamePath.c_str());
 | |
|   return MIstatus::failure;
 | |
| }
 | |
| 
 | |
| //++
 | |
| //------------------------------------------------------------------------------------
 | |
| // Details: Write data to existing opened file.
 | |
| // Type:    Method.
 | |
| // Args:    vData       - (R) Text data.
 | |
| //          vCharCnt    - (R) Text data length.
 | |
| // Return:  MIstatus::success - Functional succeeded.
 | |
| //          MIstatus::failure - Functional failed.
 | |
| // Throws:  None.
 | |
| //--
 | |
| bool CMIUtilFileStd::Write(const char *vpData, const MIuint vCharCnt) {
 | |
|   if (vCharCnt == 0)
 | |
|     return MIstatus::success;
 | |
| 
 | |
|   if (m_bFileError)
 | |
|     return MIstatus::failure;
 | |
| 
 | |
|   if (m_pFileHandle == nullptr) {
 | |
|     m_bFileError = true;
 | |
|     SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_NOTOPEN),
 | |
|                          m_fileNamePath.c_str());
 | |
|     return MIstatus::failure;
 | |
|   }
 | |
| 
 | |
|   if (::fwrite(vpData, 1, vCharCnt, m_pFileHandle) == vCharCnt) {
 | |
|     // Flush the data to the file
 | |
|     ::fflush(m_pFileHandle);
 | |
|     return MIstatus::success;
 | |
|   }
 | |
| 
 | |
|   // Not all of the data has been transferred
 | |
|   m_bFileError = true;
 | |
|   SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_FILE),
 | |
|                        m_fileNamePath.c_str());
 | |
|   return MIstatus::failure;
 | |
| }
 | |
| 
 | |
| //++
 | |
| //------------------------------------------------------------------------------------
 | |
| // Details: Close existing opened file. Note Close() must must an open!
 | |
| // Type:    Method.
 | |
| // Args:    None.
 | |
| // Return:  None.
 | |
| // Throws:  None.
 | |
| //--
 | |
| void CMIUtilFileStd::Close() {
 | |
|   if (m_pFileHandle == nullptr)
 | |
|     return;
 | |
| 
 | |
|   ::fclose(m_pFileHandle);
 | |
|   m_pFileHandle = nullptr;
 | |
|   // m_bFileError = false; Do not reset as want to remain until next attempt at
 | |
|   // open or create
 | |
| }
 | |
| 
 | |
| //++
 | |
| //------------------------------------------------------------------------------------
 | |
| // Details: Retrieve state of whether the file is ok.
 | |
| // Type:    Method.
 | |
| // Args:    None.
 | |
| // Return:  True - file ok.
 | |
| //          False - file has a problem.
 | |
| // Throws:  None.
 | |
| //--
 | |
| bool CMIUtilFileStd::IsOk() const { return !m_bFileError; }
 | |
| 
 | |
| //++
 | |
| //------------------------------------------------------------------------------------
 | |
| // Details: Status on a file existing already.
 | |
| // Type:    Method.
 | |
| // Args:    vFileNamePath.
 | |
| // Return:  True - Exists.
 | |
| //          False - Not found.
 | |
| // Throws:  None.
 | |
| //--
 | |
| bool CMIUtilFileStd::IsFileExist(const CMIUtilString &vFileNamePath) const {
 | |
|   if (vFileNamePath.empty())
 | |
|     return false;
 | |
| 
 | |
|   FILE *pTmp = nullptr;
 | |
|   pTmp = ::fopen(vFileNamePath.c_str(), "wb");
 | |
|   if (pTmp != nullptr) {
 | |
|     ::fclose(pTmp);
 | |
|     return true;
 | |
|   }
 | |
| 
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| //++
 | |
| //------------------------------------------------------------------------------------
 | |
| // Details: Retrieve the file current carriage line return characters used.
 | |
| // Type:    Method.
 | |
| // Args:    None.
 | |
| // Return:  CMIUtilString & - Text.
 | |
| // Throws:  None.
 | |
| //--
 | |
| const CMIUtilString &CMIUtilFileStd::GetLineReturn() const {
 | |
|   return m_constCharNewLine;
 | |
| }
 | |
| 
 | |
| //++
 | |
| //------------------------------------------------------------------------------------
 | |
| // Details: Given a file name directory path, strip off the filename and return
 | |
| // the path.
 | |
| //          It look for either backslash or forward slash.
 | |
| // Type:    Method.
 | |
| // Args:    vDirectoryPath  - (R) Text directory path.
 | |
| // Return:  CMIUtilString - Directory path.
 | |
| // Throws:  None.
 | |
| //--
 | |
| CMIUtilString
 | |
| CMIUtilFileStd::StripOffFileName(const CMIUtilString &vDirectoryPath) {
 | |
|   const size_t nPos = vDirectoryPath.rfind('\\');
 | |
|   size_t nPos2 = vDirectoryPath.rfind('/');
 | |
|   if ((nPos == std::string::npos) && (nPos2 == std::string::npos))
 | |
|     return vDirectoryPath;
 | |
| 
 | |
|   if (nPos > nPos2)
 | |
|     nPos2 = nPos;
 | |
| 
 | |
|   const CMIUtilString strPath(vDirectoryPath.substr(0, nPos2).c_str());
 | |
|   return strPath;
 | |
| }
 | |
| 
 | |
| //++
 | |
| //------------------------------------------------------------------------------------
 | |
| // Details: Return either backslash or forward slash appropriate to the OS this
 | |
| // application
 | |
| //          is running on.
 | |
| // Type:    Static method.
 | |
| // Args:    None.
 | |
| // Return:  char - '/' or '\' character.
 | |
| // Throws:  None.
 | |
| //--
 | |
| char CMIUtilFileStd::GetSlash() {
 | |
| #if !defined(_MSC_VER)
 | |
|   return '/';
 | |
| #else
 | |
|   return '\\';
 | |
| #endif // !defined( _MSC_VER )
 | |
| }
 |