1 //===-- MIUtilFileStd.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 //===----------------------------------------------------------------------===//
10 // Third party headers
17 #include "MICmnResources.h"
18 #include "MIUtilFileStd.h"
19 #include "lldb/Host/FileSystem.h"
21 #include "llvm/Support/ConvertUTF.h"
24 //------------------------------------------------------------------------------------
25 // Details: CMIUtilFileStd constructor.
31 CMIUtilFileStd::CMIUtilFileStd()
32 : m_fileNamePath(CMIUtilString()), m_pFileHandle(nullptr)
35 m_constCharNewLine("\r\n")
38 m_constCharNewLine("\n")
39 #endif // #if defined( _MSC_VER )
45 //------------------------------------------------------------------------------------
46 // Details: CMIUtilFileStd destructor.
52 CMIUtilFileStd::~CMIUtilFileStd() { Close(); }
55 //------------------------------------------------------------------------------------
56 // Details: Open file for writing. On the first call to this function after
58 // is created the file is either created or replace, from then on open
62 // Args: vFileNamePath - (R) File name path.
63 // vwrbNewCreated - (W) True - file recreated, false - file appended
65 // Return: MIstatus::success - Functional succeeded.
66 // MIstatus::failure - Functional failed.
69 bool CMIUtilFileStd::CreateWrite(const CMIUtilString &vFileNamePath,
70 bool &vwrbNewCreated) {
73 vwrbNewCreated = false;
75 if (vFileNamePath.empty()) {
77 SetErrorDescription(MIRSRC(IDS_UTIL_FILE_ERR_INVALID_PATHNAME));
78 return MIstatus::failure;
81 // File is already open so exit
82 if (m_pFileHandle != nullptr)
83 return MIstatus::success;
85 #if !defined(_MSC_VER)
86 // Open with 'write' and 'binary' mode
87 m_pFileHandle = ::fopen(vFileNamePath.c_str(), "wb");
89 // Open a file with exclusive write and shared read permissions
91 if (llvm::ConvertUTF8toWide(vFileNamePath.c_str(), path))
92 m_pFileHandle = ::_wfsopen(path.c_str(), L"wb", _SH_DENYWR);
95 m_pFileHandle = nullptr;
97 #endif // !defined( _MSC_VER )
99 if (m_pFileHandle == nullptr) {
101 SetErrorDescriptionn(MIRSRC(IDS_UTIL_FILE_ERR_OPENING_FILE),
102 strerror(errno), vFileNamePath.c_str());
103 return MIstatus::failure;
106 vwrbNewCreated = true;
107 m_fileNamePath = vFileNamePath;
109 return MIstatus::success;
113 //------------------------------------------------------------------------------------
114 // Details: Write data to existing opened file.
116 // Args: vData - (R) Text data.
117 // Return: MIstatus::success - Functional succeeded.
118 // MIstatus::failure - Functional failed.
121 bool CMIUtilFileStd::Write(const CMIUtilString &vData) {
122 if (vData.size() == 0)
123 return MIstatus::success;
126 return MIstatus::failure;
128 if (m_pFileHandle == nullptr) {
130 SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_NOTOPEN),
131 m_fileNamePath.c_str());
132 return MIstatus::failure;
135 // Get the string size
136 MIuint size = vData.size();
137 if (::fwrite(vData.c_str(), 1, size, m_pFileHandle) == size) {
138 // Flush the data to the file
139 ::fflush(m_pFileHandle);
140 return MIstatus::success;
143 // Not all of the data has been transferred
145 SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_FILE),
146 m_fileNamePath.c_str());
147 return MIstatus::failure;
151 //------------------------------------------------------------------------------------
152 // Details: Write data to existing opened file.
154 // Args: vData - (R) Text data.
155 // vCharCnt - (R) Text data length.
156 // Return: MIstatus::success - Functional succeeded.
157 // MIstatus::failure - Functional failed.
160 bool CMIUtilFileStd::Write(const char *vpData, const MIuint vCharCnt) {
162 return MIstatus::success;
165 return MIstatus::failure;
167 if (m_pFileHandle == nullptr) {
169 SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_NOTOPEN),
170 m_fileNamePath.c_str());
171 return MIstatus::failure;
174 if (::fwrite(vpData, 1, vCharCnt, m_pFileHandle) == vCharCnt) {
175 // Flush the data to the file
176 ::fflush(m_pFileHandle);
177 return MIstatus::success;
180 // Not all of the data has been transferred
182 SetErrorDescriptionn(MIRSRC(IDE_UTIL_FILE_ERR_WRITING_FILE),
183 m_fileNamePath.c_str());
184 return MIstatus::failure;
188 //------------------------------------------------------------------------------------
189 // Details: Close existing opened file. Note Close() must must an open!
195 void CMIUtilFileStd::Close() {
196 if (m_pFileHandle == nullptr)
199 ::fclose(m_pFileHandle);
200 m_pFileHandle = nullptr;
201 // m_bFileError = false; Do not reset as want to remain until next attempt at
206 //------------------------------------------------------------------------------------
207 // Details: Retrieve state of whether the file is ok.
210 // Return: True - file ok.
211 // False - file has a problem.
214 bool CMIUtilFileStd::IsOk() const { return !m_bFileError; }
217 //------------------------------------------------------------------------------------
218 // Details: Status on a file existing already.
220 // Args: vFileNamePath.
221 // Return: True - Exists.
222 // False - Not found.
225 bool CMIUtilFileStd::IsFileExist(const CMIUtilString &vFileNamePath) const {
226 if (vFileNamePath.empty())
229 FILE *pTmp = nullptr;
230 pTmp = ::fopen(vFileNamePath.c_str(), "wb");
231 if (pTmp != nullptr) {
240 //------------------------------------------------------------------------------------
241 // Details: Retrieve the file current carriage line return characters used.
244 // Return: CMIUtilString & - Text.
247 const CMIUtilString &CMIUtilFileStd::GetLineReturn() const {
248 return m_constCharNewLine;
252 //------------------------------------------------------------------------------------
253 // Details: Given a file name directory path, strip off the filename and return
255 // It look for either backslash or forward slash.
257 // Args: vDirectoryPath - (R) Text directory path.
258 // Return: CMIUtilString - Directory path.
262 CMIUtilFileStd::StripOffFileName(const CMIUtilString &vDirectoryPath) {
263 const size_t nPos = vDirectoryPath.rfind('\\');
264 size_t nPos2 = vDirectoryPath.rfind('/');
265 if ((nPos == std::string::npos) && (nPos2 == std::string::npos))
266 return vDirectoryPath;
271 const CMIUtilString strPath(vDirectoryPath.substr(0, nPos2).c_str());
276 //------------------------------------------------------------------------------------
277 // Details: Return either backslash or forward slash appropriate to the OS this
280 // Type: Static method.
282 // Return: char - '/' or '\' character.
285 char CMIUtilFileStd::GetSlash() {
286 #if !defined(_MSC_VER)
290 #endif // !defined( _MSC_VER )