source: libcf/trunk/src/cf_file.c@ 128

Last change on this file since 128 was 128, checked in by cheese, 11 years ago

#1 add bitwise util from ARIA of chevalier

File size: 5.1 KB
RevLine 
[4]1/**
[128]2 * \file cf_file.c
[117]3 *
[128]4 * \author myusgun <myusgun@gmail.com>
5 *
[119]6 * \brief 파일 입출력 구현
[4]7 */
8#include "cf_file.h"
[66]9#include "cf_local.h"
[40]10#include "cf_error.h"
[4]11
[41]12#include <stdio.h>
[90]13#include <fcntl.h>
[41]14#include <errno.h>
15#include <sys/stat.h>
16
[50]17#if defined(_WIN32) || defined(_WIN64)
[4]18# include <io.h>
[55]19# include <direct.h>
[14]20
[41]21# define DELIMITER '\\'
22# define mkdir(a,b) _mkdir (a)
23# define access(a,b) _access (a,b)
24
[43]25# define F_OK 0
26# define W_OK 2
27# define R_OK 4
28
[41]29/*------------------------------*/
[14]30# define S_IWUSR _S_IWRITE
31# define S_IRUSR _S_IREAD
32# define S_IXUSR _S_IEXEC
[41]33/*------------------------------*/
[14]34# define S_IRGRP 0x00000000
35# define S_IWGRP 0x00000000
36# define S_IXGRP 0x00000000
[41]37/*------------------------------*/
[14]38# define S_IROTH 0x00000000
39# define S_IWOTH 0x00000000
40# define S_IXOTH 0x00000000
[41]41/*------------------------------*/
42# define S_IRWXU 0x00000000
[50]43#else // #if defined(_WIN32) || defined(_WIN64)
[4]44# include <unistd.h>
[41]45
46# define DELIMITER '/'
[26]47# define O_BINARY 0x00000000
[50]48#endif // #if defined(_WIN32) || defined(_WIN64)
[4]49
[41]50#define DIRECTORY_MODE S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH
51#define FILE_MODE S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH
[15]52
[85]53#define ASSERT_ARGS(x) \
54 if ((x)) \
[55]55 return CF_ERROR_FILE_INVALID_ARGS
56
[90]57static int
58CF_File_Local_ConvertFlag (const CF_FILE_FLAG flag)
59{
60 int result = 0;
61
62 if (flag & CF_FILE_READ) result |= O_RDONLY;
63 if (flag & CF_FILE_WRITE) result |= O_WRONLY;
64 if (flag & CF_FILE_RW) result |= O_RDWR;
65 if (flag & CF_FILE_CREATE) result |= O_CREAT;
66 if (flag & CF_FILE_TRUNC) result |= O_TRUNC;
67 if (flag & CF_FILE_APPEND) result |= O_APPEND;
68
69 return result;
70}
71
[35]72/**
73 * 파일 열기
74 *
[119]75 * \return 성공 시, 파일 디스크립터; 실패 시, 오류 코드
[35]76 *
[119]77 * \param path 파일 경로
78 * \param flag 파일 열기 플래그
[35]79 *
[119]80 * \see CF_FILE_FLAG
[35]81 */
[4]82int
[16]83CF_File_Open (const char * path,
84 const CF_FILE_FLAG flag)
[4]85{
[55]86 int result = 0;
[93]87 int osflag = 0;
[4]88
[55]89 ASSERT_ARGS (path == NULL);
90
[93]91 osflag = CF_File_Local_ConvertFlag (flag) | O_BINARY;
92
93 result = open (path, osflag, FILE_MODE);
[4]94 if (result < 0)
95 return CF_ERROR_FILE_OPEN;
96
97 return result;
98}
99
[35]100/**
101 * 파일 생성
102 *
[119]103 * \return 성공 시, 파일 디스크립터; 실패 시, 오류 코드
[35]104 *
[119]105 * \param path 파일 경로
[35]106 */
[4]107int
108CF_File_Create (const char * path)
109{
[93]110 int result = 0;
111 const int flag = CF_FILE_CREATE|CF_FILE_WRITE|CF_FILE_TRUNC;
[55]112
113 ASSERT_ARGS (path == NULL);
[4]114
[93]115 result = CF_File_Open (path, flag);
[4]116 if (result < 0)
117 return CF_ERROR_FILE_CREATE;
118
119 return result;
120}
121
[35]122/**
123 * 파일 닫기
124 *
[119]125 * \return 성공 시, CF_OK; 실패 시, 오류 코드
[35]126 *
[119]127 * \param fd 파일 디스크립터
[35]128 */
[4]129int
130CF_File_Close (const int fd)
131{
132 int result = 0;
133
[55]134 ASSERT_ARGS (fd < 0);
[4]135
136 result = close (fd);
137 if (result < 0)
138 return CF_ERROR_FILE_CLOSE;
139
140 return CF_OK;
141}
142
[35]143/**
144 * 파일 읽기
145 *
[119]146 * \return 성공 시, 읽은 바이트 수; 실패 시, 오류 코드
[35]147 *
[119]148 * \param fd 파일 디스크립터
149 * \param buf 데이터를 저장할 메모리
150 * \param len 데이터를 저장할 메모리의 크기
[35]151 */
[4]152int
153CF_File_Read (const int fd,
154 void * buf,
155 const size_t len)
156{
[55]157 int result = 0;
158
159 ASSERT_ARGS (fd < 0);
160 ASSERT_ARGS (buf == NULL);
[4]161
[55]162 result = (int) read (fd, buf, len);
[4]163 if (result < 0)
164 return CF_ERROR_FILE_READ;
165
[26]166 return result;
[4]167}
168
[35]169/**
170 * 파일 쓰기
171 *
[119]172 * \return 성공 시, CF_OK; 실패 시, 오류 코드
[35]173 *
[119]174 * \param fd 파일 디스크립터
175 * \param buf 데이터가 저장된 메모리
176 * \param len 쓸 데이터의 길이
[35]177 */
[4]178int
179CF_File_Write (const int fd,
180 const void * buf,
181 const size_t len)
182{
[55]183 int result = 0;
184
185 ASSERT_ARGS (fd < 0);
186 ASSERT_ARGS (buf == NULL);
[4]187
[58]188 result = (int) write (fd, buf, len);
[4]189 if (result != len)
190 return CF_ERROR_FILE_WRITE;
191
192 return CF_OK;
193}
194
[35]195/**
196 * 파일 크기 얻기
197 *
[119]198 * \return 성공 시, 파일 크기; 실패 시, 오류 코드
[35]199 *
[119]200 * \param path 파일 경로
[35]201 */
[4]202int
[94]203CF_File_GetSize (const char * path)
[4]204{
[94]205 int length = 0;
206 int fd = 0;
[4]207
[94]208 ASSERT_ARGS (path == NULL);
[55]209
[94]210 fd = CF_File_Open (path, CF_FILE_READ);
211 if (fd < 0)
212 return CF_ERROR_FILE_OPEN;
213
214 length = (int) lseek (fd, 0, SEEK_END);
215 if (length < 0)
[4]216 return CF_ERROR_FILE_GET_SIZE;
217
[94]218 CF_File_Close (fd);
219
220 return length;
[4]221}
[41]222
223/**
[109]224 * 파일 및 디렉터리 존재 여부 검사
225 *
[119]226 * \return 존재 시, CF_TRUE; 아니면, CF_FALSE
[109]227 *
[119]228 * \param path 파일 및 디렉터리 경로
[109]229 */
230CF_BOOL
231CF_File_Exists (const char * path)
232{
233 return (access (path, F_OK) == 0) ? CF_TRUE : CF_FALSE;
234}
235
236/**
[41]237 * 디렉터리 생성
238 *
[119]239 * \return 성공 시, CF_OK; 실패 시, 오류 코드
[41]240 *
[119]241 * \param path 생성할 디렉터리 경로
[41]242 */
243int
244CF_File_MakeDirectory (const char * path)
245{
246 int result = 0;
247 char fullPath[1024] = {0x00,};
248 char stepPath[256] = {0x00,};
249
250 char * f = fullPath;
251 char * d = stepPath;
252
[55]253 ASSERT_ARGS (path == NULL);
254
[46]255 snprintf (fullPath, sizeof (fullPath) - 1, "%s%c", path, DELIMITER);
[41]256
257 for (*d++ = *f++ ; *f ; *d++ = *f++)
258 {
259 if (*f != DELIMITER)
260 continue;
261
[109]262 if (CF_File_Exists (stepPath))
[41]263 continue;
264
265 result = mkdir (stepPath, DIRECTORY_MODE);
266 if (result && errno != EEXIST)
267 return CF_ERROR_FILE_MAKE_DIRECTORY;
268 }
269
270 return CF_OK;
271}
Note: See TracBrowser for help on using the repository browser.