2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
18 * @file FIo_NormalFile.cpp
19 * @brief This is the implementation file for _NormalFile class.
26 #include <sys/types.h>
33 #include <unique_ptr.h>
36 #include <FIoDirectory.h>
37 #include <FBaseResult.h>
38 #include <FBaseSysLog.h>
40 #include <FBase_StringConverter.h>
41 #include <FBase_NativeError.h>
42 #include <FIo_FileAttributesImpl.h>
43 #include <FIo_NormalFile.h>
46 using namespace Tizen::Base;
48 namespace Tizen { namespace Io
51 static const int _MAX_LINE_LENGTH = 4096;
53 #define _MAX_OPENMODE_LENGTH 3
55 _NormalFile::_NormalFile(void)
60 _NormalFile::~_NormalFile(void)
66 if (fclose(__pFile) != 0)
68 r = __ConvertNativeErrorToResult(errno);
69 SysLog(NID_IO, "[%s] Failed to close the file.", GetErrorMessage(r));
76 _NormalFile::Construct(const String& filePath, const char* pOpenMode)
78 SysAssertf(__pFile == NULL, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class\n");
83 unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
84 SysTryReturn(NID_IO, (pFilePath != null), GetLastResult(), GetLastResult(), ("[%s] Invalid file path."),
85 GetErrorMessage(GetLastResult()));
87 FILE* pFile = fopen(pFilePath.get(), pOpenMode);
90 r = __ConvertNativeErrorToResult(errno);
91 SysSecureLogException(NID_IO, r, "[%s] Failed to open file (%s) in openMode (%s), errno: %d (%s).",
92 GetErrorMessage(r), pFilePath.get(), pOpenMode, errno, strerror(errno));
99 __filePath = filePath;
105 _NormalFile::ReadN(char** buffer, int& length)
107 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
108 result r = E_SUCCESS;
110 int ret = fseek(__pFile, 0, SEEK_END);
111 SysTryReturnResult(NID_IO, ret >= 0, E_SYSTEM, "The system I/O error occurred.");
113 long fileSize = ftell(__pFile);
114 SysTryReturnResult(NID_IO, fileSize >= 0, E_SYSTEM, "The system I/O error occurred.");
116 SysSecureLog(NID_IO, "The length of registry file (%ls) is %ld.", __filePath.GetPointer(), fileSize);
122 ret = fseek(__pFile, 0, SEEK_SET); // moves file offset to zero because of a+ open mode.
123 SysTryReturnResult(NID_IO, ret >= 0, E_SYSTEM, "The system I/O error occurred.");
125 unique_ptr<char[]> pBuffer(new (std::nothrow) char[fileSize + 1]);
126 SysTryReturnResult(NID_IO, pBuffer != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
127 memset(pBuffer.get(), 0x00, fileSize + 1);
129 int readBytes = fread((void*)pBuffer.get(), 1, (size_t)fileSize, __pFile);
130 SysTryCatch(NID_IO, readBytes > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to read registry file (%d, %s).",
131 errno, strerror(errno));
133 length = readBytes + 1;
134 *buffer = pBuffer.release();
148 _NormalFile::Read(ByteBuffer& buffer)
150 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
152 result r = E_SUCCESS;
154 int length = buffer.GetRemaining();
157 return E_INVALID_ARG;
160 int curPos = buffer.GetPosition();
161 int bytesRead = fread((void*) (buffer.GetPointer() + curPos), 1, length, __pFile);
162 if (bytesRead < length)
164 SysTryReturnResult(NID_IO, !(bytesRead == 0 && feof(__pFile)), E_END_OF_FILE, "end of file");
168 r = __ConvertNativeErrorToResult(errno);
169 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for reading!");
170 SysLogException(NID_IO, r, "[%s] Failed to read data from file, (errno: %d)", GetErrorMessage(r), errno);
175 buffer.SetPosition(curPos + bytesRead);
181 _NormalFile::Read(void* buffer, int length)
183 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
185 result r = E_SUCCESS;
187 int readBytes = fread(buffer, 1, length, __pFile);
188 if (readBytes < length)
190 //SysTryReturn(NID_IO, !(readBytes == 0 && feof(__pFile)), 0, E_END_OF_FILE, "[E_END_OF_FILE] end of file");
191 if (readBytes == 0 && feof(__pFile))
193 SysLog(NID_IO, "[E_END_OF_FILE] end of file");
194 SetLastResult(E_END_OF_FILE);
200 r = __ConvertNativeErrorToResult(errno);
201 SysTryReturn(NID_IO, !(r == E_INVALID_OPERATION), 0, E_ILLEGAL_ACCESS,
202 "[E_ILLEGAL_ACCESS] File was not opened for reading!");
203 SysLogException(NID_IO, r, "[%s] Failed to read data from file", GetErrorMessage(r));
208 SetLastResult(E_SUCCESS);
213 _NormalFile::Read(String& buffer)
215 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
217 char line[_MAX_LINE_LENGTH] = {0, };
218 result r = E_SUCCESS;
221 if (fgets(line, _MAX_LINE_LENGTH - 1, __pFile) == null)
223 SysTryReturnResult(NID_IO, !feof(__pFile), E_END_OF_FILE, "end of file");
227 r = __ConvertNativeErrorToResult(errno);
228 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, " File was not opened for reading!");
229 SysLogException(NID_IO, r, "[%s] Failed to read data from file", GetErrorMessage(r));
234 buffer = String(line);
241 _NormalFile::Write(const ByteBuffer& buffer)
243 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
245 result r = E_SUCCESS;
247 int length = buffer.GetLimit();
250 return E_INVALID_ARG;
253 int bytesWritten = fwrite(buffer.GetPointer(), 1, length, __pFile);
254 if (bytesWritten < length)
258 r = __ConvertNativeErrorToResult(errno);
259 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for writing!");
260 SysLogException(NID_IO, r, "[%s] Failed to write data to file, (errno: %d).", GetErrorMessage(r), errno);
268 _NormalFile::Write(const void* buffer, int length)
270 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
271 SysTryReturnResult(NID_IO, length > 0, E_INVALID_ARG, "length cannot be 0!");
273 result r = E_SUCCESS;
275 if ((size_t) length > fwrite(buffer, 1, length, __pFile))
279 r = __ConvertNativeErrorToResult(errno);
280 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for writing!");
281 SysLogException(NID_IO, r, "[%s] Failed to write data to file, (errno: %d).", GetErrorMessage(r), errno);
289 _NormalFile::Write(const String& buffer)
291 result r = E_SUCCESS;
293 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
294 SysTryReturnResult(NID_IO, buffer.GetLength() > 0, E_INVALID_ARG, "Buffer length cannot be 0!");
296 unique_ptr<char[]> pData(_StringConverter::CopyToCharArrayN(buffer));
297 SysTryReturn(NID_IO, (pData != null), GetLastResult(), GetLastResult(), ("[%s] Invalid file path."),
298 GetErrorMessage(GetLastResult()));
300 if (fputs(pData.get(), __pFile) <= 0)
304 r = __ConvertNativeErrorToResult(errno);
305 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for writing!");
306 SysLogException(NID_IO, r, "[%s] Failed to write data to file, (errno: %d).", GetErrorMessage(r), errno);
314 _NormalFile::Flush(void)
316 result r = E_SUCCESS;
318 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
320 // fflush() returns '0' even if file was opened in read only mode!
321 if (fflush(__pFile) != 0)
323 r = __ConvertNativeErrorToResult(errno);
324 SysLogException(NID_IO, r, "[%s] Failed to flush data to file. errno(%d)", GetErrorMessage(r), errno);
331 _NormalFile::Tell(void) const
333 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
334 result r = E_SUCCESS;
336 int ret = ftell(__pFile);
339 r = __ConvertNativeErrorToResult(errno);
340 SysLogException(NID_IO, r, "[%s] Failed to flush data to file", GetErrorMessage(r));
348 _NormalFile::Seek(FileSeekPosition position, long offset)
350 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
352 result r = E_SUCCESS;
354 int whence = FILESEEKPOSITION_CURRENT;
357 case FILESEEKPOSITION_BEGIN:
361 case FILESEEKPOSITION_CURRENT:
365 case FILESEEKPOSITION_END:
369 SysTryReturnResult(NID_IO, false, E_INVALID_ARG, "Seek position is invalid.");
372 int ret = fseek(__pFile, offset, whence);
375 r = __ConvertNativeErrorToResult(errno);
376 SysLogException(NID_IO, r, "[%s] Failed to seek in file", GetErrorMessage(r));
383 _NormalFile::Truncate(int length)
385 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
386 result r = E_SUCCESS;
388 int ret = ftruncate(fileno(__pFile), (off_t)length);
391 r = __ConvertNativeErrorToResult(errno);
392 SysLogException(NID_IO, r, "[%s] Failed to truncate file. errno(%d)", GetErrorMessage(r), errno);
399 _NormalFile::GetName(void)
401 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
403 SetLastResult(E_SUCCESS); // for OSP 2.0 compatibility