X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=archivers%2Fdir.c;fp=archivers%2Fdir.c;h=a5807434babd744e2d2a1e24c59e54626149ae8a;hb=1a2e54b98aaab3669eebd38facb83687c4ac7baf;hp=0000000000000000000000000000000000000000;hpb=0b9bdac28929054558b5d7f315403fe3399a1413;p=physicsfs diff --git a/archivers/dir.c b/archivers/dir.c new file mode 100644 index 0000000..a580743 --- /dev/null +++ b/archivers/dir.c @@ -0,0 +1,283 @@ +/* + * Standard directory I/O support routines for PhysicsFS. + * + * Please see the file LICENSE.txt in the source's root directory. + * + * This file written by Ryan C. Gordon. + */ + +#include +#include +#include +#include "physfs.h" + +#define __PHYSICSFS_INTERNAL__ +#include "physfs_internal.h" + +static PHYSFS_sint64 DIR_read(fvoid *opaque, void *buffer, + PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) +{ + PHYSFS_sint64 retval; + retval = __PHYSFS_platformRead(opaque, buffer, objSize, objCount); + return(retval); +} /* DIR_read */ + + +static PHYSFS_sint64 DIR_write(fvoid *opaque, const void *buffer, + PHYSFS_uint32 objSize, PHYSFS_uint32 objCount) +{ + PHYSFS_sint64 retval; + retval = __PHYSFS_platformWrite(opaque, buffer, objSize, objCount); + return(retval); +} /* DIR_write */ + + +static int DIR_eof(fvoid *opaque) +{ + return(__PHYSFS_platformEOF(opaque)); +} /* DIR_eof */ + + +static PHYSFS_sint64 DIR_tell(fvoid *opaque) +{ + return(__PHYSFS_platformTell(opaque)); +} /* DIR_tell */ + + +static int DIR_seek(fvoid *opaque, PHYSFS_uint64 offset) +{ + return(__PHYSFS_platformSeek(opaque, offset)); +} /* DIR_seek */ + + +static PHYSFS_sint64 DIR_fileLength(fvoid *opaque) +{ + return(__PHYSFS_platformFileLength(opaque)); +} /* DIR_fileLength */ + + +static int DIR_fileClose(fvoid *opaque) +{ + /* + * we manually flush the buffer, since that's the place a close will + * most likely fail, but that will leave the file handle in an undefined + * state if it fails. Flush failures we can recover from. + */ + BAIL_IF_MACRO(!__PHYSFS_platformFlush(opaque), NULL, 0); + BAIL_IF_MACRO(!__PHYSFS_platformClose(opaque), NULL, 0); + return(1); +} /* DIR_fileClose */ + + +static int DIR_isArchive(const char *filename, int forWriting) +{ + /* directories ARE archives in this driver... */ + return(__PHYSFS_platformIsDirectory(filename)); +} /* DIR_isArchive */ + + +static void *DIR_openArchive(const char *name, int forWriting) +{ + const char *dirsep = PHYSFS_getDirSeparator(); + char *retval = NULL; + size_t namelen = strlen(name); + size_t seplen = strlen(dirsep); + + /* !!! FIXME: when is this not called right before openArchive? */ + BAIL_IF_MACRO(!DIR_isArchive(name, forWriting), + ERR_UNSUPPORTED_ARCHIVE, 0); + + retval = allocator.Malloc(namelen + seplen + 1); + BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); + + /* make sure there's a dir separator at the end of the string */ + strcpy(retval, name); + if (strcmp((name + namelen) - seplen, dirsep) != 0) + strcat(retval, dirsep); + + return(retval); +} /* DIR_openArchive */ + + +static void DIR_enumerateFiles(dvoid *opaque, const char *dname, + int omitSymLinks, PHYSFS_EnumFilesCallback cb, + const char *origdir, void *callbackdata) +{ + char *d = __PHYSFS_platformCvtToDependent((char *)opaque, dname, NULL); + if (d != NULL) + { + __PHYSFS_platformEnumerateFiles(d, omitSymLinks, cb, + origdir, callbackdata); + allocator.Free(d); + } /* if */ +} /* DIR_enumerateFiles */ + + +static int DIR_exists(dvoid *opaque, const char *name) +{ + char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL); + int retval; + + BAIL_IF_MACRO(f == NULL, NULL, 0); + retval = __PHYSFS_platformExists(f); + allocator.Free(f); + return(retval); +} /* DIR_exists */ + + +static int DIR_isDirectory(dvoid *opaque, const char *name, int *fileExists) +{ + char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL); + int retval = 0; + + BAIL_IF_MACRO(d == NULL, NULL, 0); + *fileExists = __PHYSFS_platformExists(d); + if (*fileExists) + retval = __PHYSFS_platformIsDirectory(d); + allocator.Free(d); + return(retval); +} /* DIR_isDirectory */ + + +static int DIR_isSymLink(dvoid *opaque, const char *name, int *fileExists) +{ + char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL); + int retval = 0; + + BAIL_IF_MACRO(f == NULL, NULL, 0); + *fileExists = __PHYSFS_platformExists(f); + if (*fileExists) + retval = __PHYSFS_platformIsSymLink(f); + allocator.Free(f); + return(retval); +} /* DIR_isSymLink */ + + +static PHYSFS_sint64 DIR_getLastModTime(dvoid *opaque, + const char *name, + int *fileExists) +{ + char *d = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL); + PHYSFS_sint64 retval = -1; + + BAIL_IF_MACRO(d == NULL, NULL, 0); + *fileExists = __PHYSFS_platformExists(d); + if (*fileExists) + retval = __PHYSFS_platformGetLastModTime(d); + allocator.Free(d); + return(retval); +} /* DIR_getLastModTime */ + + +static fvoid *doOpen(dvoid *opaque, const char *name, + void *(*openFunc)(const char *filename), + int *fileExists) +{ + char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL); + void *rc = NULL; + + BAIL_IF_MACRO(f == NULL, NULL, NULL); + + if (fileExists != NULL) + { + *fileExists = __PHYSFS_platformExists(f); + if (!(*fileExists)) + { + allocator.Free(f); + return(NULL); + } /* if */ + } /* if */ + + rc = openFunc(f); + allocator.Free(f); + + return((fvoid *) rc); +} /* doOpen */ + + +static fvoid *DIR_openRead(dvoid *opaque, const char *fnm, int *exist) +{ + return(doOpen(opaque, fnm, __PHYSFS_platformOpenRead, exist)); +} /* DIR_openRead */ + + +static fvoid *DIR_openWrite(dvoid *opaque, const char *filename) +{ + return(doOpen(opaque, filename, __PHYSFS_platformOpenWrite, NULL)); +} /* DIR_openWrite */ + + +static fvoid *DIR_openAppend(dvoid *opaque, const char *filename) +{ + return(doOpen(opaque, filename, __PHYSFS_platformOpenAppend, NULL)); +} /* DIR_openAppend */ + + +static int DIR_remove(dvoid *opaque, const char *name) +{ + char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL); + int retval; + + BAIL_IF_MACRO(f == NULL, NULL, 0); + retval = __PHYSFS_platformDelete(f); + allocator.Free(f); + return(retval); +} /* DIR_remove */ + + +static int DIR_mkdir(dvoid *opaque, const char *name) +{ + char *f = __PHYSFS_platformCvtToDependent((char *) opaque, name, NULL); + int retval; + + BAIL_IF_MACRO(f == NULL, NULL, 0); + retval = __PHYSFS_platformMkDir(f); + allocator.Free(f); + return(retval); +} /* DIR_mkdir */ + + +static void DIR_dirClose(dvoid *opaque) +{ + allocator.Free(opaque); +} /* DIR_dirClose */ + + + +const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_DIR = +{ + "", + DIR_ARCHIVE_DESCRIPTION, + "Ryan C. Gordon ", + "http://icculus.org/physfs/", +}; + + + +const PHYSFS_Archiver __PHYSFS_Archiver_DIR = +{ + &__PHYSFS_ArchiveInfo_DIR, + DIR_isArchive, /* isArchive() method */ + DIR_openArchive, /* openArchive() method */ + DIR_enumerateFiles, /* enumerateFiles() method */ + DIR_exists, /* exists() method */ + DIR_isDirectory, /* isDirectory() method */ + DIR_isSymLink, /* isSymLink() method */ + DIR_getLastModTime, /* getLastModTime() method */ + DIR_openRead, /* openRead() method */ + DIR_openWrite, /* openWrite() method */ + DIR_openAppend, /* openAppend() method */ + DIR_remove, /* remove() method */ + DIR_mkdir, /* mkdir() method */ + DIR_dirClose, /* dirClose() method */ + DIR_read, /* read() method */ + DIR_write, /* write() method */ + DIR_eof, /* eof() method */ + DIR_tell, /* tell() method */ + DIR_seek, /* seek() method */ + DIR_fileLength, /* fileLength() method */ + DIR_fileClose /* fileClose() method */ +}; + +/* end of dir.c ... */ +