Progress toward complete implementation continues...
This commit is contained in:
parent
b7db28940e
commit
c97f88fc33
4
Makefile
4
Makefile
|
@ -173,7 +173,7 @@ $(BINDIR)/%.o: $(SRCDIR)/%.c
|
||||||
$(BINDIR)/%.o: $(SRCDIR)/%.asm
|
$(BINDIR)/%.o: $(SRCDIR)/%.asm
|
||||||
$(ASM) $(ASMFLAGS) -o $@ $<
|
$(ASM) $(ASMFLAGS) -o $@ $<
|
||||||
|
|
||||||
.PHONY: all clean listobjs
|
.PHONY: all clean distclean listobjs
|
||||||
|
|
||||||
all: $(BINDIR) $(MAINLIB)
|
all: $(BINDIR) $(MAINLIB)
|
||||||
|
|
||||||
|
@ -183,6 +183,8 @@ $(MAINLIB) : $(BINDIR) $(MAINOBJS)
|
||||||
$(BINDIR):
|
$(BINDIR):
|
||||||
mkdir -p $(BINDIR)
|
mkdir -p $(BINDIR)
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(CLEANUP)
|
rm -f $(CLEANUP)
|
||||||
rm -rf $(BINDIR)
|
rm -rf $(BINDIR)
|
||||||
|
|
24
dir.c
24
dir.c
|
@ -12,11 +12,8 @@
|
||||||
#define __PHYSICSFS_INTERNAL__
|
#define __PHYSICSFS_INTERNAL__
|
||||||
#include "physfs_internal.h"
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
/* template for filehandles. */
|
static const FileFunctions __PHYSFS_FileHandle_DIR =
|
||||||
const FileHandle __PHYSFS_FileHandle_DIR =
|
|
||||||
{
|
{
|
||||||
NULL, /* opaque */
|
|
||||||
NULL, /* dirReader */
|
|
||||||
DIR_read, /* read() method */
|
DIR_read, /* read() method */
|
||||||
NULL, /* write() method */
|
NULL, /* write() method */
|
||||||
DIR_eof, /* eof() method */
|
DIR_eof, /* eof() method */
|
||||||
|
@ -25,15 +22,28 @@ const FileHandle __PHYSFS_FileHandle_DIR =
|
||||||
DIR_close, /* close() method */
|
DIR_close, /* close() method */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* template for directories. */
|
|
||||||
const DirReader __PHYSFS_DirReader_DIR =
|
static const FileFunctions __PHYSFS_FileHandle_DIRW =
|
||||||
{
|
{
|
||||||
NULL, /* opaque */
|
NULL, /* read() method */
|
||||||
|
DIR_write, /* write() method */
|
||||||
|
DIR_eof, /* eof() method */
|
||||||
|
DIR_tell, /* tell() method */
|
||||||
|
DIR_seek, /* seek() method */
|
||||||
|
DIR_close, /* close() method */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const DirFunctions __PHYSFS_DirFunctions_DIR =
|
||||||
|
{
|
||||||
|
DIR_isArchive, /* isArchive() method */
|
||||||
|
DIR_openArchive, /* openArchive() method */
|
||||||
DIR_enumerate, /* enumerateFiles() method */
|
DIR_enumerate, /* enumerateFiles() method */
|
||||||
DIR_isDirectory, /* isDirectory() method */
|
DIR_isDirectory, /* isDirectory() method */
|
||||||
DIR_isSymLink, /* isSymLink() method */
|
DIR_isSymLink, /* isSymLink() method */
|
||||||
DIR_isOpenable, /* isOpenable() method */
|
DIR_isOpenable, /* isOpenable() method */
|
||||||
DIR_openRead, /* openRead() method */
|
DIR_openRead, /* openRead() method */
|
||||||
|
DIR_openWrite, /* openWrite() method */
|
||||||
DIR_dirClose, /* close() method */
|
DIR_dirClose, /* close() method */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
307
physfs.c
307
physfs.c
|
@ -25,7 +25,6 @@ typedef struct __PHYSFS_ERRMSGTYPE__
|
||||||
struct __PHYSFS_ERRMSGTYPE__ *next;
|
struct __PHYSFS_ERRMSGTYPE__ *next;
|
||||||
} ErrMsg;
|
} ErrMsg;
|
||||||
|
|
||||||
|
|
||||||
typedef struct __PHYSFS_SEARCHDIRINFO__
|
typedef struct __PHYSFS_SEARCHDIRINFO__
|
||||||
{
|
{
|
||||||
char *dirName;
|
char *dirName;
|
||||||
|
@ -33,22 +32,23 @@ typedef struct __PHYSFS_SEARCHDIRINFO__
|
||||||
struct __PHYSFS_SEARCHDIRINFO__ *next;
|
struct __PHYSFS_SEARCHDIRINFO__ *next;
|
||||||
} SearchDirInfo;
|
} SearchDirInfo;
|
||||||
|
|
||||||
|
typedef struct __PHYSFS_FILEHANDLELIST__
|
||||||
|
{
|
||||||
|
FileHandle *handle;
|
||||||
|
struct __PHYSFS_FILEHANDLELIST__ *next;
|
||||||
|
} FileHandleList;
|
||||||
|
|
||||||
static int initialized = 0;
|
|
||||||
static ErrMsg *errorMessages = NULL;
|
/* The various i/o drivers... */
|
||||||
static char *searchPath = NULL;
|
|
||||||
static char *baseDir = NULL;
|
|
||||||
static char *writeDir = NULL;
|
|
||||||
static int allowSymLinks = 0;
|
|
||||||
|
|
||||||
#if (defined PHYSFS_SUPPORTS_ZIP)
|
#if (defined PHYSFS_SUPPORTS_ZIP)
|
||||||
extern const __PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP;
|
extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP;
|
||||||
extern const __PHYSFS_DirReader __PHYSFS_DirReader_ZIP;
|
extern const DirFunctions __PHYSFS_DirFunctions_ZIP;
|
||||||
extern const __PHYSFS_FileHandle __PHYSFS_FileHandle_ZIP;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern const DirFunctions __PHYSFS_DirFunctions_DIR;
|
||||||
|
|
||||||
static const __PHYSFS_ArchiveInfo *supported_types[] =
|
static const PHYSFS_ArchiveInfo *supported_types[] =
|
||||||
{
|
{
|
||||||
#if (defined PHYSFS_SUPPORTS_ZIP)
|
#if (defined PHYSFS_SUPPORTS_ZIP)
|
||||||
&__PHYSFS_ArchiveInfo_ZIP,
|
&__PHYSFS_ArchiveInfo_ZIP,
|
||||||
|
@ -57,9 +57,34 @@ static const __PHYSFS_ArchiveInfo *supported_types[] =
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const DirFunctions *dirFunctions[] =
|
||||||
|
{
|
||||||
|
#if (defined PHYSFS_SUPPORTS_ZIP)
|
||||||
|
&__PHYSFS_DirFunctions_ZIP,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
&__PHYSFS_DirFunctions_DIR,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* General PhysicsFS state ... */
|
||||||
|
|
||||||
|
static int initialized = 0;
|
||||||
|
static ErrMsg *errorMessages = NULL;
|
||||||
|
static SearchDirInfo *searchPath = NULL;
|
||||||
|
static FileHandleList *openWriteList = NULL;
|
||||||
|
static FileHandleList *openReadList = NULL;
|
||||||
|
static char *baseDir = NULL;
|
||||||
|
static char *userDir = NULL;
|
||||||
|
static char *writeDir = NULL;
|
||||||
|
static int allowSymLinks = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* functions ... */
|
||||||
|
|
||||||
static ErrMsg *findErrorForCurrentThread(void)
|
static ErrMsg *findErrorForCurrentThread(void)
|
||||||
{
|
{
|
||||||
ErrMsg *i;
|
ErrMsg *i;
|
||||||
|
@ -124,12 +149,53 @@ void PHYSFS_getLinkedVersion(PHYSFS_Version *ver)
|
||||||
} /* PHYSFS_getLinkedVersion */
|
} /* PHYSFS_getLinkedVersion */
|
||||||
|
|
||||||
|
|
||||||
|
static const char *calculateUserDir(void)
|
||||||
|
{
|
||||||
|
char *retval = NULL;
|
||||||
|
const char *str = NULL;
|
||||||
|
|
||||||
|
str = __PHYSFS_platformGetUserDir();
|
||||||
|
if (str != NULL)
|
||||||
|
retval = str;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char *dirsep = PHYSFS_getDirSeparator();
|
||||||
|
const char *uname = __PHYSFS_platformGetUserName();
|
||||||
|
|
||||||
|
str = (uname != NULL) ? uname : "default";
|
||||||
|
retval = malloc(strlen(baseDir) + strlen(str) +
|
||||||
|
(strlen(dirsep) * 2) + 6);
|
||||||
|
|
||||||
|
if (retval == NULL)
|
||||||
|
__PHYSFS_setError(ERR_OUT_OF_MEMORY);
|
||||||
|
else
|
||||||
|
sprintf(retval, "%s%susers%s%s", baseDir, dirsep, dirsep, str);
|
||||||
|
|
||||||
|
if (uname != NULL)
|
||||||
|
free(uname);
|
||||||
|
} /* else */
|
||||||
|
|
||||||
|
return(retval);
|
||||||
|
} /* calculateUserDir */
|
||||||
|
|
||||||
|
|
||||||
int PHYSFS_init(const char *argv0)
|
int PHYSFS_init(const char *argv0)
|
||||||
{
|
{
|
||||||
BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0);
|
BAIL_IF_MACRO(initialized, ERR_IS_INITIALIZED, 0);
|
||||||
BAIL_IF_MACRO(argv0 == NULL, ERR_INVALID_ARGUMENT, 0);
|
BAIL_IF_MACRO(argv0 == NULL, ERR_INVALID_ARGUMENT, 0);
|
||||||
|
|
||||||
baseDir = calculateBaseDir();
|
baseDir = calculateBaseDir(argv0);
|
||||||
|
if (baseDir == NULL)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
userDir = calculateUserDir();
|
||||||
|
if (userDir == NULL)
|
||||||
|
{
|
||||||
|
free(baseDir);
|
||||||
|
baseDir = NULL;
|
||||||
|
return(0);
|
||||||
|
} /* if */
|
||||||
|
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
return(1);
|
return(1);
|
||||||
} /* PHYSFS_init */
|
} /* PHYSFS_init */
|
||||||
|
@ -137,9 +203,14 @@ int PHYSFS_init(const char *argv0)
|
||||||
|
|
||||||
static void freeSearchDir(SearchDirInfo *sdi)
|
static void freeSearchDir(SearchDirInfo *sdi)
|
||||||
{
|
{
|
||||||
assert(sdi != NULL);
|
FileHandleList *i;
|
||||||
|
|
||||||
/* !!! make sure all files in search dir are closed. */
|
assert(sdi != NULL);
|
||||||
|
for (i = openReadList; i != NULL; i = i->next)
|
||||||
|
{
|
||||||
|
BAIL_IF_MACRO(i->handle->dirReader == sdi->reader,
|
||||||
|
ERR_FILES_OPEN_READ, 0);
|
||||||
|
} /* for */
|
||||||
|
|
||||||
sdi->reader->close(sdi->reader);
|
sdi->reader->close(sdi->reader);
|
||||||
free(sdi->dirName);
|
free(sdi->dirName);
|
||||||
|
@ -147,11 +218,28 @@ static void freeSearchDir(SearchDirInfo *sdi)
|
||||||
} /* freeSearchDir */
|
} /* freeSearchDir */
|
||||||
|
|
||||||
|
|
||||||
|
static void closeFileHandleList(FileHandleList **list)
|
||||||
|
{
|
||||||
|
FileHandleList *i;
|
||||||
|
FileHandleList *next = NULL;
|
||||||
|
|
||||||
|
for (i = *list; i != NULL; i = next)
|
||||||
|
{
|
||||||
|
next = i->next;
|
||||||
|
i->handle->close(i->handle);
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
*list = NULL;
|
||||||
|
} /* closeAllFiles */
|
||||||
|
|
||||||
|
|
||||||
static void freeSearchPath(void)
|
static void freeSearchPath(void)
|
||||||
{
|
{
|
||||||
SearchDirInfo *i;
|
SearchDirInfo *i;
|
||||||
SearchDirInfo *next = NULL;
|
SearchDirInfo *next = NULL;
|
||||||
|
|
||||||
|
closeFileHandleList(&openReadList);
|
||||||
|
|
||||||
if (searchPath != NULL)
|
if (searchPath != NULL)
|
||||||
{
|
{
|
||||||
for (i = searchPath; i != NULL; i = next)
|
for (i = searchPath; i != NULL; i = next)
|
||||||
|
@ -164,23 +252,26 @@ static void freeSearchPath(void)
|
||||||
} /* freeSearchPath */
|
} /* freeSearchPath */
|
||||||
|
|
||||||
|
|
||||||
static void closeAllFiles(void)
|
|
||||||
{
|
|
||||||
} /* closeAllFiles */
|
|
||||||
|
|
||||||
|
|
||||||
void PHYSFS_deinit(void)
|
void PHYSFS_deinit(void)
|
||||||
{
|
{
|
||||||
BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0);
|
BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0);
|
||||||
|
|
||||||
closeAllFiles();
|
closeFileHandleList(&openWriteList);
|
||||||
|
|
||||||
PHYSFS_setWriteDir(NULL);
|
PHYSFS_setWriteDir(NULL);
|
||||||
freeSearchPath();
|
freeSearchPath();
|
||||||
freeErrorMessages();
|
freeErrorMessages();
|
||||||
|
|
||||||
if (baseDir != NULL)
|
if (baseDir != NULL)
|
||||||
|
{
|
||||||
free(baseDir);
|
free(baseDir);
|
||||||
|
baseDir = NULL;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
|
if (userDir != NULL)
|
||||||
|
{
|
||||||
|
free(userDir);
|
||||||
|
userDir = NULL;
|
||||||
|
} /* if */
|
||||||
|
|
||||||
allowSymLinks = 0;
|
allowSymLinks = 0;
|
||||||
initialized = 0;
|
initialized = 0;
|
||||||
|
@ -224,40 +315,7 @@ const char *PHYSFS_getBaseDir(void)
|
||||||
|
|
||||||
const char *PHYSFS_getUserDir(void)
|
const char *PHYSFS_getUserDir(void)
|
||||||
{
|
{
|
||||||
static char *retval = NULL;
|
return(userDir); /* this is calculated in PHYSFS_init()... */
|
||||||
const char *str = NULL;
|
|
||||||
|
|
||||||
if (retval != NULL)
|
|
||||||
return(retval);
|
|
||||||
|
|
||||||
str = __PHYSFS_platformGetUserDir();
|
|
||||||
if (str != NULL)
|
|
||||||
retval = str;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const char *dirsep = PHYSFS_getDirSeparator();
|
|
||||||
const char *uname;
|
|
||||||
|
|
||||||
str = getenv("HOME"); /* try a default. */
|
|
||||||
if (str != NULL)
|
|
||||||
retval = str;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uname = __PHYSFS_platformGetUserName();
|
|
||||||
str = (uname != NULL) ? uname : "default";
|
|
||||||
retval = malloc(strlen(baseDir) + strlen(str) +
|
|
||||||
(strlen(dirsep) * 2) + 6);
|
|
||||||
if (retval == NULL)
|
|
||||||
retval = baseDir; /* (*shrug*) */
|
|
||||||
else
|
|
||||||
sprintf(retval, "%s%susers%s%s", baseDir, dirsep, dirsep, uname);
|
|
||||||
|
|
||||||
if (uname != NULL)
|
|
||||||
free(uname);
|
|
||||||
} /* else */
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
return(baseDir); /* just in case. */
|
|
||||||
} /* PHYSFS_getUserDir */
|
} /* PHYSFS_getUserDir */
|
||||||
|
|
||||||
|
|
||||||
|
@ -269,7 +327,7 @@ const char *PHYSFS_getWriteDir(void)
|
||||||
|
|
||||||
int PHYSFS_setWriteDir(const char *newDir)
|
int PHYSFS_setWriteDir(const char *newDir)
|
||||||
{
|
{
|
||||||
BAIL_IF_MACRO(openWriteCount > 0, ERR_FILES_OPEN_WRITE, 0);
|
BAIL_IF_MACRO(openWriteList != NULL, ERR_FILES_OPEN_WRITE, 0);
|
||||||
|
|
||||||
if (writeDir != NULL)
|
if (writeDir != NULL)
|
||||||
{
|
{
|
||||||
|
@ -291,6 +349,21 @@ int PHYSFS_setWriteDir(const char *newDir)
|
||||||
} /* PHYSFS_setWriteDir */
|
} /* PHYSFS_setWriteDir */
|
||||||
|
|
||||||
|
|
||||||
|
static DirReader *getDirReader(const char *d)
|
||||||
|
{
|
||||||
|
DirFunctions **i;
|
||||||
|
|
||||||
|
for (i = dirFunctions; *i != NULL; i++)
|
||||||
|
{
|
||||||
|
if ((*i)->isArchive(d))
|
||||||
|
return( (*i)->openArchive(d) );
|
||||||
|
} /* for */
|
||||||
|
|
||||||
|
__PHYSFS_setError(ERR_UNSUPPORTED_ARCHIVE);
|
||||||
|
return(NULL);
|
||||||
|
} /* getDirReader */
|
||||||
|
|
||||||
|
|
||||||
int PHYSFS_addToSearchPath(const char *newDir, int appendToPath)
|
int PHYSFS_addToSearchPath(const char *newDir, int appendToPath)
|
||||||
{
|
{
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
|
@ -304,13 +377,15 @@ int PHYSFS_addToSearchPath(const char *newDir, int appendToPath)
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
sdi = (SearchDirInfo *) malloc(sizeof (SearchDirInfo));
|
sdi = (SearchDirInfo *) malloc(sizeof (SearchDirInfo));
|
||||||
|
if (sdi == NULL)
|
||||||
|
reader->close(reader);
|
||||||
BAIL_IF_MACRO(sdi == NULL, ERR_OUT_OF_MEMORY, 0);
|
BAIL_IF_MACRO(sdi == NULL, ERR_OUT_OF_MEMORY, 0);
|
||||||
|
|
||||||
sdi->dirName = (char *) malloc(strlen(newDir) + 1);
|
sdi->dirName = (char *) malloc(strlen(newDir) + 1);
|
||||||
if (sdi->dirName == NULL)
|
if (sdi->dirName == NULL)
|
||||||
{
|
{
|
||||||
free(sdi);
|
free(sdi);
|
||||||
freeReader(reader);
|
reader->close(reader);
|
||||||
__PHYSFS_setError(ERR_OUT_OF_MEMORY);
|
__PHYSFS_setError(ERR_OUT_OF_MEMORY);
|
||||||
return(0);
|
return(0);
|
||||||
} /* if */
|
} /* if */
|
||||||
|
@ -346,6 +421,7 @@ int PHYSFS_removeFromSearchPath(const char *oldDir)
|
||||||
{
|
{
|
||||||
SearchDirInfo *i;
|
SearchDirInfo *i;
|
||||||
SearchDirInfo *prev = NULL;
|
SearchDirInfo *prev = NULL;
|
||||||
|
SearchDirInfo *next = NULL;
|
||||||
|
|
||||||
BAIL_IF_MACRO(oldDir == NULL, ERR_INVALID_ARGUMENT, 0);
|
BAIL_IF_MACRO(oldDir == NULL, ERR_INVALID_ARGUMENT, 0);
|
||||||
|
|
||||||
|
@ -353,14 +429,15 @@ int PHYSFS_removeFromSearchPath(const char *oldDir)
|
||||||
{
|
{
|
||||||
if (strcmp(i->dirName, oldDir) == 0)
|
if (strcmp(i->dirName, oldDir) == 0)
|
||||||
{
|
{
|
||||||
|
next = i->next;
|
||||||
|
if (!freeSearchDir(i))
|
||||||
|
return(0);
|
||||||
|
|
||||||
if (prev == NULL)
|
if (prev == NULL)
|
||||||
searchPath = i->next;
|
searchPath = next;
|
||||||
else
|
else
|
||||||
prev->next = i->next;
|
prev->next = next;
|
||||||
|
|
||||||
/* !!! make sure all files in search dir are closed. */
|
|
||||||
|
|
||||||
freeSearchDir(i);
|
|
||||||
return(1);
|
return(1);
|
||||||
} /* if */
|
} /* if */
|
||||||
prev = i;
|
prev = i;
|
||||||
|
@ -409,55 +486,6 @@ char **PHYSFS_getSearchPath(void)
|
||||||
} /* PHYSFS_getSearchPath */
|
} /* PHYSFS_getSearchPath */
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function.
|
|
||||||
*
|
|
||||||
* Set up sane, default paths. The write path will be set to
|
|
||||||
* "userpath/.appName", which is created if it doesn't exist.
|
|
||||||
*
|
|
||||||
* The above is sufficient to make sure your program's configuration directory
|
|
||||||
* is separated from other clutter, and platform-independent. The period
|
|
||||||
* before "mygame" even hides the directory on Unix systems.
|
|
||||||
*
|
|
||||||
* The search path will be:
|
|
||||||
*
|
|
||||||
* - The Write Dir (created if it doesn't exist)
|
|
||||||
* - The Write Dir/appName (created if it doesn't exist)
|
|
||||||
* - The Base Dir (PHYSFS_getBaseDir())
|
|
||||||
* - The Base Dir/appName (if it exists)
|
|
||||||
* - All found CD-ROM paths (optionally)
|
|
||||||
* - All found CD-ROM paths/appName (optionally, and if they exist)
|
|
||||||
*
|
|
||||||
* These directories are then searched for files ending with the extension
|
|
||||||
* (archiveExt), which, if they are valid and supported archives, will also
|
|
||||||
* be added to the search path. If you specified "PKG" for (archiveExt), and
|
|
||||||
* there's a file named data.PKG in the base dir, it'll be checked. Archives
|
|
||||||
* can either be appended or prepended to the search path in alphabetical
|
|
||||||
* order, regardless of which directories they were found in.
|
|
||||||
*
|
|
||||||
* All of this can be accomplished from the application, but this just does it
|
|
||||||
* all for you. Feel free to add more to the search path manually, too.
|
|
||||||
*
|
|
||||||
* @param appName Program-specific name of your program, to separate it
|
|
||||||
* from other programs using PhysicsFS.
|
|
||||||
*
|
|
||||||
* @param archiveExt File extention used by your program to specify an
|
|
||||||
* archive. For example, Quake 3 uses "pk3", even though
|
|
||||||
* they are just zipfiles. Specify NULL to not dig out
|
|
||||||
* archives automatically.
|
|
||||||
*
|
|
||||||
* @param includeCdRoms Non-zero to include CD-ROMs in the search path, and
|
|
||||||
* (if (archiveExt) != NULL) search them for archives.
|
|
||||||
* This may cause a significant amount of blocking
|
|
||||||
* while discs are accessed, and if there are no discs
|
|
||||||
* in the drive (or even not mounted on Unix systems),
|
|
||||||
* then they may not be made available anyhow. You may
|
|
||||||
* want to specify zero and handle the disc setup
|
|
||||||
* yourself.
|
|
||||||
*
|
|
||||||
* @param archivesFirst Non-zero to prepend the archives to the search path.
|
|
||||||
* Zero to append them. Ignored if !(archiveExt).
|
|
||||||
*/
|
|
||||||
int PHYSFS_setSaneConfig(const char *appName, const char *archiveExt,
|
int PHYSFS_setSaneConfig(const char *appName, const char *archiveExt,
|
||||||
int includeCdRoms, int archivesFirst)
|
int includeCdRoms, int archivesFirst)
|
||||||
{
|
{
|
||||||
|
@ -644,7 +672,6 @@ int PHYSFS_delete(const char *filename)
|
||||||
free(str);
|
free(str);
|
||||||
|
|
||||||
rc = (rc == 0);
|
rc = (rc == 0);
|
||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
__PHYSFS_setError(strerror(errno));
|
__PHYSFS_setError(strerror(errno));
|
||||||
|
|
||||||
|
@ -780,12 +807,37 @@ PHYSFS_file *PHYSFS_openRead(const char *filename)
|
||||||
int PHYSFS_close(PHYSFS_file *handle)
|
int PHYSFS_close(PHYSFS_file *handle)
|
||||||
{
|
{
|
||||||
FileHandle *h = (FileHandle *) handle->opaque;
|
FileHandle *h = (FileHandle *) handle->opaque;
|
||||||
|
FileHandleList *i;
|
||||||
|
FileHandleList **lists[] = { &openWriteList, &openReadList, NULL };
|
||||||
|
int rc;
|
||||||
|
|
||||||
assert(h != NULL);
|
assert(h != NULL);
|
||||||
BAIL_IF_MACRO(h->close == NULL, ERR_NOT_SUPPORTED, -1);
|
assert(h->funcs != NULL);
|
||||||
|
assert(h->funcs->close != NULL);
|
||||||
|
|
||||||
|
while (lists != NULL)
|
||||||
|
{
|
||||||
|
for (i = *(*lists); i != NULL; i = i->next)
|
||||||
|
{
|
||||||
|
if (i->handle == h)
|
||||||
|
{
|
||||||
rc = h->close(h);
|
rc = h->close(h);
|
||||||
if (rc)
|
if (!rc)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if (prev == NULL)
|
||||||
|
*lists = i->next;
|
||||||
|
else
|
||||||
|
prev->next = i->next;
|
||||||
|
free(i);
|
||||||
free(handle);
|
free(handle);
|
||||||
return(rc);
|
return(1);
|
||||||
|
} /* if */
|
||||||
|
} /* for */
|
||||||
|
lists++;
|
||||||
|
} /* while */
|
||||||
|
|
||||||
|
assert(0); /* shouldn't EVER hit this. */
|
||||||
} /* PHYSFS_close */
|
} /* PHYSFS_close */
|
||||||
|
|
||||||
|
|
||||||
|
@ -794,8 +846,9 @@ int PHYSFS_read(PHYSFS_file *handle, void *buffer,
|
||||||
{
|
{
|
||||||
FileHandle *h = (FileHandle *) handle->opaque;
|
FileHandle *h = (FileHandle *) handle->opaque;
|
||||||
assert(h != NULL);
|
assert(h != NULL);
|
||||||
BAIL_IF_MACRO(h->read == NULL, ERR_NOT_SUPPORTED, -1);
|
assert(h->funcs != NULL);
|
||||||
return(h->read(h, buffer, objSize, objCount));
|
BAIL_IF_MACRO(h->funcs->read == NULL, ERR_NOT_SUPPORTED, -1);
|
||||||
|
return(h->funcs->read(h, buffer, objSize, objCount));
|
||||||
} /* PHYSFS_read */
|
} /* PHYSFS_read */
|
||||||
|
|
||||||
|
|
||||||
|
@ -804,8 +857,9 @@ int PHYSFS_write(PHYSFS_file *handle, void *buffer,
|
||||||
{
|
{
|
||||||
FileHandle *h = (FileHandle *) handle->opaque;
|
FileHandle *h = (FileHandle *) handle->opaque;
|
||||||
assert(h != NULL);
|
assert(h != NULL);
|
||||||
BAIL_IF_MACRO(h->write == NULL, ERR_NOT_SUPPORTED, -1);
|
assert(h->funcs != NULL);
|
||||||
return(h->write(h, buffer, objSize, objCount));
|
BAIL_IF_MACRO(h->funcs->write == NULL, ERR_NOT_SUPPORTED, -1);
|
||||||
|
return(h->funcs->write(h, buffer, objSize, objCount));
|
||||||
} /* PHYSFS_write */
|
} /* PHYSFS_write */
|
||||||
|
|
||||||
|
|
||||||
|
@ -813,8 +867,9 @@ int PHYSFS_eof(PHYSFS_file *handle)
|
||||||
{
|
{
|
||||||
FileHandle *h = (FileHandle *) handle->opaque;
|
FileHandle *h = (FileHandle *) handle->opaque;
|
||||||
assert(h != NULL);
|
assert(h != NULL);
|
||||||
BAIL_IF_MACRO(h->eof == NULL, ERR_NOT_SUPPORTED, -1);
|
assert(h->funcs != NULL);
|
||||||
return(h->eof(h));
|
BAIL_IF_MACRO(h->funcs->eof == NULL, ERR_NOT_SUPPORTED, -1);
|
||||||
|
return(h->funcs->eof(h));
|
||||||
} /* PHYSFS_eof */
|
} /* PHYSFS_eof */
|
||||||
|
|
||||||
|
|
||||||
|
@ -822,8 +877,9 @@ int PHYSFS_tell(PHYSFS_file *handle)
|
||||||
{
|
{
|
||||||
FileHandle *h = (FileHandle *) handle->opaque;
|
FileHandle *h = (FileHandle *) handle->opaque;
|
||||||
assert(h != NULL);
|
assert(h != NULL);
|
||||||
BAIL_IF_MACRO(h->tell == NULL, ERR_NOT_SUPPORTED, -1);
|
assert(h->funcs != NULL);
|
||||||
return(h->tell(h));
|
BAIL_IF_MACRO(h->funcs->tell == NULL, ERR_NOT_SUPPORTED, -1);
|
||||||
|
return(h->funcs->tell(h));
|
||||||
} /* PHYSFS_tell */
|
} /* PHYSFS_tell */
|
||||||
|
|
||||||
|
|
||||||
|
@ -831,8 +887,9 @@ int PHYSFS_seek(PHYSFS_file *handle, int pos)
|
||||||
{
|
{
|
||||||
FileHandle *h = (FileHandle *) handle->opaque;
|
FileHandle *h = (FileHandle *) handle->opaque;
|
||||||
assert(h != NULL);
|
assert(h != NULL);
|
||||||
BAIL_IF_MACRO(h->seek == NULL, ERR_NOT_SUPPORTED, 0);
|
assert(h->funcs != NULL);
|
||||||
return(h->seek(h, pos));
|
BAIL_IF_MACRO(h->funcs->seek == NULL, ERR_NOT_SUPPORTED, 0);
|
||||||
|
return(h->funcs->seek(h, pos));
|
||||||
} /* PHYSFS_seek */
|
} /* PHYSFS_seek */
|
||||||
|
|
||||||
/* end of physfs.c ... */
|
/* end of physfs.c ... */
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct __PHYSFS_DIRREADER__;
|
struct __PHYSFS_DIRREADER__;
|
||||||
|
struct __PHYSFS_FILEFUNCTIONS__;
|
||||||
|
|
||||||
typedef struct __PHYSFS_FILEHANDLE__
|
typedef struct __PHYSFS_FILEHANDLE__
|
||||||
{
|
{
|
||||||
|
@ -24,44 +25,53 @@ typedef struct __PHYSFS_FILEHANDLE__
|
||||||
void *opaque;
|
void *opaque;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This should be the DirReader that created this FileHandle.
|
* This should be the DirHandle that created this FileHandle.
|
||||||
*/
|
*/
|
||||||
struct __PHYSFS_DIRREADER__ *dirReader;
|
const struct __PHYSFS_DIRREADER__ *dirReader;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pointer to the file i/o functions for this filehandle.
|
||||||
|
*/
|
||||||
|
const struct __PHYSFS_FILEFUNCTIONS__ *funcs;
|
||||||
|
} FileHandle;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct __PHYSFS_FILEFUNCTIONS__
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Read more from the file.
|
* Read more from the file.
|
||||||
*/
|
*/
|
||||||
int (*read)(struct __PHYSFS_FILEHANDLE__ *handle, void *buffer,
|
int (*read)(FileHandle *handle, void *buffer,
|
||||||
unsigned int objSize, unsigned int objCount);
|
unsigned int objSize, unsigned int objCount);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write more to the file. Archives don't have to implement this.
|
* Write more to the file. Archives don't have to implement this.
|
||||||
* (Set it to NULL if not implemented).
|
* (Set it to NULL if not implemented).
|
||||||
*/
|
*/
|
||||||
int (*write)(struct __PHYSFS_FILEHANDLE__ *handle, void *buffer,
|
int (*write)(FileHandle *handle, void *buffer,
|
||||||
unsigned int objSize, unsigned int objCount);
|
unsigned int objSize, unsigned int objCount);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns non-zero if at end of file.
|
* Returns non-zero if at end of file.
|
||||||
*/
|
*/
|
||||||
int (*eof)(struct __PHYSFS_FILEHANDLE__ *handle);
|
int (*eof)(FileHandle *handle);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns byte offset from start of file.
|
* Returns byte offset from start of file.
|
||||||
*/
|
*/
|
||||||
int (*tell)(struct __PHYSFS_FILEHANDLE__ *handle);
|
int (*tell)(FileHandle *handle);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Move read/write pointer to byte offset from start of file.
|
* Move read/write pointer to byte offset from start of file.
|
||||||
* Returns non-zero on success, zero on error.
|
* Returns non-zero on success, zero on error.
|
||||||
*/
|
*/
|
||||||
int (*seek)(struct __PHYSFS_FILEHANDLE__ *handle, int offset);
|
int (*seek)(FileHandle *handle, int offset);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close the file, and free this structure (including "opaque").
|
* Close the file, and free the FileHandle structure (including "opaque").
|
||||||
*/
|
*/
|
||||||
int (*close)(void);
|
int (*close)(FileHandle *handle);
|
||||||
} FileHandle;
|
} FileFunctions;
|
||||||
|
|
||||||
|
|
||||||
typedef struct __PHYSFS_DIRREADER__
|
typedef struct __PHYSFS_DIRREADER__
|
||||||
|
@ -71,54 +81,99 @@ typedef struct __PHYSFS_DIRREADER__
|
||||||
*/
|
*/
|
||||||
void *opaque;
|
void *opaque;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pointer to the directory i/o functions for this reader.
|
||||||
|
*/
|
||||||
|
const struct __PHYSFS_DIRFUNCTIONS__ *funcs;
|
||||||
|
} DirHandle;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Symlinks should always be followed; PhysicsFS will use
|
||||||
|
* DirFunctions->isSymLink() and make a judgement on whether to
|
||||||
|
* continue to call other methods based on that.
|
||||||
|
*/
|
||||||
|
typedef struct __PHYSFS_DIRFUNCTIONS__
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Returns non-zero if (filename) is a valid archive that this
|
||||||
|
* driver can handle. This filename is in platform-dependent
|
||||||
|
* notation.
|
||||||
|
*/
|
||||||
|
int (*isArchive)(const char *filename);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a DirHandle for dir/archive (name).
|
||||||
|
* This filename is in platform-dependent notation.
|
||||||
|
* return (NULL) on error.
|
||||||
|
*/
|
||||||
|
DirHandle *(*openArchive)(const char *name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns a list (freeable via PHYSFS_freeList()) of
|
* Returns a list (freeable via PHYSFS_freeList()) of
|
||||||
* all files in dirname.
|
* all files in dirname.
|
||||||
* Symlinks should be followed.
|
* This dirname is in platform-independent notation.
|
||||||
*/
|
*/
|
||||||
char **(*enumerateFiles)(struct __PHYSFS_DIRREADER__ *r, const char *dirname);
|
char **(*enumerateFiles)(DirHandle *r, const char *dirname);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns non-zero if filename is really a directory.
|
* Returns non-zero if filename is really a directory.
|
||||||
* Symlinks should be followed.
|
* This filename is in platform-independent notation.
|
||||||
*/
|
*/
|
||||||
int (*isDirectory)(struct __PHYSFS_DIRREADER__ *r, const char *name);
|
int (*isDirectory)(DirHandle *r, const char *name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns non-zero if filename is really a symlink.
|
* Returns non-zero if filename is really a symlink.
|
||||||
|
* This filename is in platform-independent notation.
|
||||||
*/
|
*/
|
||||||
int (*isSymLink)(struct __PHYSFS_DIRREADER__ *r, const char *name);
|
int (*isSymLink)(DirHandle *r, const char *name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns non-zero if filename can be opened for reading.
|
* Returns non-zero if filename can be opened for reading.
|
||||||
* Symlinks should be followed.
|
* This filename is in platform-independent notation.
|
||||||
*/
|
*/
|
||||||
int (*isOpenable)(struct __PHYSFS_DIRREADER__ *r, const char *name);
|
int (*isOpenable)(DirHandle *r, const char *name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open file for reading, and return a FileHandle.
|
* Open file for reading, and return a FileHandle.
|
||||||
* Symlinks should be followed.
|
* This filename is in platform-independent notation.
|
||||||
*/
|
*/
|
||||||
FileHandle *(*openRead)(struct __PHYSFS_DIRREADER__ *r, const char *filename);
|
FileHandle *(*openRead)(DirHandle *r, const char *filename);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close directories/archives, and free this structure, including
|
* Open file for writing, and return a FileHandle.
|
||||||
* the "opaque" entry. This should assume that it won't be called if
|
* This filename is in platform-independent notation.
|
||||||
* there are still files open from this DirReader.
|
* This method may be NULL.
|
||||||
*/
|
*/
|
||||||
void (*close)(struct __PHYSFS_DIRREADER__ *r);
|
FileHandle *(*openWrite)(DirHandle *r, const char *filename);
|
||||||
} DirReader;
|
|
||||||
|
/*
|
||||||
|
* Open file for appending, and return a FileHandle.
|
||||||
|
* This filename is in platform-independent notation.
|
||||||
|
* This method may be NULL.
|
||||||
|
*/
|
||||||
|
FileHandle *(*openAppend)(DirHandle *r, const char *filename);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Close directories/archives, and free the handle, including
|
||||||
|
* the "opaque" entry. This should assume that it won't be called if
|
||||||
|
* there are still files open from this DirHandle.
|
||||||
|
*/
|
||||||
|
void (*close)(DirHandle *r);
|
||||||
|
} DirFunctions;
|
||||||
|
|
||||||
|
|
||||||
/* error messages... */
|
/* error messages... */
|
||||||
#define ERR_IS_INITIALIZED "Already initialized"
|
#define ERR_IS_INITIALIZED "Already initialized"
|
||||||
#define ERR_NOT_INITIALIZED "Not initialized"
|
#define ERR_NOT_INITIALIZED "Not initialized"
|
||||||
#define ERR_INVALID_ARGUMENT "Invalid argument"
|
#define ERR_INVALID_ARGUMENT "Invalid argument"
|
||||||
|
#define ERR_FILES_OPEN_READ "Files still open for reading"
|
||||||
#define ERR_FILES_OPEN_WRITE "Files still open for writing"
|
#define ERR_FILES_OPEN_WRITE "Files still open for writing"
|
||||||
#define ERR_NO_DIR_CREATE "Failed to create directories"
|
#define ERR_NO_DIR_CREATE "Failed to create directories"
|
||||||
#define ERR_OUT_OF_MEMORY "Out of memory"
|
#define ERR_OUT_OF_MEMORY "Out of memory"
|
||||||
#define ERR_NOT_IN_SEARCH_PATH "No such entry in search path"
|
#define ERR_NOT_IN_SEARCH_PATH "No such entry in search path"
|
||||||
#define ERR_NOT_SUPPORTED "Operation not supported"
|
#define ERR_NOT_SUPPORTED "Operation not supported"
|
||||||
|
#define ERR_UNSUPPORTED_ARCHIVE "Archive type unsupported"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -193,6 +248,11 @@ int __PHYSFS_platformGetThreadID(void);
|
||||||
*/
|
*/
|
||||||
int __PHYSFS_platformStricmp(const char *str1, const char *str2);
|
int __PHYSFS_platformStricmp(const char *str1, const char *str2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return non-zero if filename (in platform-dependent notation) is a symlink.
|
||||||
|
*/
|
||||||
|
int __PHYSFS_platformIsSymlink(const char *fname);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
16
unix.c
16
unix.c
|
@ -38,5 +38,21 @@ int __PHYSFS_platformStricmp(const char *str1, const char *str2)
|
||||||
return(strcasecmp(str1, str2));
|
return(strcasecmp(str1, str2));
|
||||||
} /* __PHYSFS_platformStricmp */
|
} /* __PHYSFS_platformStricmp */
|
||||||
|
|
||||||
|
|
||||||
|
int __PHYSFS_platformIsSymlink(const char *fname)
|
||||||
|
{
|
||||||
|
} /* __PHYSFS_platformIsSymlink */
|
||||||
|
|
||||||
|
|
||||||
|
char *__PHYSFS_platformGetUserName(void)
|
||||||
|
{
|
||||||
|
} /* __PHYSFS_platformGetUserName */
|
||||||
|
|
||||||
|
|
||||||
|
char *__PHYSFS_platformGetUserDir(void);
|
||||||
|
{
|
||||||
|
} /* __PHYSFS_platformGetUserDir */
|
||||||
|
|
||||||
|
|
||||||
/* end of unix.c ... */
|
/* end of unix.c ... */
|
||||||
|
|
||||||
|
|
18
zip.c
18
zip.c
|
@ -12,11 +12,13 @@
|
||||||
#define __PHYSICSFS_INTERNAL__
|
#define __PHYSICSFS_INTERNAL__
|
||||||
#include "physfs_internal.h"
|
#include "physfs_internal.h"
|
||||||
|
|
||||||
/* template for filehandles. */
|
#if (!defined PHYSFS_SUPPORTS_ZIP)
|
||||||
const FileHandle __PHYSFS_FileHandle_ZIP =
|
#error PHYSFS_SUPPORTS_ZIP must be defined.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static const FileFunctions __PHYSFS_FileHandle_ZIP =
|
||||||
{
|
{
|
||||||
NULL, /* opaque */
|
|
||||||
NULL, /* dirReader */
|
|
||||||
ZIP_read, /* read() method */
|
ZIP_read, /* read() method */
|
||||||
NULL, /* write() method */
|
NULL, /* write() method */
|
||||||
ZIP_eof, /* eof() method */
|
ZIP_eof, /* eof() method */
|
||||||
|
@ -25,15 +27,17 @@ const FileHandle __PHYSFS_FileHandle_ZIP =
|
||||||
ZIP_close, /* close() method */
|
ZIP_close, /* close() method */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* template for directories. */
|
|
||||||
const DirReader __PHYSFS_DirReader_ZIP =
|
const DirFunctions __PHYSFS_DirFunctions_ZIP =
|
||||||
{
|
{
|
||||||
NULL, /* opaque */
|
ZIP_isArchive, /* isArchive() method */
|
||||||
|
ZIP_openArchive, /* openArchive() method */
|
||||||
ZIP_enumerate, /* enumerateFiles() method */
|
ZIP_enumerate, /* enumerateFiles() method */
|
||||||
ZIP_isDirectory, /* isDirectory() method */
|
ZIP_isDirectory, /* isDirectory() method */
|
||||||
ZIP_isSymLink, /* isSymLink() method */
|
ZIP_isSymLink, /* isSymLink() method */
|
||||||
ZIP_isOpenable, /* isOpenable() method */
|
ZIP_isOpenable, /* isOpenable() method */
|
||||||
ZIP_openRead, /* openRead() method */
|
ZIP_openRead, /* openRead() method */
|
||||||
|
NULL, /* openWrite() method */
|
||||||
ZIP_dirClose, /* close() method */
|
ZIP_dirClose, /* close() method */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue