Skip to content
Permalink
Browse files
Allow application-supplied archivers.
This lets an application supply its own archivers, where they will work like
 any built-in archiver. This allows abstract directory interfaces the same
 way that PHYSFS_Io allows stream implementations.

This is a work in progress still. The API is still changing, and will remain
 at version 0 until it is finalized (a theoretical future version 1 will be
 for when the final public interface changes, not when we evolve the initial
 API design).
  • Loading branch information
icculus committed Nov 28, 2012
1 parent 123313c commit e40d80b00f4b9750603358f86b95da611731d4ac
Showing with 520 additions and 226 deletions.
  1. +10 −9 src/archiver_dir.c
  2. +1 −0 src/archiver_grp.c
  3. +1 −0 src/archiver_hog.c
  4. +12 −11 src/archiver_iso9660.c
  5. +12 −11 src/archiver_lzma.c
  6. +1 −0 src/archiver_mvl.c
  7. +1 −0 src/archiver_qpak.c
  8. +1 −0 src/archiver_slb.c
  9. +10 −11 src/archiver_unpacked.c
  10. +1 −0 src/archiver_wad.c
  11. +10 −9 src/archiver_zip.c
  12. +206 −25 src/physfs.c
  13. +235 −4 src/physfs.h
  14. +12 −139 src/physfs_internal.h
  15. +2 −2 src/platform_posix.c
  16. +5 −5 src/platform_windows.c
@@ -66,7 +66,7 @@ static void *DIR_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
} /* DIR_openArchive */


static void DIR_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
static void DIR_enumerateFiles(void *opaque, const char *dname,
int omitSymLinks, PHYSFS_EnumFilesCallback cb,
const char *origdir, void *callbackdata)
{
@@ -82,7 +82,7 @@ static void DIR_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
} /* DIR_enumerateFiles */


static PHYSFS_Io *doOpen(PHYSFS_Dir *opaque, const char *name,
static PHYSFS_Io *doOpen(void *opaque, const char *name,
const int mode, int *fileExists)
{
char *f;
@@ -114,25 +114,25 @@ static PHYSFS_Io *doOpen(PHYSFS_Dir *opaque, const char *name,
} /* doOpen */


static PHYSFS_Io *DIR_openRead(PHYSFS_Dir *opaque, const char *fnm, int *exist)
static PHYSFS_Io *DIR_openRead(void *opaque, const char *fnm, int *exist)
{
return doOpen(opaque, fnm, 'r', exist);
} /* DIR_openRead */


static PHYSFS_Io *DIR_openWrite(PHYSFS_Dir *opaque, const char *filename)
static PHYSFS_Io *DIR_openWrite(void *opaque, const char *filename)
{
return doOpen(opaque, filename, 'w', NULL);
} /* DIR_openWrite */


static PHYSFS_Io *DIR_openAppend(PHYSFS_Dir *opaque, const char *filename)
static PHYSFS_Io *DIR_openAppend(void *opaque, const char *filename)
{
return doOpen(opaque, filename, 'a', NULL);
} /* DIR_openAppend */


static int DIR_remove(PHYSFS_Dir *opaque, const char *name)
static int DIR_remove(void *opaque, const char *name)
{
int retval;
char *f;
@@ -145,7 +145,7 @@ static int DIR_remove(PHYSFS_Dir *opaque, const char *name)
} /* DIR_remove */


static int DIR_mkdir(PHYSFS_Dir *opaque, const char *name)
static int DIR_mkdir(void *opaque, const char *name)
{
int retval;
char *f;
@@ -158,13 +158,13 @@ static int DIR_mkdir(PHYSFS_Dir *opaque, const char *name)
} /* DIR_mkdir */


static void DIR_closeArchive(PHYSFS_Dir *opaque)
static void DIR_closeArchive(void *opaque)
{
allocator.Free(opaque);
} /* DIR_closeArchive */


static int DIR_stat(PHYSFS_Dir *opaque, const char *name,
static int DIR_stat(void *opaque, const char *name,
int *exists, PHYSFS_Stat *stat)
{
int retval = 0;
@@ -180,6 +180,7 @@ static int DIR_stat(PHYSFS_Dir *opaque, const char *name,

const PHYSFS_Archiver __PHYSFS_Archiver_DIR =
{
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
{
"",
"Non-archive, direct filesystem I/O",
@@ -87,6 +87,7 @@ static void *GRP_openArchive(PHYSFS_Io *io, const char *name, int forWriting)

const PHYSFS_Archiver __PHYSFS_Archiver_GRP =
{
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
{
"GRP",
"Build engine Groupfile format",
@@ -93,6 +93,7 @@ static void *HOG_openArchive(PHYSFS_Io *io, const char *name, int forWriting)

const PHYSFS_Archiver __PHYSFS_Archiver_HOG =
{
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
{
"HOG",
"Descent I/II HOG file format",
@@ -291,8 +291,8 @@ static int iso_extractfilenameISO(ISO9660FileDescriptor *descriptor,
for(;pos < descriptor->filenamelen; pos++)
if (descriptor->filename[pos] == ';')
lastfound = pos;
BAIL_IF_MACRO(lastfound < 1, PHYSFS_ERR_NO_SUCH_PATH /* !!! FIXME: PHYSFS_ERR_BAD_FILENAME */, -1);
BAIL_IF_MACRO(lastfound == (descriptor->filenamelen -1), PHYSFS_ERR_NO_SUCH_PATH /* !!! PHYSFS_ERR_BAD_FILENAME */, -1);
BAIL_IF_MACRO(lastfound < 1, PHYSFS_ERR_NOT_FOUND /* !!! FIXME: PHYSFS_ERR_BAD_FILENAME */, -1);
BAIL_IF_MACRO(lastfound == (descriptor->filenamelen -1), PHYSFS_ERR_NOT_FOUND /* !!! PHYSFS_ERR_BAD_FILENAME */, -1);
strncpy(filename, descriptor->filename, lastfound);
if (filename[lastfound - 1] == '.')
filename[lastfound - 1] = '\0'; /* consume trailing ., as done in all implementations */
@@ -638,7 +638,7 @@ static void *ISO9660_openArchive(PHYSFS_Io *io, const char *filename, int forWri
} /* ISO9660_openArchive */


static void ISO9660_closeArchive(PHYSFS_Dir *opaque)
static void ISO9660_closeArchive(void *opaque)
{
ISO9660Handle *handle = (ISO9660Handle*) opaque;
handle->io->destroy(handle->io);
@@ -766,7 +766,7 @@ static int iso_file_open_foreign(ISO9660Handle *handle,
} /* iso_file_open_foreign */


static PHYSFS_Io *ISO9660_openRead(PHYSFS_Dir *opaque, const char *filename,
static PHYSFS_Io *ISO9660_openRead(void *opaque, const char *filename,
int *exists)
{
PHYSFS_Io *retval = NULL;
@@ -785,7 +785,7 @@ static PHYSFS_Io *ISO9660_openRead(PHYSFS_Dir *opaque, const char *filename,
/* find file descriptor */
rc = iso_find_dir_entry(handle, filename, &descriptor, exists);
GOTO_IF_MACRO(rc, ERRPASS, errorhandling);
GOTO_IF_MACRO(!*exists, PHYSFS_ERR_NO_SUCH_PATH, errorhandling);
GOTO_IF_MACRO(!*exists, PHYSFS_ERR_NOT_FOUND, errorhandling);

fhandle->startblock = descriptor.extentpos + descriptor.extattributelen;
fhandle->filesize = descriptor.datalen;
@@ -816,7 +816,7 @@ static PHYSFS_Io *ISO9660_openRead(PHYSFS_Dir *opaque, const char *filename,
* Information gathering functions
******************************************************************************/

static void ISO9660_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
static void ISO9660_enumerateFiles(void *opaque, const char *dname,
int omitSymLinks,
PHYSFS_EnumFilesCallback cb,
const char *origdir, void *callbackdata)
@@ -873,7 +873,7 @@ static void ISO9660_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
} /* ISO9660_enumerateFiles */


static int ISO9660_stat(PHYSFS_Dir *opaque, const char *name, int *exists,
static int ISO9660_stat(void *opaque, const char *name, int *exists,
PHYSFS_Stat *stat)
{
ISO9660Handle *handle = (ISO9660Handle*) opaque;
@@ -920,32 +920,33 @@ static int ISO9660_stat(PHYSFS_Dir *opaque, const char *name, int *exists,
* Not supported functions
******************************************************************************/

static PHYSFS_Io *ISO9660_openWrite(PHYSFS_Dir *opaque, const char *name)
static PHYSFS_Io *ISO9660_openWrite(void *opaque, const char *name)
{
BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
} /* ISO9660_openWrite */


static PHYSFS_Io *ISO9660_openAppend(PHYSFS_Dir *opaque, const char *name)
static PHYSFS_Io *ISO9660_openAppend(void *opaque, const char *name)
{
BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
} /* ISO9660_openAppend */


static int ISO9660_remove(PHYSFS_Dir *opaque, const char *name)
static int ISO9660_remove(void *opaque, const char *name)
{
BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
} /* ISO9660_remove */


static int ISO9660_mkdir(PHYSFS_Dir *opaque, const char *name)
static int ISO9660_mkdir(void *opaque, const char *name)
{
BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
} /* ISO9660_mkdir */


const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660 =
{
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
{
"ISO",
"ISO9660 image file",
@@ -205,7 +205,7 @@ static LZMAfile * lzma_find_file(const LZMAarchive *archive, const char *name)
{
LZMAfile *file = bsearch(name, archive->files, archive->db.Database.NumFiles, sizeof(*archive->files), lzma_file_cmp_stdlib); /* FIXME: Should become __PHYSFS_search!!! */

BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NO_SUCH_PATH, NULL);
BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NOT_FOUND, NULL);

return file;
} /* lzma_find_file */
@@ -531,7 +531,7 @@ static void doEnumCallback(PHYSFS_EnumFilesCallback cb, void *callbackdata,
} /* doEnumCallback */


static void LZMA_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
static void LZMA_enumerateFiles(void *opaque, const char *dname,
int omitSymLinks, PHYSFS_EnumFilesCallback cb,
const char *origdir, void *callbackdata)
{
@@ -551,7 +551,7 @@ static void LZMA_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
file = archive->files;
}

BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NO_SUCH_PATH, );
BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NOT_FOUND, );

while (file < lastFile)
{
@@ -575,15 +575,15 @@ static void LZMA_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
} /* LZMA_enumerateFiles */


static PHYSFS_Io *LZMA_openRead(PHYSFS_Dir *opaque, const char *name,
static PHYSFS_Io *LZMA_openRead(void *opaque, const char *name,
int *fileExists)
{
LZMAarchive *archive = (LZMAarchive *) opaque;
LZMAfile *file = lzma_find_file(archive, name);
PHYSFS_Io *io = NULL;

*fileExists = (file != NULL);
BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NO_SUCH_PATH, NULL);
BAIL_IF_MACRO(file == NULL, PHYSFS_ERR_NOT_FOUND, NULL);
BAIL_IF_MACRO(file->folder == NULL, PHYSFS_ERR_NOT_A_FILE, NULL);

file->position = 0;
@@ -598,19 +598,19 @@ static PHYSFS_Io *LZMA_openRead(PHYSFS_Dir *opaque, const char *name,
} /* LZMA_openRead */


static PHYSFS_Io *LZMA_openWrite(PHYSFS_Dir *opaque, const char *filename)
static PHYSFS_Io *LZMA_openWrite(void *opaque, const char *filename)
{
BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
} /* LZMA_openWrite */


static PHYSFS_Io *LZMA_openAppend(PHYSFS_Dir *opaque, const char *filename)
static PHYSFS_Io *LZMA_openAppend(void *opaque, const char *filename)
{
BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
} /* LZMA_openAppend */


static void LZMA_closeArchive(PHYSFS_Dir *opaque)
static void LZMA_closeArchive(void *opaque)
{
LZMAarchive *archive = (LZMAarchive *) opaque;

@@ -628,18 +628,18 @@ static void LZMA_closeArchive(PHYSFS_Dir *opaque)
} /* LZMA_closeArchive */


static int LZMA_remove(PHYSFS_Dir *opaque, const char *name)
static int LZMA_remove(void *opaque, const char *name)
{
BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
} /* LZMA_remove */


static int LZMA_mkdir(PHYSFS_Dir *opaque, const char *name)
static int LZMA_mkdir(void *opaque, const char *name)
{
BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
} /* LZMA_mkdir */

static int LZMA_stat(PHYSFS_Dir *opaque, const char *filename,
static int LZMA_stat(void *opaque, const char *filename,
int *exists, PHYSFS_Stat *stat)
{
const LZMAarchive *archive = (const LZMAarchive *) opaque;
@@ -678,6 +678,7 @@ static int LZMA_stat(PHYSFS_Dir *opaque, const char *filename,

const PHYSFS_Archiver __PHYSFS_Archiver_LZMA =
{
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
{
"7Z",
"LZMA (7zip) format",
@@ -80,6 +80,7 @@ static void *MVL_openArchive(PHYSFS_Io *io, const char *name, int forWriting)

const PHYSFS_Archiver __PHYSFS_Archiver_MVL =
{
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
{
"MVL",
"Descent II Movielib format",
@@ -96,6 +96,7 @@ static void *QPAK_openArchive(PHYSFS_Io *io, const char *name, int forWriting)

const PHYSFS_Archiver __PHYSFS_Archiver_QPAK =
{
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
{
"PAK",
"Quake I/II format",
@@ -101,6 +101,7 @@ static void *SLB_openArchive(PHYSFS_Io *io, const char *name, int forWriting)

const PHYSFS_Archiver __PHYSFS_Archiver_SLB =
{
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
{
"SLB",
"I-War / Independence War Slab file",
@@ -34,7 +34,7 @@ typedef struct
} UNPKfileinfo;


void UNPK_closeArchive(PHYSFS_Dir *opaque)
void UNPK_closeArchive(void *opaque)
{
UNPKinfo *info = ((UNPKinfo *) opaque);
info->io->destroy(info->io);
@@ -242,7 +242,7 @@ static void doEnumCallback(PHYSFS_EnumFilesCallback cb, void *callbackdata,
} /* doEnumCallback */


void UNPK_enumerateFiles(PHYSFS_Dir *opaque, const char *dname,
void UNPK_enumerateFiles(void *opaque, const char *dname,
int omitSymLinks, PHYSFS_EnumFilesCallback cb,
const char *origdir, void *callbackdata)
{
@@ -340,11 +340,11 @@ static UNPKentry *findEntry(const UNPKinfo *info, const char *path, int *isDir)
if (isDir != NULL)
*isDir = 0;

BAIL_MACRO(PHYSFS_ERR_NO_SUCH_PATH, NULL);
BAIL_MACRO(PHYSFS_ERR_NOT_FOUND, NULL);
} /* findEntry */


PHYSFS_Io *UNPK_openRead(PHYSFS_Dir *opaque, const char *fnm, int *fileExists)
PHYSFS_Io *UNPK_openRead(void *opaque, const char *fnm, int *fileExists)
{
PHYSFS_Io *retval = NULL;
UNPKinfo *info = (UNPKinfo *) opaque;
@@ -390,31 +390,31 @@ PHYSFS_Io *UNPK_openRead(PHYSFS_Dir *opaque, const char *fnm, int *fileExists)
} /* UNPK_openRead */


PHYSFS_Io *UNPK_openWrite(PHYSFS_Dir *opaque, const char *name)
PHYSFS_Io *UNPK_openWrite(void *opaque, const char *name)
{
BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
} /* UNPK_openWrite */


PHYSFS_Io *UNPK_openAppend(PHYSFS_Dir *opaque, const char *name)
PHYSFS_Io *UNPK_openAppend(void *opaque, const char *name)
{
BAIL_MACRO(PHYSFS_ERR_READ_ONLY, NULL);
} /* UNPK_openAppend */


int UNPK_remove(PHYSFS_Dir *opaque, const char *name)
int UNPK_remove(void *opaque, const char *name)
{
BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
} /* UNPK_remove */


int UNPK_mkdir(PHYSFS_Dir *opaque, const char *name)
int UNPK_mkdir(void *opaque, const char *name)
{
BAIL_MACRO(PHYSFS_ERR_READ_ONLY, 0);
} /* UNPK_mkdir */


int UNPK_stat(PHYSFS_Dir *opaque, const char *filename,
int UNPK_stat(void *opaque, const char *filename,
int *exists, PHYSFS_Stat *stat)
{
int isDir = 0;
@@ -448,8 +448,7 @@ int UNPK_stat(PHYSFS_Dir *opaque, const char *filename,
} /* UNPK_stat */


PHYSFS_Dir *UNPK_openArchive(PHYSFS_Io *io, UNPKentry *e,
const PHYSFS_uint32 num)
void *UNPK_openArchive(PHYSFS_Io *io, UNPKentry *e, const PHYSFS_uint32 num)
{
UNPKinfo *info = (UNPKinfo *) allocator.Malloc(sizeof (UNPKinfo));
if (info == NULL)
@@ -104,6 +104,7 @@ static void *WAD_openArchive(PHYSFS_Io *io, const char *name, int forWriting)

const PHYSFS_Archiver __PHYSFS_Archiver_WAD =
{
CURRENT_PHYSFS_ARCHIVER_API_VERSION,
{
"WAD",
"DOOM engine format",

0 comments on commit e40d80b

Please sign in to comment.