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");
110 result r = E_SUCCESS;
114 ret = fseek(__pFile, 0, SEEK_END);
115 SysTryReturnResult(NID_IO, ret >= 0, E_SYSTEM, "The system I/O error occurred.");
117 fileSize = ftell(__pFile);
118 SysTryReturnResult(NID_IO, fileSize >= 0, E_SYSTEM, "The system I/O error occurred.");
120 SysLog(NID_IO, "The length of registry file (%ls) is %d.", __filePath.GetPointer(), fileSize);
126 ret = fseek(__pFile, 0, SEEK_SET); // moves file offset to zero because of a+ open mode.
127 SysTryReturnResult(NID_IO, ret >= 0, E_SYSTEM, "The system I/O error occurred.");
129 unique_ptr<char[]> pBuffer(new (std::nothrow) char[fileSize + 1]);
130 SysTryReturnResult(NID_IO, pBuffer != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
131 memset(pBuffer.get(), 0x00, fileSize + 1);
133 int readBytes = fread((void*)pBuffer.get(), 1, fileSize, __pFile);
134 SysTryCatch(NID_IO, readBytes > 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to read registry file (%d, %s).",
135 errno, strerror(errno));
137 length = readBytes + 1;
138 *buffer = pBuffer.release();
152 _NormalFile::Read(ByteBuffer& buffer)
154 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
156 result r = E_SUCCESS;
158 int length = buffer.GetRemaining();
161 return E_INVALID_ARG;
164 int curPos = buffer.GetPosition();
165 int bytesRead = fread((void*) (buffer.GetPointer() + curPos), 1, length, __pFile);
166 if (bytesRead < length)
168 SysTryReturnResult(NID_IO, !(bytesRead == 0 && feof(__pFile)), E_END_OF_FILE, "end of file");
172 r = __ConvertNativeErrorToResult(errno);
173 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for reading!");
174 SysLogException(NID_IO, r, "[%s] Failed to read data from file, (errno: %d)", GetErrorMessage(r), errno);
179 buffer.SetPosition(curPos + bytesRead);
185 _NormalFile::Read(void* buffer, int length)
187 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
189 result r = E_SUCCESS;
191 int readBytes = fread(buffer, 1, length, __pFile);
192 if (readBytes < length)
194 //SysTryReturn(NID_IO, !(readBytes == 0 && feof(__pFile)), 0, E_END_OF_FILE, "[E_END_OF_FILE] end of file");
195 if (readBytes == 0 && feof(__pFile))
197 SysLog(NID_IO, "[E_END_OF_FILE] end of file");
198 SetLastResult(E_END_OF_FILE);
204 r = __ConvertNativeErrorToResult(errno);
205 SysTryReturn(NID_IO, !(r == E_INVALID_OPERATION), 0, E_ILLEGAL_ACCESS,
206 "[E_ILLEGAL_ACCESS] File was not opened for reading!");
207 SysLogException(NID_IO, r, "[%s] Failed to read data from file", GetErrorMessage(r));
212 SetLastResult(E_SUCCESS);
217 _NormalFile::Read(String& buffer)
219 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
221 char line[_MAX_LINE_LENGTH] = {0, };
222 result r = E_SUCCESS;
225 if (fgets(line, _MAX_LINE_LENGTH - 1, __pFile) == null)
227 SysTryReturnResult(NID_IO, !feof(__pFile), E_END_OF_FILE, "end of file");
231 r = __ConvertNativeErrorToResult(errno);
232 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, " File was not opened for reading!");
233 SysLogException(NID_IO, r, "[%s] Failed to read data from file", GetErrorMessage(r));
238 buffer = String(line);
245 _NormalFile::Write(const ByteBuffer& buffer)
247 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
249 result r = E_SUCCESS;
251 int length = buffer.GetLimit();
254 return E_INVALID_ARG;
257 int bytesWritten = fwrite(buffer.GetPointer(), 1, length, __pFile);
258 if (bytesWritten < length)
262 r = __ConvertNativeErrorToResult(errno);
263 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for writing!");
264 SysLogException(NID_IO, r, "[%s] Failed to write data to file, (errno: %d).", GetErrorMessage(r), errno);
272 _NormalFile::Write(const void* buffer, int length)
274 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
275 SysTryReturnResult(NID_IO, length > 0, E_INVALID_ARG, "length cannot be 0!");
277 result r = E_SUCCESS;
279 if ((size_t) length > fwrite(buffer, 1, length, __pFile))
283 r = __ConvertNativeErrorToResult(errno);
284 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for writing!");
285 SysLogException(NID_IO, r, "[%s] Failed to write data to file, (errno: %d).", GetErrorMessage(r), errno);
293 _NormalFile::Write(const String& buffer)
295 result r = E_SUCCESS;
297 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
298 SysTryReturnResult(NID_IO, buffer.GetLength() > 0, E_INVALID_ARG, "Buffer length cannot be 0!");
300 unique_ptr<char[]> pData(_StringConverter::CopyToCharArrayN(buffer));
301 SysTryReturn(NID_IO, (pData != null), GetLastResult(), GetLastResult(), ("[%s] Invalid file path."),
302 GetErrorMessage(GetLastResult()));
304 if (fputs(pData.get(), __pFile) <= 0)
308 r = __ConvertNativeErrorToResult(errno);
309 SysTryReturnResult(NID_IO, !(r == E_INVALID_OPERATION), E_ILLEGAL_ACCESS, "File was not opened for writing!");
310 SysLogException(NID_IO, r, "[%s] Failed to write data to file, (errno: %d).", GetErrorMessage(r), errno);
318 _NormalFile::Flush(void)
320 result r = E_SUCCESS;
322 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
324 // fflush() returns '0' even if file was opened in read only mode!
325 if (fflush(__pFile) != 0)
327 r = __ConvertNativeErrorToResult(errno);
328 SysLogException(NID_IO, r, "[%s] Failed to flush data to file. errno(%d)", GetErrorMessage(r), errno);
335 _NormalFile::Tell(void) const
337 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
338 result r = E_SUCCESS;
340 int ret = ftell(__pFile);
343 r = __ConvertNativeErrorToResult(errno);
344 SysLogException(NID_IO, r, "[%s] Failed to flush data to file", GetErrorMessage(r));
352 _NormalFile::Seek(FileSeekPosition position, long offset)
354 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
356 result r = E_SUCCESS;
358 int whence = FILESEEKPOSITION_CURRENT;
361 case FILESEEKPOSITION_BEGIN:
365 case FILESEEKPOSITION_CURRENT:
369 case FILESEEKPOSITION_END:
373 SysTryReturnResult(NID_IO, false, E_INVALID_ARG, "Seek position is invalid.");
376 int ret = fseek(__pFile, offset, whence);
379 r = __ConvertNativeErrorToResult(errno);
380 SysLogException(NID_IO, r, "[%s] Failed to seek in file", GetErrorMessage(r));
387 _NormalFile::Truncate(int length)
389 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
390 result r = E_SUCCESS;
392 int ret = ftruncate(fileno(__pFile), (off_t) length);
395 r = __ConvertNativeErrorToResult(errno);
396 SysLogException(NID_IO, r, "[%s] Failed to truncate file. errno(%d)", GetErrorMessage(r), errno);
403 _NormalFile::GetName(void)
405 SysAssertf(__pFile != NULL, "Not yet constructed. Construct() should be called before use.\n");
407 SetLastResult(E_SUCCESS); // for OSP 2.0 compatibility