Added first work on PHYSFS_stat() API (thanks, Christoph!).
--- a/docs/CREDITS.txt Thu Feb 04 04:46:14 2010 -0500
+++ b/docs/CREDITS.txt Sun Feb 14 23:07:19 2010 -0500
@@ -105,6 +105,9 @@
Bug fixes:
Patrice Mandin
+PHYSFS_stat() API:
+ Christoph Nelles
+
Other stuff:
Your name here! Patches go to icculus@icculus.org ...
--- a/extras/physfs-swig.i Thu Feb 04 04:46:14 2010 -0500
+++ b/extras/physfs-swig.i Sun Feb 14 23:07:19 2010 -0500
@@ -83,6 +83,7 @@
%rename(symbolicLinksPermitted) PHYSFS_symbolicLinksPermitted;
%rename(mount) PHYSFS_mount;
%rename(getMountPoint) PHYSFS_getMountPoint;
+%rename(stat) PHYSFS_stat;
#endif /* SWIGPERL */
%include "../src/physfs.h"
--- a/src/archiver_dir.c Thu Feb 04 04:46:14 2010 -0500
+++ b/src/archiver_dir.c Sun Feb 14 23:07:19 2010 -0500
@@ -169,6 +169,20 @@
} /* DIR_getLastModTime */
+static int DIR_stat(dvoid *opaque, const char *name, PHYSFS_Stat *st)
+{
+ char *d = __PHYSFS_platformCvtToDependent((char *)opaque, name, NULL);
+ int retval = -1;
+
+ BAIL_IF_MACRO(d == NULL, NULL, -1);
+
+ retval = __PHYSFS_platformStat(d, st);
+
+ allocator.Free(d);
+ return(retval);
+} /* DIR_stat */
+
+
static fvoid *doOpen(dvoid *opaque, const char *name,
void *(*openFunc)(const char *filename),
int *fileExists)
@@ -261,6 +275,7 @@
DIR_openArchive, /* openArchive() method */
DIR_enumerateFiles, /* enumerateFiles() method */
DIR_exists, /* exists() method */
+ DIR_stat, /* stat() method */
DIR_isDirectory, /* isDirectory() method */
DIR_isSymLink, /* isSymLink() method */
DIR_getLastModTime, /* getLastModTime() method */
--- a/src/archiver_grp.c Thu Feb 04 04:46:14 2010 -0500
+++ b/src/archiver_grp.c Sun Feb 14 23:07:19 2010 -0500
@@ -384,6 +384,12 @@
} /* GRP_getLastModTime */
+static int GRP_stat(dvoid *opaque, const char *name, PHYSFS_Stat *st)
+{
+ return -1; /* !!! FIXME: write me */
+} /* GRP_stat */
+
+
static fvoid *GRP_openRead(dvoid *opaque, const char *fnm, int *fileExists)
{
GRPinfo *info = (GRPinfo *) opaque;
@@ -451,6 +457,7 @@
GRP_openArchive, /* openArchive() method */
GRP_enumerateFiles, /* enumerateFiles() method */
GRP_exists, /* exists() method */
+ GRP_stat, /* stat() method */
GRP_isDirectory, /* isDirectory() method */
GRP_isSymLink, /* isSymLink() method */
GRP_getLastModTime, /* getLastModTime() method */
--- a/src/archiver_hog.c Thu Feb 04 04:46:14 2010 -0500
+++ b/src/archiver_hog.c Sun Feb 14 23:07:19 2010 -0500
@@ -423,6 +423,12 @@
} /* HOG_getLastModTime */
+static int HOG_stat(dvoid *opaque, const char *name, PHYSFS_Stat *st)
+{
+ return -1; /* !!! FIXME: write me */
+} /* HOG_stat */
+
+
static fvoid *HOG_openRead(dvoid *opaque, const char *fnm, int *fileExists)
{
HOGinfo *info = ((HOGinfo *) opaque);
@@ -490,6 +496,7 @@
HOG_openArchive, /* openArchive() method */
HOG_enumerateFiles, /* enumerateFiles() method */
HOG_exists, /* exists() method */
+ HOG_stat, /* stat() method */
HOG_isDirectory, /* isDirectory() method */
HOG_isSymLink, /* isSymLink() method */
HOG_getLastModTime, /* getLastModTime() method */
--- a/src/archiver_lzma.c Thu Feb 04 04:46:14 2010 -0500
+++ b/src/archiver_lzma.c Sun Feb 14 23:07:19 2010 -0500
@@ -623,6 +623,12 @@
} /* LZMA_getLastModTime */
+static int LZMA_stat(dvoid *opaque, const char *name, PHYSFS_Stat *st)
+{
+ return -1; /* !!! FIXME: write me */
+} /* LZMA_stat */
+
+
static int LZMA_isDirectory(dvoid *opaque, const char *name, int *fileExists)
{
LZMAarchive *archive = (LZMAarchive *) opaque;
@@ -712,6 +718,7 @@
LZMA_openArchive, /* openArchive() method */
LZMA_enumerateFiles, /* enumerateFiles() method */
LZMA_exists, /* exists() method */
+ LZMA_stat, /* stat() method */
LZMA_isDirectory, /* isDirectory() method */
LZMA_isSymLink, /* isSymLink() method */
LZMA_getLastModTime, /* getLastModTime() method */
--- a/src/archiver_mvl.c Thu Feb 04 04:46:14 2010 -0500
+++ b/src/archiver_mvl.c Sun Feb 14 23:07:19 2010 -0500
@@ -380,6 +380,12 @@
} /* MVL_getLastModTime */
+static int MVL_stat(dvoid *opaque, const char *name, PHYSFS_Stat *st)
+{
+ return -1; /* !!! FIXME: write me */
+} /* MVL_stat */
+
+
static fvoid *MVL_openRead(dvoid *opaque, const char *fnm, int *fileExists)
{
MVLinfo *info = ((MVLinfo *) opaque);
@@ -447,6 +453,7 @@
MVL_openArchive, /* openArchive() method */
MVL_enumerateFiles, /* enumerateFiles() method */
MVL_exists, /* exists() method */
+ MVL_stat, /* stat() method */
MVL_isDirectory, /* isDirectory() method */
MVL_isSymLink, /* isSymLink() method */
MVL_getLastModTime, /* getLastModTime() method */
--- a/src/archiver_qpak.c Thu Feb 04 04:46:14 2010 -0500
+++ b/src/archiver_qpak.c Sun Feb 14 23:07:19 2010 -0500
@@ -537,6 +537,12 @@
} /* QPAK_getLastModTime */
+static int QPAK_stat(dvoid *opaque, const char *name, PHYSFS_Stat *st)
+{
+ return -1; /* !!! FIXME: write me */
+} /* QPAK_stat */
+
+
static fvoid *QPAK_openRead(dvoid *opaque, const char *fnm, int *fileExists)
{
QPAKinfo *info = ((QPAKinfo *) opaque);
@@ -606,6 +612,7 @@
QPAK_openArchive, /* openArchive() method */
QPAK_enumerateFiles, /* enumerateFiles() method */
QPAK_exists, /* exists() method */
+ QPAK_stat, /* stat() method */
QPAK_isDirectory, /* isDirectory() method */
QPAK_isSymLink, /* isSymLink() method */
QPAK_getLastModTime, /* getLastModTime() method */
--- a/src/archiver_wad.c Thu Feb 04 04:46:14 2010 -0500
+++ b/src/archiver_wad.c Sun Feb 14 23:07:19 2010 -0500
@@ -443,6 +443,12 @@
} /* WAD_getLastModTime */
+static int WAD_stat(dvoid *opaque, const char *name, PHYSFS_Stat *st)
+{
+ return -1; /* !!! FIXME: write me */
+} /* WAD_stat */
+
+
static fvoid *WAD_openRead(dvoid *opaque, const char *fnm, int *fileExists)
{
WADinfo *info = ((WADinfo *) opaque);
@@ -510,6 +516,7 @@
WAD_openArchive, /* openArchive() method */
WAD_enumerateFiles, /* enumerateFiles() method */
WAD_exists, /* exists() method */
+ WAD_stat, /* stat() method */
WAD_isDirectory, /* isDirectory() method */
WAD_isSymLink, /* isSymLink() method */
WAD_getLastModTime, /* getLastModTime() method */
--- a/src/archiver_zip.c Thu Feb 04 04:46:14 2010 -0500
+++ b/src/archiver_zip.c Sun Feb 14 23:07:19 2010 -0500
@@ -1264,6 +1264,12 @@
} /* ZIP_getLastModTime */
+static int ZIP_stat(dvoid *opaque, const char *name, PHYSFS_Stat *st)
+{
+ return -1; /* !!! FIXME: write me */
+} /* ZIP_stat */
+
+
static int ZIP_isDirectory(dvoid *opaque, const char *name, int *fileExists)
{
ZIPinfo *info = (ZIPinfo *) opaque;
@@ -1422,6 +1428,7 @@
ZIP_openArchive, /* openArchive() method */
ZIP_enumerateFiles, /* enumerateFiles() method */
ZIP_exists, /* exists() method */
+ ZIP_stat, /* stat() method */
ZIP_isDirectory, /* isDirectory() method */
ZIP_isSymLink, /* isSymLink() method */
ZIP_getLastModTime, /* getLastModTime() method */
--- a/src/physfs.c Thu Feb 04 04:46:14 2010 -0500
+++ b/src/physfs.c Sun Feb 14 23:07:19 2010 -0500
@@ -1620,6 +1620,50 @@
return (PHYSFS_getRealDir(fname) != NULL);
} /* PHYSFS_exists */
+int PHYSFS_stat(const char *_fname, PHYSFS_Stat *st)
+{
+ char *fname;
+ size_t len;
+ int retval = -1;
+
+ BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, -1);
+ BAIL_IF_MACRO(st == NULL, ERR_INVALID_ARGUMENT, -1);
+
+ memset(st, 0, sizeof(PHYSFS_Stat));
+ len = strlen(_fname) + 1;
+ fname = (char *) __PHYSFS_smallAlloc(len);
+ BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, -1);
+
+ if (sanitizePlatformIndependentPath(_fname, fname))
+ {
+ if (*fname == '\0') /* eh...punt if it's the root dir. */
+ {
+ retval = 0; /* !!! FIXME: Maybe this should be an error? */
+ st->is_dir = 1;
+ } /* if */
+ else
+ {
+ DirHandle *i;
+ int exists = 0;
+ __PHYSFS_platformGrabMutex(stateLock);
+ for (i = searchPath; ((i != NULL) && (!exists)); i = i->next)
+ {
+ char *arcfname = fname;
+ exists = partOfMountPoint(i, arcfname);
+ if (exists)
+ retval = 1; /* !!! FIXME: What's the right value? */
+ else if (verifyPath(i, &arcfname, 0))
+ {
+ retval = i->funcs->stat(i->opaque, arcfname, st);
+ } /* else if */
+ } /* for */
+ __PHYSFS_platformReleaseMutex(stateLock);
+ } /* else */
+ } /* if */
+
+ __PHYSFS_smallFree(fname);
+ return(retval);
+}
PHYSFS_sint64 PHYSFS_getLastModTime(const char *_fname)
{
--- a/src/physfs.h Thu Feb 04 04:46:14 2010 -0500
+++ b/src/physfs.h Sun Feb 14 23:07:19 2010 -0500
@@ -2463,6 +2463,42 @@
#endif /* SWIG */
+/**
+ * \struct PHYSFS_Stat
+ * \brief Information on a file in a PhysicsFS filesystem.
+ *
+ * Created as a way to get a file's information without repeated calls and
+ * without having to open the file.
+ *
+ * \sa PHYSFS_stat
+ */
+typedef struct PHYSFS_Stat
+{
+ int is_dir;
+ int is_symlink;
+ PHYSFS_sint64 size;
+ PHYSFS_sint64 atime;
+ PHYSFS_sint64 mtime;
+ PHYSFS_sint64 ctime;
+} PHYSFS_Stat;
+
+
+/**
+ * \fn int PHYSFS_stat(const char *fname, PHYSFS_Stat * st)
+ * \brief Get information on a file in the search path.
+ *
+ * \param fname filename in platform-independent notation.
+ * \param st pointer to an PHYSFS_Stat structure.
+ * \return 0 on success (file exists and information retreived successfully),
+ * non-zero otherwise.
+ *
+ * !!! FIXME: have to distinguish between "unsupported", "missing" and
+ * !!! FIXME: "failure" results.
+ *
+ * \sa PHYSFS_Stat
+ */
+PHYSFS_DECL int PHYSFS_stat(const char *fname, PHYSFS_Stat *st);
+
/* Everything above this line is part of the PhysicsFS 2.1 API. */
--- a/src/physfs_internal.h Thu Feb 04 04:46:14 2010 -0500
+++ b/src/physfs_internal.h Sun Feb 14 23:07:19 2010 -0500
@@ -774,6 +774,12 @@
int (*exists)(dvoid *opaque, const char *name);
/*
+ * Returns zero if filename can be opened for reading and
+ * information was retreived. Non-zero otherwise.
+ */
+ int (*stat)(dvoid *opaque, const char *name, PHYSFS_Stat *st);
+
+ /*
* Returns non-zero if filename is really a directory.
* This filename is in platform-independent notation.
* Symlinks should be followed; if what the symlink points
@@ -1346,6 +1352,12 @@
/*
+ * !!! FIXME: comment me.
+ */
+int __PHYSFS_platformStat(const char *fname, PHYSFS_Stat *st);
+
+
+/*
* Convert (dirName) to platform-dependent notation, then prepend (prepend)
* and append (append) to the converted string.
*
--- a/src/platform_os2.c Thu Feb 04 04:46:14 2010 -0500
+++ b/src/platform_os2.c Sun Feb 14 23:07:19 2010 -0500
@@ -322,6 +322,12 @@
} /* __PHYSFS_platformIsDirectory */
+int __PHYSFS_platformStat(const char *fname, PHYSFS_Stat *st)
+{
+ return -1; /* !!! FIXME: write me */
+} /* __PHYSFS_platformStat */
+
+
/* !!! FIXME: can we lose the malloc here? */
char *__PHYSFS_platformCvtToDependent(const char *prepend,
const char *dirName,
--- a/src/platform_pocketpc.c Thu Feb 04 04:46:14 2010 -0500
+++ b/src/platform_pocketpc.c Sun Feb 14 23:07:19 2010 -0500
@@ -201,6 +201,12 @@
} /* __PHYSFS_platformIsDirectory */
+int __PHYSFS_platformStat(const char *fname, PHYSFS_Stat *st)
+{
+ return -1; /* !!! FIXME: write me */
+} /* __PHYSFS_platformStat */
+
+
char *__PHYSFS_platformCvtToDependent(const char *prepend,
const char *dirName,
const char *append)
--- a/src/platform_posix.c Thu Feb 04 04:46:14 2010 -0500
+++ b/src/platform_posix.c Sun Feb 14 23:07:19 2010 -0500
@@ -127,6 +127,27 @@
} /* __PHYSFS_platformIsDirectory */
+int __PHYSFS_platformStat(const char *fname, PHYSFS_Stat *st)
+{
+ int retval = 0;
+ struct stat pstat;
+
+ /* !!! FIXME: lstat()? */
+ retval = stat(fname, &pstat);
+ if (retval == 0)
+ {
+ st->size = pstat.st_size;
+ st->mtime = pstat.st_mtime;
+ st->atime = pstat.st_atime;
+ st->ctime = pstat.st_ctime;
+ st->is_symlink = S_ISLNK(pstat.st_mode) ? 1 : 0;
+ st->is_dir = S_ISDIR(pstat.st_mode) ? 1 : 0;
+ } /* if */
+
+ return(retval);
+} /* __PHYSFS_platformStat */
+
+
char *__PHYSFS_platformCvtToDependent(const char *prepend,
const char *dirName,
const char *append)
--- a/src/platform_windows.c Thu Feb 04 04:46:14 2010 -0500
+++ b/src/platform_windows.c Sun Feb 14 23:07:19 2010 -0500
@@ -23,6 +23,7 @@
#include <errno.h>
#include <ctype.h>
#include <time.h>
+#include <sys/stat.h>
#include "physfs_internal.h"
@@ -587,6 +588,29 @@
return retval;
} /* __PHYSFS_platformExists */
+int __PHYSFS_platformStat(const char *fname, PHYSFS_Stat *st)
+{
+ int retval = 0;
+ LPWSTR wpath;
+ struct _stat64 pstat;
+ UTF8_TO_UNICODE_STACK_MACRO(wpath, fname);
+ BAIL_IF_MACRO(wpath == NULL, ERR_OUT_OF_MEMORY, -1);
+
+ retval = _wstat64(wpath, &pstat);
+ if (retval == 0)
+ {
+ st->size = pstat.st_size;
+ st->mtime = pstat.st_mtime;
+ st->atime = pstat.st_atime;
+ st->ctime = pstat.st_ctime;
+ st->is_dir = (pstat.st_mode & _S_IFDIR) ? 1:0;
+ st->is_symlink = 0;
+ } /* if */
+
+ __PHYSFS_smallFree(wpath);
+ return(retval);
+} /* __PHYSFS_platformStat */
+
static int isSymlinkAttrs(const DWORD attr, const DWORD tag)
{