2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FIo_NormalFile.cpp
20 * @brief This is the implementation file for _NormalFile class.
27 #include <sys/types.h>
34 #include <unique_ptr.h>
37 #include <FIoDirectory.h>
38 #include <FBaseResult.h>
39 #include <FBaseSysLog.h>
41 #include <FBase_StringConverter.h>
42 #include <FBase_NativeError.h>
43 #include <FIo_FileAttributesImpl.h>
44 #include <FIo_NormalFile.h>
47 using namespace Tizen::Base;
49 namespace Tizen { namespace Io
52 static const int _MAX_LINE_LENGTH = 4096;
54 #define _MAX_OPENMODE_LENGTH 3
56 _NormalFile::_NormalFile(void)
61 _NormalFile::~_NormalFile(void)
67 if (fclose(__pFile) != 0)
69 r = __ConvertNativeErrorToResult(errno);
70 SysLog(NID_IO, "[%s] Failed to close the file.", GetErrorMessage(r));
77 _NormalFile::Construct(const String& filePath, const char* pOpenMode)
79 SysAssertf(__pFile == NULL, "Already constructed. Calling Construct() twice or more on a same instance is not allowed for this class\n");
84 unique_ptr<char[]> pFilePath(_StringConverter::CopyToCharArrayN(filePath));
85 SysTryReturn(NID_IO, (pFilePath != null), GetLastResult(), GetLastResult(), ("[%s] Invalid file path."),
86 GetErrorMessage(GetLastResult()));
88 FILE* pFile = fopen(pFilePath.get(), pOpenMode);
91 r = __ConvertNativeErrorToResult(errno);
92 SysLogException(NID_IO, r, "[%s] Failed to open file (%s) in openMode (%s), errno: %d (%s).",
93 GetErrorMessage(r), pFilePath.get(), pOpenMode, errno, strerror(errno));
100 __filePath = filePath;
106 _NormalFile::ReadN(char** buffer, int& length)
108 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
109 result r = E_SUCCESS;
111 int ret = fseek(__pFile, 0, SEEK_END);
112 SysTryReturnResult(NID_IO, ret >= 0, E_SYSTEM, "The system I/O error occurred.");
114 long fileSize = ftell(__pFile);
115 SysTryReturnResult(NID_IO, fileSize >= 0, E_SYSTEM, "The system I/O error occurred.");
117 SysLog(NID_IO, "The length of registry file (%ls) is %ld.", __filePath.GetPointer(), fileSize);
123 ret = fseek(__pFile, 0, SEEK_SET); // moves file offset to zero because of a+ open mode.
124 SysTryReturnResult(NID_IO, ret >= 0, E_SYSTEM, "The system I/O error occurred.");
126 unique_ptr<char[]> pBuffer(new (std::nothrow) char[fileSize + 1]);
127 SysTryReturnResult(NID_IO, pBuffer != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
128 memset(pBuffer.get(), 0x00, fileSize + 1);
130 int readBytes = fread((void*)pBuffer.get(), 1, (size_t)fileSize, __pFile);
131 SysTryCatch(NID_IO, readBytes > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to read registry file (%d, %s).",
132 errno, strerror(errno));
134 length = readBytes + 1;
135 *buffer = pBuffer.release();
149 _NormalFile::Read(ByteBuffer& buffer)
151 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
153 result r = E_SUCCESS;
155 int length = buffer.GetRemaining();
158 return E_INVALID_ARG;
161 int curPos = buffer.GetPosition();
162 int bytesRead = fread((void*) (buffer.GetPointer() + curPos), 1, length, __pFile);
163 if (bytesRead < length)
165 SysTryReturnResult(NID_IO, !(bytesRead == 0 && feof(__pFile)), E_END_OF_FILE, "end of file");
169 r = __ConvertNativeErrorToResult(errno);
170 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for reading!");
171 SysLogException(NID_IO, r, "[%s] Failed to read data from file, (errno: %d)", GetErrorMessage(r), errno);
176 buffer.SetPosition(curPos + bytesRead);
182 _NormalFile::Read(void* buffer, int length)
184 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
186 result r = E_SUCCESS;
188 int readBytes = fread(buffer, 1, length, __pFile);
189 if (readBytes < length)
191 //SysTryReturn(NID_IO, !(readBytes == 0 && feof(__pFile)), 0, E_END_OF_FILE, "[E_END_OF_FILE] end of file");
192 if (readBytes == 0 && feof(__pFile))
194 SysLog(NID_IO, "[E_END_OF_FILE] end of file");
195 SetLastResult(E_END_OF_FILE);
201 r = __ConvertNativeErrorToResult(errno);
202 SysTryReturn(NID_IO, !(r == E_INVALID_OPERATION), 0, E_ILLEGAL_ACCESS,
203 "[E_ILLEGAL_ACCESS] File was not opened for reading!");
204 SysLogException(NID_IO, r, "[%s] Failed to read data from file", GetErrorMessage(r));
209 SetLastResult(E_SUCCESS);
214 _NormalFile::Read(String& buffer)
216 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
218 char line[_MAX_LINE_LENGTH] = {0, };
219 result r = E_SUCCESS;
222 if (fgets(line, _MAX_LINE_LENGTH - 1, __pFile) == null)
224 SysTryReturnResult(NID_IO, !feof(__pFile), E_END_OF_FILE, "end of file");
228 r = __ConvertNativeErrorToResult(errno);
229 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, " File was not opened for reading!");
230 SysLogException(NID_IO, r, "[%s] Failed to read data from file", GetErrorMessage(r));
235 buffer = String(line);
242 _NormalFile::Write(const ByteBuffer& buffer)
244 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
246 result r = E_SUCCESS;
248 int length = buffer.GetLimit();
251 return E_INVALID_ARG;
254 int bytesWritten = fwrite(buffer.GetPointer(), 1, length, __pFile);
255 if (bytesWritten < length)
259 r = __ConvertNativeErrorToResult(errno);
260 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for writing!");
261 SysLogException(NID_IO, r, "[%s] Failed to write data to file, (errno: %d).", GetErrorMessage(r), errno);
269 _NormalFile::Write(const void* buffer, int length)
271 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
272 SysTryReturnResult(NID_IO, length > 0, E_INVALID_ARG, "length cannot be 0!");
274 result r = E_SUCCESS;
276 if ((size_t) length > fwrite(buffer, 1, length, __pFile))
280 r = __ConvertNativeErrorToResult(errno);
281 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for writing!");
282 SysLogException(NID_IO, r, "[%s] Failed to write data to file, (errno: %d).", GetErrorMessage(r), errno);
290 _NormalFile::Write(const String& buffer)
292 result r = E_SUCCESS;
294 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
295 SysTryReturnResult(NID_IO, buffer.GetLength() > 0, E_INVALID_ARG, "Buffer length cannot be 0!");
297 unique_ptr<char[]> pData(_StringConverter::CopyToCharArrayN(buffer));
298 SysTryReturn(NID_IO, (pData != null), GetLastResult(), GetLastResult(), ("[%s] Invalid file path."),
299 GetErrorMessage(GetLastResult()));
301 if (fputs(pData.get(), __pFile) <= 0)
305 r = __ConvertNativeErrorToResult(errno);
306 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for writing!");
307 SysLogException(NID_IO, r, "[%s] Failed to write data to file, (errno: %d).", GetErrorMessage(r), errno);
315 _NormalFile::Flush(void)
317 result r = E_SUCCESS;
319 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
321 // fflush() returns '0' even if file was opened in read only mode!
322 if (fflush(__pFile) != 0)
324 r = __ConvertNativeErrorToResult(errno);
325 SysLogException(NID_IO, r, "[%s] Failed to flush data to file. errno(%d)", GetErrorMessage(r), errno);
332 _NormalFile::Tell(void) const
334 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
335 result r = E_SUCCESS;
337 int ret = ftell(__pFile);
340 r = __ConvertNativeErrorToResult(errno);
341 SysLogException(NID_IO, r, "[%s] Failed to flush data to file", GetErrorMessage(r));
349 _NormalFile::Seek(FileSeekPosition position, long offset)
351 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
353 result r = E_SUCCESS;
355 int whence = FILESEEKPOSITION_CURRENT;
358 case FILESEEKPOSITION_BEGIN:
362 case FILESEEKPOSITION_CURRENT:
366 case FILESEEKPOSITION_END:
370 SysTryReturnResult(NID_IO, false, E_INVALID_ARG, "Seek position is invalid.");
373 int ret = fseek(__pFile, offset, whence);
376 r = __ConvertNativeErrorToResult(errno);
377 SysLogException(NID_IO, r, "[%s] Failed to seek in file", GetErrorMessage(r));
384 _NormalFile::Truncate(int length)
386 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
387 result r = E_SUCCESS;
389 int ret = ftruncate(fileno(__pFile), (off_t)length);
392 r = __ConvertNativeErrorToResult(errno);
393 SysLogException(NID_IO, r, "[%s] Failed to truncate file. errno(%d)", GetErrorMessage(r), errno);
400 _NormalFile::GetName(void)
402 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
404 SetLastResult(E_SUCCESS); // for OSP 2.0 compatibility