Mercurial > projects > hoofbaby
comparison deps/Platinum/ThirdParty/Neptune/Source/System/Posix/NptPosixFile.cpp @ 0:3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
author | fraserofthenight |
---|---|
date | Mon, 06 Jul 2009 08:06:28 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3425707ddbf6 |
---|---|
1 /***************************************************************** | |
2 | | |
3 | Neptune - File :: Posix Implementation | |
4 | | |
5 | (c) 2001-2008 Gilles Boccon-Gibod | |
6 | Author: Gilles Boccon-Gibod (bok@bok.net) | |
7 | | |
8 ****************************************************************/ | |
9 | |
10 /*---------------------------------------------------------------------- | |
11 | includes | |
12 +---------------------------------------------------------------------*/ | |
13 #define _LARGEFILE_SOURCE | |
14 #define _LARGEFILE_SOURCE64 | |
15 #define _FILE_OFFSET_BITS 64 | |
16 | |
17 #include <sys/stat.h> | |
18 | |
19 #include <errno.h> | |
20 | |
21 #if defined(_WIN32) | |
22 #include <direct.h> | |
23 #include <stdlib.h> | |
24 #include <stdio.h> | |
25 #else | |
26 #include <unistd.h> | |
27 #include <dirent.h> | |
28 #endif | |
29 | |
30 #include "NptLogging.h" | |
31 #include "NptFile.h" | |
32 #include "NptUtils.h" | |
33 | |
34 /*---------------------------------------------------------------------- | |
35 | logging | |
36 +---------------------------------------------------------------------*/ | |
37 //NPT_SET_LOCAL_LOGGER("neptune.posix.file") | |
38 | |
39 /*---------------------------------------------------------------------- | |
40 | Win32 adaptation | |
41 +---------------------------------------------------------------------*/ | |
42 #if defined(_WIN32) || defined(_XBOX) | |
43 extern int NPT_stat_utf8(const char* path, NPT_stat_struct* info); | |
44 extern char* NPT_getcwd_utf8(char* path, unsigned int path_size); | |
45 #define getcwd NPT_getcwd_utf8 | |
46 #define S_ISDIR(_m) (((_m)&_S_IFMT) == _S_IFDIR) | |
47 #define S_ISREG(_m) (((_m)&_S_IFMT) == _S_IFREG) | |
48 #define S_IWUSR _S_IWRITE | |
49 #endif | |
50 | |
51 /*---------------------------------------------------------------------- | |
52 | MapErrno | |
53 +---------------------------------------------------------------------*/ | |
54 static NPT_Result | |
55 MapErrno(int err) { | |
56 switch (err) { | |
57 case EACCES: return NPT_ERROR_PERMISSION_DENIED; | |
58 case EPERM: return NPT_ERROR_PERMISSION_DENIED; | |
59 case ENOENT: return NPT_ERROR_NO_SUCH_FILE; | |
60 case ENAMETOOLONG: return NPT_ERROR_INVALID_PARAMETERS; | |
61 case EBUSY: return NPT_ERROR_FILE_BUSY; | |
62 case EROFS: return NPT_ERROR_FILE_NOT_WRITABLE; | |
63 case ENOTDIR: return NPT_ERROR_FILE_NOT_DIRECTORY; | |
64 case EEXIST: return NPT_ERROR_FILE_ALREADY_EXISTS; | |
65 case ENOSPC: return NPT_ERROR_FILE_NOT_ENOUGH_SPACE; | |
66 case ENOTEMPTY: return NPT_ERROR_DIRECTORY_NOT_EMPTY; | |
67 default: return NPT_ERROR_ERRNO(err); | |
68 } | |
69 } | |
70 | |
71 #if !defined(_WIN32) | |
72 /*---------------------------------------------------------------------- | |
73 | NPT_FilePath::Separator | |
74 +---------------------------------------------------------------------*/ | |
75 const NPT_String NPT_FilePath::Separator("/"); | |
76 | |
77 /*---------------------------------------------------------------------- | |
78 | NPT_File::GetRoots | |
79 +---------------------------------------------------------------------*/ | |
80 NPT_Result | |
81 NPT_File::GetRoots(NPT_List<NPT_String>& roots) | |
82 { | |
83 roots.Clear(); | |
84 roots.Add("/"); | |
85 return NPT_SUCCESS; | |
86 } | |
87 | |
88 /*---------------------------------------------------------------------- | |
89 | NPT_File::CreateDirectory | |
90 +---------------------------------------------------------------------*/ | |
91 NPT_Result | |
92 NPT_File::CreateDirectory(const char* path) | |
93 { | |
94 int result; | |
95 | |
96 result = mkdir(path, 0755); | |
97 if (result != 0) { | |
98 return MapErrno(errno); | |
99 } | |
100 | |
101 return NPT_SUCCESS; | |
102 } | |
103 | |
104 /*---------------------------------------------------------------------- | |
105 | NPT_File::DeleteFile | |
106 +---------------------------------------------------------------------*/ | |
107 NPT_Result | |
108 NPT_File::DeleteFile(const char* path) | |
109 { | |
110 int result = unlink(path); | |
111 if (result != 0) return MapErrno(errno); | |
112 | |
113 return NPT_SUCCESS; | |
114 } | |
115 | |
116 /*---------------------------------------------------------------------- | |
117 | NPT_File::DeleteDirectory | |
118 +---------------------------------------------------------------------*/ | |
119 NPT_Result | |
120 NPT_File::DeleteDirectory(const char* path) | |
121 { | |
122 int result = rmdir(path); | |
123 if (result != 0) return MapErrno(errno); | |
124 | |
125 return NPT_SUCCESS; | |
126 } | |
127 | |
128 /*---------------------------------------------------------------------- | |
129 | NPT_File::Rename | |
130 +---------------------------------------------------------------------*/ | |
131 NPT_Result | |
132 NPT_File::Rename(const char* from_path, const char* to_path) | |
133 { | |
134 int result = rename(from_path, to_path); | |
135 if (result != 0) return MapErrno(errno); | |
136 | |
137 return NPT_SUCCESS; | |
138 } | |
139 | |
140 /*---------------------------------------------------------------------- | |
141 | NPT_File::ListDirectory | |
142 +---------------------------------------------------------------------*/ | |
143 NPT_Result | |
144 NPT_File::ListDirectory(const char* path, | |
145 NPT_List<NPT_String>& entries, | |
146 NPT_Ordinal start /* = 0 */, | |
147 NPT_Cardinal max /* = 0 */) | |
148 { | |
149 // default return value | |
150 entries.Clear(); | |
151 | |
152 // check the arguments | |
153 if (path == NULL) return NPT_ERROR_INVALID_PARAMETERS; | |
154 | |
155 // list the entries | |
156 DIR *directory = opendir(path); | |
157 if (directory == NULL) return NPT_ERROR_OUT_OF_MEMORY; | |
158 | |
159 NPT_Cardinal count = 0; | |
160 for (;;) { | |
161 struct dirent* entry_pointer = NULL; | |
162 #if defined(NPT_CONFIG_HAVE_READDIR_R) | |
163 struct dirent entry; | |
164 int result = readdir_r(directory, &entry, &entry_pointer); | |
165 if (result != 0 || entry_pointer == NULL) break; | |
166 #else | |
167 entry_pointer = readdir(directory); | |
168 if (entry_pointer == NULL) break; | |
169 #endif | |
170 // ignore odd names | |
171 if (entry_pointer->d_name[0] == '\0') continue; | |
172 | |
173 // ignore . and .. | |
174 if (entry_pointer->d_name[0] == '.' && | |
175 entry_pointer->d_name[1] == '\0') { | |
176 continue; | |
177 } | |
178 if (entry_pointer->d_name[0] == '.' && | |
179 entry_pointer->d_name[1] == '.' && | |
180 entry_pointer->d_name[2] == '\0') { | |
181 continue; | |
182 } | |
183 | |
184 // continue if not yet first item requested | |
185 if (start > 0) { | |
186 --start; | |
187 continue; | |
188 } | |
189 entries.Add(NPT_String(entry_pointer->d_name)); | |
190 | |
191 // stop when reaching maximum requested | |
192 if (max && ++count == max) break; | |
193 } | |
194 | |
195 closedir(directory); | |
196 | |
197 return NPT_SUCCESS; | |
198 } | |
199 #endif | |
200 | |
201 /*---------------------------------------------------------------------- | |
202 | NPT_File::GetWorkingDirectory | |
203 +---------------------------------------------------------------------*/ | |
204 NPT_Result | |
205 NPT_File::GetWorkingDirectory(NPT_String& path) | |
206 { | |
207 char buffer[1024+1]; | |
208 char* dir = getcwd(buffer, 1024+1); | |
209 if (dir == NULL) return MapErrno(errno); | |
210 path = dir; | |
211 | |
212 return NPT_SUCCESS; | |
213 } | |
214 | |
215 /*---------------------------------------------------------------------- | |
216 | NPT_File::GetInfo | |
217 +---------------------------------------------------------------------*/ | |
218 NPT_Result | |
219 NPT_File::GetInfo(const char* path, NPT_FileInfo* info) | |
220 { | |
221 // default value | |
222 if (info) NPT_SetMemory(info, 0, sizeof(*info)); | |
223 | |
224 // On Windows, stat will fail if a dir ends with a separator | |
225 NPT_String _path = path; | |
226 _path.TrimRight("\\/"); | |
227 if (NPT_StringLength(path) == 2 && path[1] == ':') { | |
228 _path += NPT_FilePath::Separator; | |
229 } | |
230 | |
231 // get the file info | |
232 NPT_stat_struct stat_buffer; | |
233 int result = NPT_stat(_path, &stat_buffer); | |
234 if (result != 0) return MapErrno(errno); | |
235 | |
236 // setup the returned fields | |
237 if (info) { | |
238 info->m_Size = stat_buffer.st_size; | |
239 if (S_ISREG(stat_buffer.st_mode)) { | |
240 info->m_Type = NPT_FileInfo::FILE_TYPE_REGULAR; | |
241 } else if (S_ISDIR(stat_buffer.st_mode)) { | |
242 info->m_Type = NPT_FileInfo::FILE_TYPE_DIRECTORY; | |
243 } else { | |
244 info->m_Type = NPT_FileInfo::FILE_TYPE_OTHER; | |
245 } | |
246 info->m_AttributesMask &= NPT_FILE_ATTRIBUTE_READ_ONLY; | |
247 if ((stat_buffer.st_mode & S_IWUSR) == 0) { | |
248 info->m_Attributes &= NPT_FILE_ATTRIBUTE_READ_ONLY; | |
249 } | |
250 } | |
251 | |
252 return NPT_SUCCESS; | |
253 } |