2 * Standard directory I/O support routines for PhysicsFS.
4 * Please see the file LICENSE.txt in the source's root directory.
6 * This file written by Ryan C. Gordon.
14 #define __PHYSICSFS_INTERNAL__
15 #include "physfs_internal.h"
17 static PHYSFS_sint64 DIR_read(fvoid *opaque, void *buffer,
18 PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
21 retval = __PHYSFS_platformRead(opaque, buffer, objSize, objCount);
26 static PHYSFS_sint64 DIR_write(fvoid *opaque, const void *buffer,
27 PHYSFS_uint32 objSize, PHYSFS_uint32 objCount)
30 retval = __PHYSFS_platformWrite(opaque, buffer, objSize, objCount);
35 static int DIR_eof(fvoid *opaque)
37 return(__PHYSFS_platformEOF(opaque));
41 static PHYSFS_sint64 DIR_tell(fvoid *opaque)
43 return(__PHYSFS_platformTell(opaque));
47 static int DIR_seek(fvoid *opaque, PHYSFS_uint64 offset)
49 return(__PHYSFS_platformSeek(opaque, offset));
53 static PHYSFS_sint64 DIR_fileLength(fvoid *opaque)
55 return(__PHYSFS_platformFileLength(opaque));
56 } /* DIR_fileLength */
59 static int DIR_fileClose(fvoid *opaque)
62 * we manually flush the buffer, since that's the place a close will
63 * most likely fail, but that will leave the file handle in an undefined
64 * state if it fails. Flush failures we can recover from.
66 BAIL_IF_MACRO(!__PHYSFS_platformFlush(opaque), NULL, 0);
67 BAIL_IF_MACRO(!__PHYSFS_platformClose(opaque), NULL, 0);
72 static int DIR_isArchive(const char *filename, int forWriting)
74 /* directories ARE archives in this driver... */
75 return(__PHYSFS_platformIsDirectory(filename));
79 static void *DIR_openArchive(const char *name, int forWriting)
81 const char *dirsep = PHYSFS_getDirSeparator();
83 size_t namelen = strlen(name);
84 size_t seplen = strlen(dirsep);
86 /* !!! FIXME: when is this not called right before openArchive? */
87 BAIL_IF_MACRO(!DIR_isArchive(name, forWriting),
88 ERR_UNSUPPORTED_ARCHIVE, 0);
90 retval = allocator.Malloc(namelen + seplen + 1);
91 BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
93 /* make sure there's a dir separator at the end of the string */
95 if (strcmp((name + namelen) - seplen, dirsep) != 0)
96 strcat(retval, dirsep);
99 } /* DIR_openArchive */
102 static void DIR_enumerateFiles(dvoid *opaque, const char *dname,
103 int omitSymLinks, PHYSFS_EnumFilesCallback cb,
104 const char *origdir, void *callbackdata)
106 char *d = __PHYSFS_platformCvtToDependent((char *)opaque, dname, NULL);
109 __PHYSFS_platformEnumerateFiles(d, omitSymLinks, cb,
110 origdir, callbackdata);
113 } /* DIR_enumerateFiles */
116 static int DIR_exists(dvoid *opaque, const char *name)
118 char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
121 BAIL_IF_MACRO(f == NULL, NULL, 0);
122 retval = __PHYSFS_platformExists(f);
128 static int DIR_isDirectory(dvoid *opaque, const char *name, int *fileExists)
130 char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
133 BAIL_IF_MACRO(d == NULL, NULL, 0);
134 *fileExists = __PHYSFS_platformExists(d);
136 retval = __PHYSFS_platformIsDirectory(d);
139 } /* DIR_isDirectory */
142 static int DIR_isSymLink(dvoid *opaque, const char *name, int *fileExists)
144 char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
147 BAIL_IF_MACRO(f == NULL, NULL, 0);
148 *fileExists = __PHYSFS_platformExists(f);
150 retval = __PHYSFS_platformIsSymLink(f);
153 } /* DIR_isSymLink */
156 static PHYSFS_sint64 DIR_getLastModTime(dvoid *opaque,
160 char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
161 PHYSFS_sint64 retval = -1;
163 BAIL_IF_MACRO(d == NULL, NULL, 0);
164 *fileExists = __PHYSFS_platformExists(d);
166 retval = __PHYSFS_platformGetLastModTime(d);
169 } /* DIR_getLastModTime */
172 static fvoid *doOpen(dvoid *opaque, const char *name,
173 void *(*openFunc)(const char *filename),
176 char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
179 BAIL_IF_MACRO(f == NULL, NULL, NULL);
181 if (fileExists != NULL)
183 *fileExists = __PHYSFS_platformExists(f);
194 return((fvoid *) rc);
198 static fvoid *DIR_openRead(dvoid *opaque, const char *fnm, int *exist)
200 return(doOpen(opaque, fnm, __PHYSFS_platformOpenRead, exist));
204 static fvoid *DIR_openWrite(dvoid *opaque, const char *filename)
206 return(doOpen(opaque, filename, __PHYSFS_platformOpenWrite, NULL));
207 } /* DIR_openWrite */
210 static fvoid *DIR_openAppend(dvoid *opaque, const char *filename)
212 return(doOpen(opaque, filename, __PHYSFS_platformOpenAppend, NULL));
213 } /* DIR_openAppend */
216 static int DIR_remove(dvoid *opaque, const char *name)
218 char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
221 BAIL_IF_MACRO(f == NULL, NULL, 0);
222 retval = __PHYSFS_platformDelete(f);
228 static int DIR_mkdir(dvoid *opaque, const char *name)
230 char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL);
233 BAIL_IF_MACRO(f == NULL, NULL, 0);
234 retval = __PHYSFS_platformMkDir(f);
240 static void DIR_dirClose(dvoid *opaque)
242 allocator.Free(opaque);
247 const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_DIR =
250 DIR_ARCHIVE_DESCRIPTION,
251 "Ryan C. Gordon <icculus@icculus.org>",
252 "http://icculus.org/physfs/",
257 const PHYSFS_Archiver __PHYSFS_Archiver_DIR =
259 &__PHYSFS_ArchiveInfo_DIR,
260 DIR_isArchive, /* isArchive() method */
261 DIR_openArchive, /* openArchive() method */
262 DIR_enumerateFiles, /* enumerateFiles() method */
263 DIR_exists, /* exists() method */
264 DIR_isDirectory, /* isDirectory() method */
265 DIR_isSymLink, /* isSymLink() method */
266 DIR_getLastModTime, /* getLastModTime() method */
267 DIR_openRead, /* openRead() method */
268 DIR_openWrite, /* openWrite() method */
269 DIR_openAppend, /* openAppend() method */
270 DIR_remove, /* remove() method */
271 DIR_mkdir, /* mkdir() method */
272 DIR_dirClose, /* dirClose() method */
273 DIR_read, /* read() method */
274 DIR_write, /* write() method */
275 DIR_eof, /* eof() method */
276 DIR_tell, /* tell() method */
277 DIR_seek, /* seek() method */
278 DIR_fileLength, /* fileLength() method */
279 DIR_fileClose /* fileClose() method */
282 /* end of dir.c ... */