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

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

#1 add typical data structure algorithms (linked-list / queue / stak) and rename symbol for context of each modules

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