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