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

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

#1 more fix and arrange doxygen comments

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