1 /*         ______   ___    ___
2  *        /\  _  \ /\_ \  /\_ \
3  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
4  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
5  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
6  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7  *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8  *                                           /\____/
9  *                                           \_/__/
10  *
11  *      File System Hooks.
12  *
13  *      By Thomas Fjellstrom.
14  *
15  *      See readme.txt for copyright information.
16  */
17 
18 /* Title: Filesystem routines
19 */
20 
21 #include "allegro5/allegro.h"
22 #include "allegro5/internal/aintern_fshook.h"
23 
24 
25 
26 /* Function: al_create_fs_entry
27  */
al_create_fs_entry(const char * path)28 ALLEGRO_FS_ENTRY *al_create_fs_entry(const char *path)
29 {
30    const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface();
31    ASSERT(vt->fs_create_entry);
32    return vt->fs_create_entry(path);
33 }
34 
35 
36 /* Function: al_destroy_fs_entry
37  */
al_destroy_fs_entry(ALLEGRO_FS_ENTRY * fh)38 void al_destroy_fs_entry(ALLEGRO_FS_ENTRY *fh)
39 {
40    if (fh) {
41       fh->vtable->fs_destroy_entry(fh);
42    }
43 }
44 
45 
46 /* Function: al_get_fs_entry_name
47  */
al_get_fs_entry_name(ALLEGRO_FS_ENTRY * e)48 const char *al_get_fs_entry_name(ALLEGRO_FS_ENTRY *e)
49 {
50    ASSERT(e != NULL);
51 
52    return e->vtable->fs_entry_name(e);
53 }
54 
55 
56 /* Function: al_update_fs_entry
57  */
al_update_fs_entry(ALLEGRO_FS_ENTRY * e)58 bool al_update_fs_entry(ALLEGRO_FS_ENTRY *e)
59 {
60    ASSERT(e != NULL);
61 
62    return e->vtable->fs_update_entry(e);
63 }
64 
65 
66 /* Function: al_get_fs_entry_mode
67  */
al_get_fs_entry_mode(ALLEGRO_FS_ENTRY * e)68 uint32_t al_get_fs_entry_mode(ALLEGRO_FS_ENTRY *e)
69 {
70    ASSERT(e != NULL);
71 
72    return e->vtable->fs_entry_mode(e);
73 }
74 
75 
76 /* Function: al_get_fs_entry_atime
77  */
al_get_fs_entry_atime(ALLEGRO_FS_ENTRY * e)78 time_t al_get_fs_entry_atime(ALLEGRO_FS_ENTRY *e)
79 {
80    ASSERT(e != NULL);
81 
82    return e->vtable->fs_entry_atime(e);
83 }
84 
85 
86 /* Function: al_get_fs_entry_mtime
87  */
al_get_fs_entry_mtime(ALLEGRO_FS_ENTRY * e)88 time_t al_get_fs_entry_mtime(ALLEGRO_FS_ENTRY *e)
89 {
90    ASSERT(e != NULL);
91 
92    return e->vtable->fs_entry_mtime(e);
93 }
94 
95 
96 /* Function: al_get_fs_entry_ctime
97  */
al_get_fs_entry_ctime(ALLEGRO_FS_ENTRY * e)98 time_t al_get_fs_entry_ctime(ALLEGRO_FS_ENTRY *e)
99 {
100    ASSERT(e != NULL);
101 
102    return e->vtable->fs_entry_ctime(e);
103 }
104 
105 
106 /* Function: al_get_fs_entry_size
107  */
al_get_fs_entry_size(ALLEGRO_FS_ENTRY * e)108 off_t al_get_fs_entry_size(ALLEGRO_FS_ENTRY *e)
109 {
110    ASSERT(e != NULL);
111 
112    return e->vtable->fs_entry_size(e);
113 }
114 
115 
116 /* Function: al_remove_fs_entry
117  */
al_remove_fs_entry(ALLEGRO_FS_ENTRY * e)118 bool al_remove_fs_entry(ALLEGRO_FS_ENTRY *e)
119 {
120    ASSERT(e != NULL);
121 
122    return e->vtable->fs_remove_entry(e);
123 }
124 
125 
126 /* Function: al_fs_entry_exists
127  */
al_fs_entry_exists(ALLEGRO_FS_ENTRY * e)128 bool al_fs_entry_exists(ALLEGRO_FS_ENTRY *e)
129 {
130    ASSERT(e != NULL);
131 
132    return e->vtable->fs_entry_exists(e);
133 }
134 
135 
136 /* Function: al_open_directory
137  */
al_open_directory(ALLEGRO_FS_ENTRY * e)138 bool al_open_directory(ALLEGRO_FS_ENTRY *e)
139 {
140    ASSERT(e != NULL);
141 
142    return e->vtable->fs_open_directory(e);
143 }
144 
145 
146 /* Function: al_close_directory
147  */
al_close_directory(ALLEGRO_FS_ENTRY * e)148 bool al_close_directory(ALLEGRO_FS_ENTRY *e)
149 {
150    ASSERT(e != NULL);
151 
152    return e->vtable->fs_close_directory(e);
153 }
154 
155 
156 /* Function: al_read_directory
157  */
al_read_directory(ALLEGRO_FS_ENTRY * e)158 ALLEGRO_FS_ENTRY *al_read_directory(ALLEGRO_FS_ENTRY *e)
159 {
160    ASSERT(e != NULL);
161 
162    return e->vtable->fs_read_directory(e);
163 }
164 
165 
166 /* Function: al_get_current_directory
167  */
al_get_current_directory(void)168 char *al_get_current_directory(void)
169 {
170    const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface();
171    ASSERT(vt->fs_get_current_directory);
172    return vt->fs_get_current_directory();
173 }
174 
175 
176 /* Function: al_change_directory
177  */
al_change_directory(const char * path)178 bool al_change_directory(const char *path)
179 {
180    const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface();
181    ASSERT(vt->fs_change_directory);
182    ASSERT(path);
183 
184    return vt->fs_change_directory(path);
185 }
186 
187 
188 /* Function: al_make_directory
189  */
al_make_directory(const char * path)190 bool al_make_directory(const char *path)
191 {
192    const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface();
193    ASSERT(path);
194    ASSERT(vt->fs_make_directory);
195 
196    return vt->fs_make_directory(path);
197 }
198 
199 
200 /* Function: al_filename_exists
201  */
al_filename_exists(const char * path)202 bool al_filename_exists(const char *path)
203 {
204    const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface();
205    ASSERT(path != NULL);
206    ASSERT(vt->fs_filename_exists);
207 
208    return vt->fs_filename_exists(path);
209 }
210 
211 
212 /* Function: al_remove_filename
213  */
al_remove_filename(const char * path)214 bool al_remove_filename(const char *path)
215 {
216    const ALLEGRO_FS_INTERFACE *vt = al_get_fs_interface();
217    ASSERT(vt->fs_remove_filename);
218    ASSERT(path != NULL);
219 
220    return vt->fs_remove_filename(path);
221 }
222 
223 
224 /* Function: al_open_fs_entry
225  */
al_open_fs_entry(ALLEGRO_FS_ENTRY * e,const char * mode)226 ALLEGRO_FILE *al_open_fs_entry(ALLEGRO_FS_ENTRY *e, const char *mode)
227 {
228    ASSERT(e != NULL);
229 
230    if (e->vtable->fs_open_file)
231       return e->vtable->fs_open_file(e, mode);
232 
233    al_set_errno(EINVAL);
234    return NULL;
235 }
236 
237 
238 /* Utility functions for iterating over a directory using callbacks. */
239 
240 /* Function: al_for_each_fs_entry
241  */
al_for_each_fs_entry(ALLEGRO_FS_ENTRY * dir,int (* callback)(ALLEGRO_FS_ENTRY * dir,void * extra),void * extra)242 int al_for_each_fs_entry(ALLEGRO_FS_ENTRY *dir,
243                          int (*callback)(ALLEGRO_FS_ENTRY *dir, void *extra),
244                          void *extra)
245 {
246    ALLEGRO_FS_ENTRY *entry;
247 
248    if (!dir || !al_open_directory(dir)) {
249       al_set_errno(ENOENT);
250       return ALLEGRO_FOR_EACH_FS_ENTRY_ERROR;
251    }
252 
253    for (entry = al_read_directory(dir); entry; entry = al_read_directory(dir)) {
254       /* Call the callback first. */
255       int result = callback(entry, extra);
256 
257       /* Recurse if requested and needed. Only OK allows recursion. */
258       if (result == ALLEGRO_FOR_EACH_FS_ENTRY_OK) {
259          if (al_get_fs_entry_mode(entry) & ALLEGRO_FILEMODE_ISDIR) {
260             result = al_for_each_fs_entry(entry, callback, extra);
261          }
262       }
263 
264       al_destroy_fs_entry(entry);
265 
266       if ((result == ALLEGRO_FOR_EACH_FS_ENTRY_STOP) ||
267          (result == ALLEGRO_FOR_EACH_FS_ENTRY_ERROR)) {
268          return result;
269       }
270    }
271 
272    return ALLEGRO_FOR_EACH_FS_ENTRY_OK;
273 }
274 
275 
276 
277 
278 /*
279  * Local Variables:
280  * c-basic-offset: 3
281  * indent-tabs-mode: nil
282  * End:
283  */
284 /* vim: set sts=3 sw=3 et: */
285