From 4cfd7277f3196f042fc16dcdad920707c08f9219 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 25 Mar 2012 15:59:29 -0400 Subject: [PATCH] Made archiver list dynamic, in preparation for external archivers. --- src/physfs.c | 112 ++++++++++++++++++++++++++++----------------------- src/physfs.h | 5 ++- 2 files changed, 65 insertions(+), 52 deletions(-) diff --git a/src/physfs.c b/src/physfs.c index b12c0faf..02cc9242 100644 --- a/src/physfs.c +++ b/src/physfs.c @@ -47,55 +47,17 @@ typedef struct __PHYSFS_ERRSTATETYPE__ /* The various i/o drivers...some of these may not be compiled in. */ -extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ZIP; -extern const PHYSFS_Archiver __PHYSFS_Archiver_ZIP; -extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_LZMA; -extern const PHYSFS_Archiver __PHYSFS_Archiver_LZMA; -extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_GRP; -extern const PHYSFS_Archiver __PHYSFS_Archiver_GRP; -extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_QPAK; -extern const PHYSFS_Archiver __PHYSFS_Archiver_QPAK; -extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_HOG; -extern const PHYSFS_Archiver __PHYSFS_Archiver_HOG; -extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_MVL; -extern const PHYSFS_Archiver __PHYSFS_Archiver_MVL; -extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_WAD; -extern const PHYSFS_Archiver __PHYSFS_Archiver_WAD; -extern const PHYSFS_Archiver __PHYSFS_Archiver_DIR; -extern const PHYSFS_ArchiveInfo __PHYSFS_ArchiveInfo_ISO9660; -extern const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660; - - -static const PHYSFS_ArchiveInfo *supported_types[] = -{ -#if PHYSFS_SUPPORTS_ZIP - &__PHYSFS_ArchiveInfo_ZIP, -#endif -#if PHYSFS_SUPPORTS_7Z - &__PHYSFS_ArchiveInfo_LZMA, -#endif -#if PHYSFS_SUPPORTS_GRP - &__PHYSFS_ArchiveInfo_GRP, -#endif -#if PHYSFS_SUPPORTS_QPAK - &__PHYSFS_ArchiveInfo_QPAK, -#endif -#if PHYSFS_SUPPORTS_HOG - &__PHYSFS_ArchiveInfo_HOG, -#endif -#if PHYSFS_SUPPORTS_MVL - &__PHYSFS_ArchiveInfo_MVL, -#endif -#if PHYSFS_SUPPORTS_WAD - &__PHYSFS_ArchiveInfo_WAD, -#endif -#if PHYSFS_SUPPORTS_ISO9660 - &__PHYSFS_ArchiveInfo_ISO9660, -#endif - NULL -}; - -static const PHYSFS_Archiver *archivers[] = +extern const PHYSFS_Archiver __PHYSFS_Archiver_ZIP; +extern const PHYSFS_Archiver __PHYSFS_Archiver_LZMA; +extern const PHYSFS_Archiver __PHYSFS_Archiver_GRP; +extern const PHYSFS_Archiver __PHYSFS_Archiver_QPAK; +extern const PHYSFS_Archiver __PHYSFS_Archiver_HOG; +extern const PHYSFS_Archiver __PHYSFS_Archiver_MVL; +extern const PHYSFS_Archiver __PHYSFS_Archiver_WAD; +extern const PHYSFS_Archiver __PHYSFS_Archiver_DIR; +extern const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660; + +static const PHYSFS_Archiver *staticArchivers[] = { #if PHYSFS_SUPPORTS_ZIP &__PHYSFS_Archiver_ZIP, @@ -137,6 +99,8 @@ static char *baseDir = NULL; static char *userDir = NULL; static char *prefDir = NULL; static int allowSymLinks = 0; +static const PHYSFS_Archiver **archivers = NULL; +static const PHYSFS_ArchiveInfo **archiveInfo = NULL; /* mutexes ... */ static void *errorLock = NULL; /* protects error message list. */ @@ -1158,6 +1122,37 @@ static int initializeMutexes(void) static void setDefaultAllocator(void); +static int initStaticArchivers(void) +{ + const size_t numStaticArchivers = __PHYSFS_ARRAYLEN(staticArchivers); + const size_t len = numStaticArchivers * sizeof (void *); + size_t i; + + assert(numStaticArchivers > 0); /* seriously, none at all?! */ + assert(staticArchivers[numStaticArchivers - 1] == NULL); + + archiveInfo = (const PHYSFS_ArchiveInfo **) allocator.Malloc(len); + GOTO_IF_MACRO(!archiveInfo, PHYSFS_ERR_OUT_OF_MEMORY, failed); + archivers = (const PHYSFS_Archiver **) allocator.Malloc(len); + GOTO_IF_MACRO(!archivers, PHYSFS_ERR_OUT_OF_MEMORY, failed); + + for (i = 0; i < numStaticArchivers - 1; i++) + archiveInfo[i] = staticArchivers[i]->info; + archiveInfo[numStaticArchivers - 1] = NULL; + + memcpy(archivers, staticArchivers, len); + + return 1; + +failed: + allocator.Free(archiveInfo); + allocator.Free(archivers); + archivers = NULL; + archiveInfo = NULL; + return 0; +} /* initStaticArchivers */ + + int PHYSFS_init(const char *argv0) { BAIL_IF_MACRO(initialized, PHYSFS_ERR_IS_INITIALIZED, 0); @@ -1175,6 +1170,8 @@ int PHYSFS_init(const char *argv0) baseDir = calculateBaseDir(argv0); BAIL_IF_MACRO(!baseDir, ERRPASS, 0); + /* !!! FIXME: we have to clean up all the half-initialized state if something fails. */ + userDir = __PHYSFS_platformCalcUserDir(); if (!userDir) { @@ -1187,6 +1184,8 @@ int PHYSFS_init(const char *argv0) assert(baseDir[strlen(baseDir) - 1] == __PHYSFS_platformDirSeparator); assert(userDir[strlen(userDir) - 1] == __PHYSFS_platformDirSeparator); + BAIL_IF_MACRO(!initStaticArchivers(), ERRPASS, 0); + initialized = 1; /* This makes sure that the error subsystem is initialized. */ @@ -1271,6 +1270,18 @@ int PHYSFS_deinit(void) prefDir = NULL; } /* if */ + if (archiveInfo != NULL) + { + allocator.Free(archiveInfo); + archiveInfo = NULL; + } /* if */ + + if (archivers != NULL) + { + allocator.Free(archivers); + archivers = NULL; + } /* if */ + allowSymLinks = 0; initialized = 0; @@ -1293,7 +1304,8 @@ int PHYSFS_isInit(void) const PHYSFS_ArchiveInfo **PHYSFS_supportedArchiveTypes(void) { - return supported_types; + BAIL_IF_MACRO(!initialized, PHYSFS_ERR_NOT_INITIALIZED, NULL); + return archiveInfo; } /* PHYSFS_supportedArchiveTypes */ diff --git a/src/physfs.h b/src/physfs.h index c927d5d4..6550855a 100644 --- a/src/physfs.h +++ b/src/physfs.h @@ -575,8 +575,9 @@ PHYSFS_DECL int PHYSFS_deinit(void); * } * \endcode * - * The return values are pointers to static internal memory, and should - * be considered READ ONLY, and never freed. + * The return values are pointers to internal memory, and should + * be considered READ ONLY, and never freed. The returned values are + * valid until the next call to PHYSFS_deinit(). * * \return READ ONLY Null-terminated array of READ ONLY structures. */