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