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 _NormalFile::_NormalFile(void)
58 _NormalFile::~_NormalFile(void)
64 if (fclose(__pFile) != 0)
66 r = __ConvertNativeErrorToResult(errno);
67 SysLog(NID_IO, "[%s] Failed to close the file.", GetErrorMessage(r));
74 _NormalFile::Construct(const String& filePath, const char* pOpenMode)
76 SysAssertf(__pFile == NULL, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class\n");
81 unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
82 SysTryReturn(NID_IO, (pFilePath != null), GetLastResult(), GetLastResult(), ("[%s] Invalid file path."),
83 GetErrorMessage(GetLastResult()));
85 FILE* pFile = fopen(pFilePath.get(), pOpenMode);
88 r = __ConvertNativeErrorToResult(errno);
89 SysSecureLogException(NID_IO, r, "[%s] Failed to open file (%s) in openMode (%s), errno: %d (%s).",
90 GetErrorMessage(r), pFilePath.get(), pOpenMode, errno, strerror(errno));
97 __filePath = filePath;
103 _NormalFile::ReadN(char** buffer, int& length)
105 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
106 result r = E_SUCCESS;
108 int ret = fseek(__pFile, 0, SEEK_END);
109 SysTryReturnResult(NID_IO, ret >= 0, E_SYSTEM, "The system I/O error occurred.");
111 long fileSize = ftell(__pFile);
112 SysTryReturnResult(NID_IO, fileSize >= 0, E_SYSTEM, "The system I/O error occurred.");
114 SysSecureLog(NID_IO, "The length of registry file (%ls) is %ld.", __filePath.GetPointer(), fileSize);
120 ret = fseek(__pFile, 0, SEEK_SET); // moves file offset to zero because of a+ open mode.
121 SysTryReturnResult(NID_IO, ret >= 0, E_SYSTEM, "The system I/O error occurred.");
123 unique_ptr<char[]> pBuffer(new (std::nothrow) char[fileSize + 1]);
124 SysTryReturnResult(NID_IO, pBuffer != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
125 memset(pBuffer.get(), 0x00, fileSize + 1);
127 int readBytes = fread((void*)pBuffer.get(), 1, (size_t)fileSize, __pFile);
128 SysTryCatch(NID_IO, readBytes > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to read registry file (%d, %s).",
129 errno, strerror(errno));
131 length = readBytes + 1;
132 *buffer = pBuffer.release();
146 _NormalFile::Read(ByteBuffer& buffer)
148 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
150 result r = E_SUCCESS;
152 int length = buffer.GetRemaining();
155 return E_INVALID_ARG;
158 int curPos = buffer.GetPosition();
159 int bytesRead = fread((void*) (buffer.GetPointer() + curPos), 1, length, __pFile);
160 if (bytesRead < length)
162 SysTryReturnResult(NID_IO, !(bytesRead == 0 && feof(__pFile)), E_END_OF_FILE, "end of file");
166 r = __ConvertNativeErrorToResult(errno);
167 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for reading!");
168 SysLogException(NID_IO, r, "[%s] Failed to read data from file, (errno: %d)", GetErrorMessage(r), errno);
173 buffer.SetPosition(curPos + bytesRead);
179 _NormalFile::Read(void* buffer, int length)
181 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
183 result r = E_SUCCESS;
185 int readBytes = fread(buffer, 1, length, __pFile);
186 if (readBytes < length)
188 //SysTryReturn(NID_IO, !(readBytes == 0 && feof(__pFile)), 0, E_END_OF_FILE, "[E_END_OF_FILE] end of file");
189 if (readBytes == 0 && feof(__pFile))
191 SysLog(NID_IO, "[E_END_OF_FILE] end of file");
192 SetLastResult(E_END_OF_FILE);
198 r = __ConvertNativeErrorToResult(errno);
199 SysTryReturn(NID_IO, !(r == E_INVALID_OPERATION), 0, E_ILLEGAL_ACCESS,
200 "[E_ILLEGAL_ACCESS] File was not opened for reading!");
201 SysLogException(NID_IO, r, "[%s] Failed to read data from file", GetErrorMessage(r));
206 SetLastResult(E_SUCCESS);
211 _NormalFile::Read(String& buffer)
213 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
215 char line[_MAX_LINE_LENGTH] = {0, };
216 result r = E_SUCCESS;
219 if (fgets(line, _MAX_LINE_LENGTH - 1, __pFile) == null)
221 SysTryReturnResult(NID_IO, !feof(__pFile), E_END_OF_FILE, "end of file");
225 r = __ConvertNativeErrorToResult(errno);
226 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, " File was not opened for reading!");
227 SysLogException(NID_IO, r, "[%s] Failed to read data from file", GetErrorMessage(r));
232 buffer = String(line);
239 _NormalFile::Write(const ByteBuffer& buffer)
241 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
243 result r = E_SUCCESS;
245 int length = buffer.GetLimit();
248 return E_INVALID_ARG;
251 int bytesWritten = fwrite(buffer.GetPointer(), 1, length, __pFile);
252 if (bytesWritten < length)
256 r = __ConvertNativeErrorToResult(errno);
257 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for writing!");
258 SysLogException(NID_IO, r, "[%s] Failed to write data to file, (errno: %d).", GetErrorMessage(r), errno);
266 _NormalFile::Write(const void* buffer, int length)
268 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
269 SysTryReturnResult(NID_IO, length > 0, E_INVALID_ARG, "length cannot be 0!");
271 result r = E_SUCCESS;
273 if ((size_t) length > fwrite(buffer, 1, length, __pFile))
277 r = __ConvertNativeErrorToResult(errno);
278 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for writing!");
279 SysLogException(NID_IO, r, "[%s] Failed to write data to file, (errno: %d).", GetErrorMessage(r), errno);
287 _NormalFile::Write(const String& buffer)
289 result r = E_SUCCESS;
291 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
292 SysTryReturnResult(NID_IO, buffer.GetLength() > 0, E_INVALID_ARG, "Buffer length cannot be 0!");
294 unique_ptr<char[]> pData(_StringConverter::CopyToCharArrayN(buffer));
295 SysTryReturn(NID_IO, (pData != null), GetLastResult(), GetLastResult(), ("[%s] Invalid file path."),
296 GetErrorMessage(GetLastResult()));
298 if (fputs(pData.get(), __pFile) <= 0)
302 r = __ConvertNativeErrorToResult(errno);
303 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for writing!");
304 SysLogException(NID_IO, r, "[%s] Failed to write data to file, (errno: %d).", GetErrorMessage(r), errno);
312 _NormalFile::Flush(void)
314 result r = E_SUCCESS;
316 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
318 // fflush() returns '0' even if file was opened in read only mode!
319 if (fflush(__pFile) != 0)
321 r = __ConvertNativeErrorToResult(errno);
322 SysLogException(NID_IO, r, "[%s] Failed to flush data to file. errno(%d)", GetErrorMessage(r), errno);
329 _NormalFile::Tell(void) const
331 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
332 result r = E_SUCCESS;
334 int ret = ftell(__pFile);
337 r = __ConvertNativeErrorToResult(errno);
338 SysLogException(NID_IO, r, "[%s] Failed to flush data to file", GetErrorMessage(r));
346 _NormalFile::Seek(FileSeekPosition position, long offset)
348 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
350 result r = E_SUCCESS;
352 int whence = FILESEEKPOSITION_CURRENT;
355 case FILESEEKPOSITION_BEGIN:
359 case FILESEEKPOSITION_CURRENT:
363 case FILESEEKPOSITION_END:
367 SysTryReturnResult(NID_IO, false, E_INVALID_ARG, "Seek position is invalid.");
370 int ret = fseek(__pFile, offset, whence);
373 r = __ConvertNativeErrorToResult(errno);
374 SysLogException(NID_IO, r, "[%s] Failed to seek in file", GetErrorMessage(r));
381 _NormalFile::Truncate(int length)
383 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
384 result r = E_SUCCESS;
386 int ret = ftruncate(fileno(__pFile), (off_t)length);
389 r = __ConvertNativeErrorToResult(errno);
390 SysLogException(NID_IO, r, "[%s] Failed to truncate file. errno(%d)", GetErrorMessage(r), errno);
397 _NormalFile::GetName(void)
399 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
401 SetLastResult(E_SUCCESS); // for OSP 2.0 compatibility