Added callback APIs and ripped up the internals everywhere to use them.
--- a/CHANGELOG Wed Sep 29 06:03:44 2004 +0000
+++ b/CHANGELOG Wed Sep 29 06:09:29 2004 +0000
@@ -2,6 +2,13 @@
* CHANGELOG.
*/
+09292004 - Every API that can return a list of strings can now use a
+ callback mechanism if the application wants to do it's own
+ allocation or handling on a per-item basis. The guts of those
+ APIs that create string lists now use the callbacks themselves to
+ build the lists, too. The callback functionality goes all the way
+ down to the archivers and platform drivers where appropriate, which
+ cleans things up and simplifies some internal tasks very nicely.
09262004 - Did the same thing to FileHandles than I did to DirHandles, but
this triggered massive tweaking in physfs.c. A lot of code got
little cleanups, which was nice. Less malloc pressure, too, since
--- a/TODO Wed Sep 29 06:03:44 2004 +0000
+++ b/TODO Wed Sep 29 06:09:29 2004 +0000
@@ -22,7 +22,6 @@
- Cygwin should use unix/posix and not win32 platform code.
- Add "mount points"
- Expose the archiver registration mechanism to the outside world.
-- Set up a mechanism for file enumeration that employs a callback.
- Allow the application to provide allocation services.
- Find some way to relax or remove the security model for external tools.
- Non-blocking I/O
@@ -41,7 +40,6 @@
- Deprecate PHYSFS_setSaneConfig and move it to extras?
- (Re)move the profiling code in physfs.c.
- Why is physfsrwops.c cut-and-pasted into the ruby bindings?
-- Get rid of addToLinkedStringList
- Replace code from SDL...
- MIX grabs all archives that no other archivers claim.
- MIX enumerates files as hash values.
--- a/archivers/dir.c Wed Sep 29 06:03:44 2004 +0000
+++ b/archivers/dir.c Wed Sep 29 06:09:29 2004 +0000
@@ -29,9 +29,9 @@
static int DIR_fileClose(fvoid *opaque);
static int DIR_isArchive(const char *filename, int forWriting);
static void *DIR_openArchive(const char *name, int forWriting);
-static LinkedStringList *DIR_enumerateFiles(dvoid *opaque,
- const char *dname,
- int omitSymLinks);
+static void DIR_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata);
static int DIR_exists(dvoid *opaque, const char *name);
static int DIR_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int DIR_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@@ -165,17 +165,16 @@
} /* DIR_openArchive */
-static LinkedStringList *DIR_enumerateFiles(dvoid *opaque,
- const char *dname,
- int omitSymLinks)
+static void DIR_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata)
{
char *d = __PHYSFS_platformCvtToDependent((char *)opaque, dname, NULL);
- LinkedStringList *retval;
-
- BAIL_IF_MACRO(d == NULL, NULL, NULL);
- retval = __PHYSFS_platformEnumerateFiles(d, omitSymLinks);
- free(d);
- return(retval);
+ if (d != NULL)
+ {
+ __PHYSFS_platformEnumerateFiles(d, omitSymLinks, cb, callbackdata);
+ free(d);
+ } /* if */
} /* DIR_enumerateFiles */
--- a/archivers/grp.c Wed Sep 29 06:03:44 2004 +0000
+++ b/archivers/grp.c Wed Sep 29 06:09:29 2004 +0000
@@ -72,9 +72,9 @@
static int GRP_fileClose(fvoid *opaque);
static int GRP_isArchive(const char *filename, int forWriting);
static void *GRP_openArchive(const char *name, int forWriting);
-static LinkedStringList *GRP_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks);
+static void GRP_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata);
static int GRP_exists(dvoid *opaque, const char *name);
static int GRP_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int GRP_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@@ -359,23 +359,21 @@
} /* GRP_openArchive */
-static LinkedStringList *GRP_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks)
+static void GRP_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata)
{
- GRPinfo *info = (GRPinfo *) opaque;
- GRPentry *entry = info->entries;
- LinkedStringList *retval = NULL, *p = NULL;
- PHYSFS_uint32 max = info->entryCount;
- PHYSFS_uint32 i;
+ /* no directories in GRP files. */
+ if (*dname != '\0')
+ {
+ GRPinfo *info = (GRPinfo *) opaque;
+ GRPentry *entry = info->entries;
+ PHYSFS_uint32 max = info->entryCount;
+ PHYSFS_uint32 i;
- /* no directories in GRP files. */
- BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL);
-
- for (i = 0; i < max; i++, entry++)
- retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1);
-
- return(retval);
+ for (i = 0; i < max; i++, entry++)
+ cb(callbackdata, entry->name);
+ } /* if */
} /* GRP_enumerateFiles */
--- a/archivers/hog.c Wed Sep 29 06:03:44 2004 +0000
+++ b/archivers/hog.c Wed Sep 29 06:09:29 2004 +0000
@@ -86,9 +86,9 @@
static int HOG_fileClose(fvoid *opaque);
static int HOG_isArchive(const char *filename, int forWriting);
static void *HOG_openArchive(const char *name, int forWriting);
-static LinkedStringList *HOG_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks);
+static void HOG_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata);
static int HOG_exists(dvoid *opaque, const char *name);
static int HOG_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int HOG_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@@ -398,23 +398,21 @@
} /* HOG_openArchive */
-static LinkedStringList *HOG_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks)
+static void HOG_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata)
{
- HOGinfo *info = ((HOGinfo *) opaque);
- HOGentry *entry = info->entries;
- LinkedStringList *retval = NULL, *p = NULL;
- PHYSFS_uint32 max = info->entryCount;
- PHYSFS_uint32 i;
+ /* no directories in HOG files. */
+ if (*dname != '\0')
+ {
+ HOGinfo *info = (HOGinfo *) opaque;
+ HOGentry *entry = info->entries;
+ PHYSFS_uint32 max = info->entryCount;
+ PHYSFS_uint32 i;
- /* no directories in HOG files. */
- BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL);
-
- for (i = 0; i < max; i++, entry++)
- retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1);
-
- return(retval);
+ for (i = 0; i < max; i++, entry++)
+ cb(callbackdata, entry->name);
+ } /* if */
} /* HOG_enumerateFiles */
--- a/archivers/mix.c Wed Sep 29 06:03:44 2004 +0000
+++ b/archivers/mix.c Wed Sep 29 06:09:29 2004 +0000
@@ -91,9 +91,9 @@
static int MIX_fileClose(fvoid *opaque);
static int MIX_isArchive(const char *filename, int forWriting);
static void *MIX_openArchive(const char *name, int forWriting);
-static LinkedStringList *MIX_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks);
+static void MIX_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata)
static int MIX_exists(dvoid *opaque, const char *name);
static int MIX_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int MIX_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@@ -354,23 +354,24 @@
} /* MIX_openArchive */
-static LinkedStringList *MIX_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks)
+static void MIX_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata)
{
- LinkedStringList *retval = NULL, *p = NULL;
- MIXinfo *info = (MIXinfo*) opaque;
- MIXentry *entry = info->entry;
- int i;
- char buffer[32];
+ /* no directories in MIX files. */
+ if (*dirname != '\0')
+ {
+ MIXinfo *info = (MIXinfo*) opaque;
+ MIXentry *entry = info->entry;
+ int i;
+ char buffer[32];
- for (i = 0; i < info->header.num_files; i++, entry++)
- {
- sprintf(buffer, "%X", entry->hash);
- retval = __PHYSFS_addToLinkedStringList(retval, &p, buffer, -1);
- } /* for */
-
- return(retval);
+ for (i = 0; i < info->header.num_files; i++, entry++)
+ {
+ sprintf(buffer, "%X", entry->hash);
+ cb(callbackdata, buffer);
+ } /* for */
+ } /* if */
} /* MIX_enumerateFiles */
--- a/archivers/mvl.c Wed Sep 29 06:03:44 2004 +0000
+++ b/archivers/mvl.c Wed Sep 29 06:09:29 2004 +0000
@@ -75,9 +75,9 @@
static int MVL_fileClose(fvoid *opaque);
static int MVL_isArchive(const char *filename, int forWriting);
static void *MVL_openArchive(const char *name, int forWriting);
-static LinkedStringList *MVL_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks);
+static void MVL_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata);
static int MVL_exists(dvoid *opaque, const char *name);
static int MVL_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int MVL_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@@ -356,23 +356,21 @@
} /* MVL_openArchive */
-static LinkedStringList *MVL_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks)
+static void MVL_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata)
{
- MVLinfo *info = ((MVLinfo *) opaque);
- MVLentry *entry = info->entries;
- LinkedStringList *retval = NULL, *p = NULL;
- PHYSFS_uint32 max = info->entryCount;
- PHYSFS_uint32 i;
+ /* no directories in MVL files. */
+ if (*dname != '\0')
+ {
+ MVLinfo *info = ((MVLinfo *) opaque);
+ MVLentry *entry = info->entries;
+ PHYSFS_uint32 max = info->entryCount;
+ PHYSFS_uint32 i;
- /* no directories in MVL files. */
- BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL);
-
- for (i = 0; i < max; i++, entry++)
- retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1);
-
- return(retval);
+ for (i = 0; i < max; i++, entry++)
+ cb(callbackdata, entry->name);
+ } /* if */
} /* MVL_enumerateFiles */
--- a/archivers/qpak.c Wed Sep 29 06:03:44 2004 +0000
+++ b/archivers/qpak.c Wed Sep 29 06:09:29 2004 +0000
@@ -89,9 +89,9 @@
static int QPAK_fileClose(fvoid *opaque);
static int QPAK_isArchive(const char *filename, int forWriting);
static void *QPAK_openArchive(const char *name, int forWriting);
-static LinkedStringList *QPAK_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks);
+static void QPAK_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata);
static int QPAK_exists(dvoid *opaque, const char *name);
static int QPAK_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int QPAK_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@@ -443,19 +443,36 @@
} /* qpak_find_start_of_dir */
-static LinkedStringList *QPAK_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks)
+/*
+ * Moved to seperate function so we can use alloca then immediately throw
+ * away the allocated stack space...
+ */
+static void doEnumCallback(PHYSFS_StringCallback cb, void *callbackdata,
+ const char *str, PHYSFS_sint32 ln)
+{
+ char *newstr = alloca(ln + 1);
+ if (newstr == NULL)
+ return;
+
+ memcpy(newstr, str, ln);
+ newstr[ln] = '\0';
+ cb(callbackdata, newstr);
+} /* doEnumCallback */
+
+
+static void QPAK_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata)
{
QPAKinfo *info = ((QPAKinfo *) opaque);
- LinkedStringList *retval = NULL, *p = NULL;
PHYSFS_sint32 dlen, dlen_inc, max, i;
- i = qpak_find_start_of_dir(info, dirname, 0);
- BAIL_IF_MACRO(i == -1, ERR_NO_SUCH_FILE, NULL);
+ i = qpak_find_start_of_dir(info, dname, 0);
+ if (i == -1) /* no such directory. */
+ return;
- dlen = strlen(dirname);
- if ((dlen > 0) && (dirname[dlen - 1] == '/')) /* ignore trailing slash. */
+ dlen = strlen(dname);
+ if ((dlen > 0) && (dname[dlen - 1] == '/')) /* ignore trailing slash. */
dlen--;
dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
@@ -466,13 +483,13 @@
char *ptr;
PHYSFS_sint32 ln;
char *e = info->entries[i].name;
- if ((dlen) && ((QPAK_strncmp(e, dirname, dlen)) || (e[dlen] != '/')))
+ if ((dlen) && ((QPAK_strncmp(e, dname, dlen)) || (e[dlen] != '/')))
break; /* past end of this dir; we're done. */
add = e + dlen_inc;
ptr = strchr(add, '/');
ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(add));
- retval = __PHYSFS_addToLinkedStringList(retval, &p, add, ln);
+ doEnumCallback(cb, callbackdata, add, ln);
ln += dlen_inc; /* point past entry to children... */
/* increment counter and skip children of subdirs... */
@@ -483,8 +500,6 @@
break;
} /* while */
} /* while */
-
- return(retval);
} /* QPAK_enumerateFiles */
--- a/archivers/wad.c Wed Sep 29 06:03:44 2004 +0000
+++ b/archivers/wad.c Wed Sep 29 06:09:29 2004 +0000
@@ -91,9 +91,9 @@
static int WAD_fileClose(fvoid *opaque);
static int WAD_isArchive(const char *filename, int forWriting);
static void *WAD_openArchive(const char *name, int forWriting);
-static LinkedStringList *WAD_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks);
+static void WAD_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata);
static int WAD_exists(dvoid *opaque, const char *name);
static int WAD_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int WAD_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@@ -386,45 +386,39 @@
} /* WAD_openArchive */
-static LinkedStringList *WAD_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks)
+static void WAD_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata)
{
WADinfo *info = ((WADinfo *) opaque);
WADentry *entry = info->entries;
- LinkedStringList *retval = NULL, *p = NULL;
PHYSFS_uint32 max = info->entryCount;
PHYSFS_uint32 i;
+ const char *name;
char *sep;
- if (dirname[0] == 0)
+ if (*dname == '\0') /* root directory enumeration? */
{
for (i = 0; i < max; i++, entry++)
{
- if (strchr(entry->name, '/') == NULL)
- {
- retval = __PHYSFS_addToLinkedStringList(retval, &p,
- entry->name, -1);
- } /* if */
+ name = entry->name;
+ if (strchr(name, '/') == NULL)
+ cb(callbackdata, name);
} /* for */
} /* if */
else
{
for (i = 0; i < max; i++, entry++)
{
- sep = strchr(entry->name, '/');
+ name = entry->name;
+ sep = strchr(name, '/');
if (sep != NULL)
{
- if (strncmp(dirname, entry->name, (sep-entry->name)) == 0)
- {
- retval = __PHYSFS_addToLinkedStringList(retval, &p,
- sep + 1, -1);
- } /* if */
+ if (strncmp(dname, name, (sep - name)) == 0)
+ cb(callbackdata, sep + 1);
} /* if */
} /* for */
} /* else */
-
- return(retval);
} /* WAD_enumerateFiles */
--- a/archivers/zip.c Wed Sep 29 06:03:44 2004 +0000
+++ b/archivers/zip.c Wed Sep 29 06:09:29 2004 +0000
@@ -127,9 +127,9 @@
static int ZIP_fileClose(fvoid *opaque);
static int ZIP_isArchive(const char *filename, int forWriting);
static void *ZIP_openArchive(const char *name, int forWriting);
-static LinkedStringList *ZIP_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks);
+static void ZIP_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata);
static int ZIP_exists(dvoid *opaque, const char *name);
static int ZIP_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int ZIP_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@@ -1235,19 +1235,36 @@
} /* zip_find_start_of_dir */
-static LinkedStringList *ZIP_enumerateFiles(dvoid *opaque,
- const char *dirname,
- int omitSymLinks)
+/*
+ * Moved to seperate function so we can use alloca then immediately throw
+ * away the allocated stack space...
+ */
+static void doEnumCallback(PHYSFS_StringCallback cb, void *callbackdata,
+ const char *str, PHYSFS_sint32 ln)
+{
+ char *newstr = alloca(ln + 1);
+ if (newstr == NULL)
+ return;
+
+ memcpy(newstr, str, ln);
+ newstr[ln] = '\0';
+ cb(callbackdata, newstr);
+} /* doEnumCallback */
+
+
+static void ZIP_enumerateFiles(dvoid *opaque, const char *dname,
+ int omitSymLinks, PHYSFS_StringCallback cb,
+ void *callbackdata)
{
ZIPinfo *info = ((ZIPinfo *) opaque);
- LinkedStringList *retval = NULL, *p = NULL;
PHYSFS_sint32 dlen, dlen_inc, max, i;
- i = zip_find_start_of_dir(info, dirname, 0);
- BAIL_IF_MACRO(i == -1, ERR_NO_SUCH_FILE, NULL);
+ i = zip_find_start_of_dir(info, dname, 0);
+ if (i == -1) /* no such directory. */
+ return;
- dlen = strlen(dirname);
- if ((dlen > 0) && (dirname[dlen - 1] == '/')) /* ignore trailing slash. */
+ dlen = strlen(dname);
+ if ((dlen > 0) && (dname[dlen - 1] == '/')) /* ignore trailing slash. */
dlen--;
dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
@@ -1255,7 +1272,7 @@
while (i < max)
{
char *e = info->entries[i].name;
- if ((dlen) && ((strncmp(e, dirname, dlen) != 0) || (e[dlen] != '/')))
+ if ((dlen) && ((strncmp(e, dname, dlen) != 0) || (e[dlen] != '/')))
break; /* past end of this dir; we're done. */
if ((omitSymLinks) && (zip_entry_is_symlink(&info->entries[i])))
@@ -1265,7 +1282,7 @@
char *add = e + dlen_inc;
char *ptr = strchr(add, '/');
PHYSFS_sint32 ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(add));
- retval = __PHYSFS_addToLinkedStringList(retval, &p, add, ln);
+ doEnumCallback(cb, callbackdata, add, ln);
ln += dlen_inc; /* point past entry to children... */
/* increment counter and skip children of subdirs... */
@@ -1277,8 +1294,6 @@
} /* while */
} /* else */
} /* while */
-
- return(retval);
} /* ZIP_enumerateFiles */
--- a/physfs.c Wed Sep 29 06:03:44 2004 +0000
+++ b/physfs.c Wed Sep 29 06:09:29 2004 +0000
@@ -189,6 +189,54 @@
/* functions ... */
+typedef struct
+{
+ char **list;
+ PHYSFS_uint32 size;
+ const char *errorstr;
+} EnumStringListCallbackData;
+
+static void enumStringListCallback(void *data, const char *str)
+{
+ void *ptr;
+ char *newstr;
+ EnumStringListCallbackData *pecd = (EnumStringListCallbackData *) data;
+
+ if (pecd->errorstr)
+ return;
+
+ ptr = realloc(pecd->list, (pecd->size + 2) * sizeof (char *));
+ newstr = malloc(strlen(str) + 1);
+ if (ptr != NULL)
+ pecd->list = (char **) ptr;
+
+ if ((ptr == NULL) || (newstr == NULL))
+ {
+ pecd->errorstr = ERR_OUT_OF_MEMORY;
+ pecd->list[pecd->size] = NULL;
+ PHYSFS_freeList(pecd->list);
+ return;
+ } /* if */
+
+ strcpy(newstr, str);
+ pecd->list[pecd->size] = newstr;
+ pecd->size++;
+} /* enumStringListCallback */
+
+
+static char **doEnumStringList(void (*func)(PHYSFS_StringCallback, void *))
+{
+ EnumStringListCallbackData ecd;
+ memset(&ecd, '\0', sizeof (ecd));
+ ecd.list = (char **) malloc(sizeof (char *));
+ BAIL_IF_MACRO(ecd.list == NULL, ERR_OUT_OF_MEMORY, NULL);
+ func(enumStringListCallback, &ecd);
+ BAIL_IF_MACRO(ecd.errorstr != NULL, ecd.errorstr, NULL);
+ ecd.list[ecd.size] = NULL;
+ return(ecd.list);
+} /* doEnumStringList */
+
+
static void __PHYSFS_bubble_sort(void *a, PHYSFS_uint32 lo, PHYSFS_uint32 hi,
int (*cmpfn)(void *, PHYSFS_uint32, PHYSFS_uint32),
void (*swapfn)(void *, PHYSFS_uint32, PHYSFS_uint32))
@@ -838,7 +886,6 @@
{
FileHandle *i;
FileHandle *next = NULL;
- FileHandle *h;
for (i = *list; i != NULL; i = next)
{
@@ -937,10 +984,16 @@
char **PHYSFS_getCdRomDirs(void)
{
- return(__PHYSFS_platformDetectAvailableCDs());
+ return(doEnumStringList(__PHYSFS_platformDetectAvailableCDs));
} /* PHYSFS_getCdRomDirs */
+void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback callback, void *data)
+{
+ __PHYSFS_platformDetectAvailableCDs(callback, data);
+} /* PHYSFS_getCdRomDirsCallback */
+
+
const char *PHYSFS_getBaseDir(void)
{
return(baseDir); /* this is calculated in PHYSFS_init()... */
@@ -1060,42 +1113,21 @@
char **PHYSFS_getSearchPath(void)
{
- int count = 1;
- int x;
+ return(doEnumStringList(PHYSFS_getSearchPathCallback));
+} /* PHYSFS_getSearchPath */
+
+
+void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback callback, void *data)
+{
DirHandle *i;
- char **retval;
__PHYSFS_platformGrabMutex(stateLock);
for (i = searchPath; i != NULL; i = i->next)
- count++;
-
- retval = (char **) malloc(sizeof (char *) * count);
- BAIL_IF_MACRO_MUTEX(!retval, ERR_OUT_OF_MEMORY, stateLock, NULL);
- count--;
- retval[count] = NULL;
-
- for (i = searchPath, x = 0; x < count; i = i->next, x++)
- {
- retval[x] = (char *) malloc(strlen(i->dirName) + 1);
- if (retval[x] == NULL) /* this is friggin' ugly. */
- {
- while (x > 0)
- {
- x--;
- free(retval[x]);
- } /* while */
-
- free(retval);
- BAIL_MACRO_MUTEX(ERR_OUT_OF_MEMORY, stateLock, NULL);
- } /* if */
-
- strcpy(retval[x], i->dirName);
- } /* for */
+ callback(data, i->dirName);
__PHYSFS_platformReleaseMutex(stateLock);
- return(retval);
-} /* PHYSFS_getSearchPath */
+} /* PHYSFS_getSearchPathCallback */
int PHYSFS_setSaneConfig(const char *organization, const char *appName,
@@ -1441,7 +1473,7 @@
return(retval);
} /* PHYSFS_getRealDir */
-
+#if 0
static int countList(LinkedStringList *list)
{
int retval = 0;
@@ -1529,34 +1561,114 @@
newList = next;
} /* while */
} /* interpolateStringLists */
+#endif
+
+
+static int locateInStringList(const char *str,
+ char **list,
+ PHYSFS_uint32 *pos)
+{
+ PHYSFS_uint32 hi = *pos - 1;
+ PHYSFS_uint32 lo = 0;
+ PHYSFS_uint32 i = hi / 2;
+ int cmp;
+
+ while (hi != lo)
+ {
+ cmp = strcmp(list[i], str);
+ if (cmp == 0) /* it's in the list already. */
+ return(1);
+ else if (cmp < 0)
+ hi = i;
+ else
+ lo = i;
+ i = lo + ((hi - lo) / 2);
+ } /* while */
+
+ /* hi == lo, check it in case it's the match... */
+ cmp = strcmp(list[lo], str);
+ if (cmp == 0)
+ return(1);
+
+ /* not in the list, set insertion point... */
+ *pos = (cmp < 0) ? lo : lo + 1;
+ return(0);
+} /* locateInStringList */
+
+
+static void enumFilesCallback(void *data, const char *str)
+{
+ PHYSFS_uint32 pos;
+ void *ptr;
+ char *newstr;
+ EnumStringListCallbackData *pecd = (EnumStringListCallbackData *) data;
+
+ /*
+ * See if file is in the list already, and if not, insert it in there
+ * alphabetically...
+ */
+ pos = pecd->size;
+ if (pos > 0)
+ {
+ if (locateInStringList(str, pecd->list, &pos))
+ return; /* already in the list. */
+ } /* if */
+
+ ptr = realloc(pecd->list, (pecd->size + 2) * sizeof (char *));
+ newstr = malloc(strlen(str) + 1);
+ if (ptr != NULL)
+ pecd->list = (char **) ptr;
+
+ if ((ptr == NULL) || (newstr == NULL))
+ return; /* better luck next time. */
+
+ strcpy(newstr, str);
+
+ if (pos != pecd->size)
+ {
+ memmove(&pecd->list[pos+1], &pecd->list[pos],
+ sizeof (char *) * ((pecd->size) - pos));
+ } /* if */
+
+ pecd->list[pos] = newstr;
+ pecd->size++;
+} /* enumFilesCallback */
char **PHYSFS_enumerateFiles(const char *path)
{
+ EnumStringListCallbackData ecd;
+ memset(&ecd, '\0', sizeof (ecd));
+ ecd.list = (char **) malloc(sizeof (char *));
+ BAIL_IF_MACRO(ecd.list == NULL, ERR_OUT_OF_MEMORY, NULL);
+ PHYSFS_enumerateFilesCallback(path, enumFilesCallback, &ecd);
+ ecd.list[ecd.size] = NULL;
+ return(ecd.list);
+} /* PHYSFS_enumerateFiles */
+
+
+void PHYSFS_enumerateFilesCallback(const char *path,
+ PHYSFS_StringCallback callback,
+ void *data)
+{
DirHandle *i;
- char **retval = NULL;
- LinkedStringList *rc;
- LinkedStringList *finalList = NULL;
- int omitSymLinks = !allowSymLinks;
-
- BAIL_IF_MACRO(path == NULL, ERR_INVALID_ARGUMENT, NULL);
+ int noSyms;
+
+ if ((path == NULL) || (callback == NULL))
+ return;
+
while (*path == '/')
path++;
__PHYSFS_platformGrabMutex(stateLock);
+ noSyms = !allowSymLinks;
for (i = searchPath; i != NULL; i = i->next)
{
if (__PHYSFS_verifySecurity(i, path, 0))
- {
- rc = i->funcs->enumerateFiles(i->opaque, path, omitSymLinks);
- interpolateStringLists(&finalList, rc);
- } /* if */
+ i->funcs->enumerateFiles(i->opaque, path, noSyms, callback, data);
} /* for */
__PHYSFS_platformReleaseMutex(stateLock);
-
- retval = convertStringListToPhysFSList(finalList);
- return(retval);
-} /* PHYSFS_enumerateFiles */
+} /* PHYSFS_enumerateFilesCallback */
int PHYSFS_exists(const char *fname)
@@ -2077,6 +2189,5 @@
return(&allocator);
} /* __PHYFS_getAllocator */
-
/* end of physfs.c ... */
--- a/physfs.h Wed Sep 29 06:03:44 2004 +0000
+++ b/physfs.h Wed Sep 29 06:09:29 2004 +0000
@@ -1874,6 +1874,22 @@
__EXPORT__ int PHYSFS_setAllocator(PHYSFS_Allocator *allocator);
+/*
+ * it is not safe to call physfs functions in these callbacks, as they may
+ * be holding non recursive mutexes.
+ */
+/* !!! FIXME: comment! */
+typedef void (*PHYSFS_StringCallback)(void *data, const char *);
+
+__EXPORT__ void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback c, void *d);
+
+__EXPORT__ void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback c, void *d);
+
+__EXPORT__ void PHYSFS_enumerateFilesCallback(const char *dir,
+ PHYSFS_StringCallback c,
+ void *d);
+
+
/* Everything above this line is part of the PhysicsFS 2.0 API. */
--- a/physfs_internal.h Wed Sep 29 06:03:44 2004 +0000
+++ b/physfs_internal.h Wed Sep 29 06:09:29 2004 +0000
@@ -979,17 +979,18 @@
void *(*openArchive)(const char *name, int forWriting);
/*
- * Returns a list of all files in dirname. Each element of this list
- * (and its "str" field) will be deallocated with the system's free()
- * function by the caller, so be sure to explicitly malloc() each
- * chunk. Omit symlinks if (omitSymLinks) is non-zero.
- * If you have a memory failure, return as much as you can.
- * This dirname is in platform-independent notation.
+ * List all files in (dirname). Each file is passed to (callback),
+ * where a copy is made if appropriate, so you should dispose of
+ * it properly upon return from the callback.
+ * You should omit symlinks if (omitSymLinks) is non-zero.
+ * If you have a failure, report as much as you can.
+ * (dirname) is in platform-independent notation.
*/
- LinkedStringList *(*enumerateFiles)(dvoid *opaque,
- const char *dirname,
- int omitSymLinks);
-
+ void (*enumerateFiles)(dvoid *opaque,
+ const char *dirname,
+ int omitSymLinks,
+ PHYSFS_StringCallback callback,
+ void *callbackdata);
/*
* Returns non-zero if filename can be opened for reading.
@@ -1445,10 +1446,13 @@
int __PHYSFS_platformClose(void *opaque);
/*
- * Platform implementation of PHYSFS_getCdRomDirs()...
- * See physfs.h. The retval should be freeable via PHYSFS_freeList().
+ * Platform implementation of PHYSFS_getCdRomDirsCallback()...
+ * CD directories are discovered and reported to the callback one at a time.
+ * Pointers passed to the callback are assumed to be invalid to the
+ * application after the callback returns, so you can free them or whatever.
+ * Callback does not assume results will be sorted in any meaningful way.
*/
-char **__PHYSFS_platformDetectAvailableCDs(void);
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data);
/*
* Calculate the base dir, if your platform needs special consideration.
@@ -1559,8 +1563,10 @@
* uses platform-independent notation. Note that ".", "..", and other
* metaentries should always be ignored.
*/
-LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks);
+void __PHYSFS_platformEnumerateFiles(const char *dirname,
+ int omitSymLinks,
+ PHYSFS_StringCallback callback,
+ void *callbackdata);
/*
--- a/platform/beos.cpp Wed Sep 29 06:03:44 2004 +0000
+++ b/platform/beos.cpp Wed Sep 29 06:09:29 2004 +0000
@@ -47,20 +47,6 @@
} /* __PHYSFS_platformDeinit */
-
-/* caller needs to malloc() mntpnt, and expect us to free() it. */
-static void addDisc(char *mntpnt, char ***discs, int *disccount)
-{
- char **tmp = (char **) realloc(*discs, sizeof (char *) * (*disccount + 1));
- if (tmp)
- {
- tmp[*disccount - 1] = mntpnt;
- *discs = tmp;
- (*disccount)++;
- } /* if */
-} /* addDisc */
-
-
static char *getMountPoint(const char *devname)
{
BVolumeRoster mounts;
@@ -101,10 +87,10 @@
* This function is lifted from Simple Directmedia Layer (SDL):
* http://www.libsdl.org/
*/
-static void tryDir(const char *dirname, char ***discs, int *disccount)
+static void tryDir(const char *d, PHYSFS_StringCallback callback, void *data)
{
BDirectory dir;
- dir.SetTo(dirname);
+ dir.SetTo(d);
if (dir.InitCheck() != B_NO_ERROR)
return;
@@ -127,7 +113,7 @@
if (entry.IsDirectory())
{
if (strcmp(e.name, "floppy") != 0)
- tryDir(name, discs, disccount);
+ tryDir(name, callback, data);
} /* if */
else
@@ -147,7 +133,10 @@
{
char *mntpnt = getMountPoint(name);
if (mntpnt != NULL)
- addDisc(mntpnt, discs, disccount);
+ {
+ callback(data, mntpnt);
+ free(mntpnt); /* !!! FIXME: lose this malloc! */
+ } /* if */
} /* if */
} /* if */
} /* if */
@@ -159,14 +148,9 @@
} /* tryDir */
-char **__PHYSFS_platformDetectAvailableCDs(void)
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
- char **retval = (char **) malloc(sizeof (char *));
- int cd_count = 1; /* We count the NULL entry. */
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
- tryDir("/dev/disk", &retval, &cd_count);
- retval[cd_count - 1] = NULL;
- return(retval);
+ tryDir("/dev/disk", cb, data);
} /* __PHYSFS_platformDetectAvailableCDs */
--- a/platform/macclassic.c Wed Sep 29 06:03:44 2004 +0000
+++ b/platform/macclassic.c Wed Sep 29 06:09:29 2004 +0000
@@ -177,17 +177,12 @@
* CD detection code is borrowed from Apple Technical Q&A DV18.
* http://developer.apple.com/qa/dv/dv18.html
*/
-char **__PHYSFS_platformDetectAvailableCDs(void)
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
+
DriverGestaltParam pb;
DrvQEl *dqp;
OSErr status;
- char **retval = (char **) malloc(sizeof (char *));
- int cd_count = 1;
-
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- *retval = NULL;
pb.csCode = kDriverGestaltCode;
pb.driverGestaltSelector = kdgDeviceType;
@@ -201,6 +196,7 @@
if ((status == noErr) && (pb.driverGestaltResponse == kdgCDType))
{
Str63 volName;
+ size_t size;
HParamBlockRec hpbr;
memset(&hpbr, '\0', sizeof (HParamBlockRec));
hpbr.volumeParam.ioNamePtr = volName;
@@ -208,27 +204,15 @@
hpbr.volumeParam.ioVolIndex = 0;
if (PBHGetVInfoSync(&hpbr) == noErr)
{
- char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
- if (tmp)
- {
- char *str = (char *) malloc(volName[0] + 1);
- retval = tmp;
- if (str != NULL)
- {
- memcpy(str, &volName[1], volName[0]);
- str[volName[0]] = '\0';
- retval[cd_count-1] = str;
- cd_count++;
- } /* if */
- } /* if */
+ size = (size_t) volName[0]; /* convert to ASCIZ string... */
+ memmove(&volName[0], &volName[1], size);
+ volName[size] = '\0';
+ cb(data, volName);
} /* if */
} /* if */
dqp = (DrvQEl *) dqp->qLink;
} /* while */
-
- retval[cd_count - 1] = NULL;
- return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
@@ -577,10 +561,12 @@
} /* __PHYSFS_platformTimeslice */
-LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks)
+/* returns int so we can use BAIL*MACRO... */
+static int macClassicEnumerateFiles(const char *dirname,
+ int omitSymLinks,
+ PHYSFS_StringCallback callback,
+ void *callbackdata)
{
- LinkedStringList *ret = NULL, *p = NULL;
UInt16 i;
UInt16 max;
FSSpec spec;
@@ -606,6 +592,7 @@
for (i = 1; i <= max; i++)
{
+ size_t size;
FSSpec aliasspec;
Boolean alias = 0;
Boolean folder = 0;
@@ -629,10 +616,20 @@
continue;
/* still here? Add it to the list. */
- ret = __PHYSFS_addToLinkedStringList(ret, &p, (const char *) &str255[1], str255[0]);
+ size = (size_t) str255[0]; /* (convert to ASCIZ string...) */
+ memmove(&str255[0], &str255[1], size);
+ str255[size] = '\0';
+ callback(callbackdata, str255);
} /* for */
+} /* macClassicEnumerateFiles */
- return(ret);
+
+void __PHYSFS_platformEnumerateFiles(const char *dirname,
+ int omitSymLinks,
+ PHYSFS_StringCallback callback,
+ void *callbackdata)
+{
+ macClassicEnumerateFiles(dirname, omitSymLinks, callback, callbackdata);
} /* __PHYSFS_platformEnumerateFiles */
--- a/platform/os2.c Wed Sep 29 06:03:44 2004 +0000
+++ b/platform/os2.c Wed Sep 29 06:09:29 2004 +0000
@@ -254,20 +254,12 @@
} /* is_cdrom_drive */
-char **__PHYSFS_platformDetectAvailableCDs(void)
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
- ULONG dummy;
- ULONG drivemap;
+ ULONG dummy = 0;
+ ULONG drivemap = 0;
ULONG i, bit;
- APIRET rc;
- char **retval;
- PHYSFS_uint32 cd_count = 1; /* we count the NULL entry. */
-
- retval = (char **) malloc(sizeof (char *));
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
- *retval = NULL;
-
- rc = DosQueryCurrentDisk(&dummy, &drivemap);
+ APIRET rc = DosQueryCurrentDisk(&dummy, &drivemap);
BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, retval);
for (i = 0, bit = 1; i < 26; i++, bit <<= 1)
@@ -276,27 +268,12 @@
{
if ((is_cdrom_drive(i)) && (disc_is_inserted(i)))
{
- char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
- if (tmp)
- {
- char *str = (char *) malloc(4);
- retval = tmp;
- retval[cd_count - 1] = str;
- if (str)
- {
- str[0] = ('A' + i);
- str[1] = ':';
- str[2] = '\\';
- str[3] = '\0';
- cd_count++;
- } /* if */
- } /* if */
+ char drive[4] = "x:\\";
+ drive[0] = ('A' + i);
+ cb(data, drive);
} /* if */
} /* if */
} /* for */
-
- retval[cd_count - 1] = NULL;
- return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
@@ -417,11 +394,12 @@
} /* __PHYSFS_platformCvtToDependent */
-LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks)
+void __PHYSFS_platformEnumerateFiles(const char *dirname,
+ int omitSymLinks,
+ PHYSFS_StringCallback callback,
+ void *callbackdata)
{
char spec[CCHMAXPATH];
- LinkedStringList *ret = NULL, *p = NULL;
FILEFINDBUF3 fb;
HDIR hdir = HDIR_CREATE;
ULONG count = 1;
@@ -439,13 +417,12 @@
while (count == 1)
{
if ((strcmp(fb.achName, ".") != 0) && (strcmp(fb.achName, "..") != 0))
- ret = __PHYSFS_addToLinkedStringList(ret, &p, fb.achName, -1);
+ callback(callbackdata, fb.achName);
DosFindNext(hdir, &fb, sizeof (fb), &count);
} /* while */
DosFindClose(hdir);
- return(ret);
} /* __PHYSFS_platformEnumerateFiles */
--- a/platform/pocketpc.c Wed Sep 29 06:03:44 2004 +0000
+++ b/platform/pocketpc.c Wed Sep 29 06:09:29 2004 +0000
@@ -67,52 +67,53 @@
static char *UnicodeToAsc(const wchar_t *w_str)
{
- char *str=NULL;
+ char *str = NULL;
- if(w_str!=NULL)
+ if (w_str != NULL)
{
- int len=wcslen(w_str)+1;
- str=(char *)malloc(len);
+ int len = wcslen(w_str) + 1;
+ str = (char *) malloc(len);
- if(WideCharToMultiByte(CP_ACP,0,w_str,-1,str,len,NULL,NULL)==0)
- { //Conversion failed
- free(str);
+ if (WideCharToMultiByte(CP_ACP,0,w_str,-1,str,len,NULL,NULL) == 0)
+ { /*Conversion failed */
+ free(str);
+ return(NULL);
+ } /* if */
+ else
+ { /* Conversion successful */
+ return(str);
+ } /* else */
+ } /* if */
+
+ else
+ { /* Given NULL string */
return NULL;
}
- else
- { //Conversion successful
- return(str);
- }
+} /* UnicodeToAsc */
- }
- else
- { //Given NULL string
- return NULL;
- }
-}
static wchar_t *AscToUnicode(const char *str)
{
- wchar_t *w_str=NULL;
- if(str!=NULL)
+ wchar_t *w_str = NULL;
+ if (str != NULL)
{
- int len=strlen(str)+1;
- w_str=(wchar_t *)malloc(sizeof(wchar_t)*len);
- if(MultiByteToWideChar(CP_ACP,0,str,-1,w_str,len)==0)
- {
- free(w_str);
- return NULL;
- }
+ int len = strlen(str) + 1;
+ w_str = (wchar_t *) malloc(sizeof (wchar_t) * len);
+ if (MultiByteToWideChar(CP_ACP,0,str,-1,w_str,len) == 0)
+ {
+ free(w_str);
+ return(NULL);
+ } /* if */
+ else
+ {
+ return(w_str);
+ } /* else */
+ } /* if */
else
{
- return(w_str);
- }
- }
- else
- {
- return NULL;
- }
-}
+ return(NULL);
+ } /* else */
+} /* AscToUnicode */
static char *getExePath()
@@ -177,9 +178,9 @@
} /* __PHYSFS_platformDeinit */
-char **__PHYSFS_platformDetectAvailableCDs(void)
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
- BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
+ /* no-op on this platform. */
} /* __PHYSFS_platformDetectAvailableCDs */
@@ -293,12 +294,11 @@
} /* __PHYSFS_platformTimeslice */
-LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks)
+void __PHYSFS_platformEnumerateFiles(const char *dirname,
+ int omitSymLinks,
+ PHYSFS_StringCallback callback,
+ void *callbackdata)
{
- LinkedStringList *retval = NULL;
- LinkedStringList *l = NULL;
- LinkedStringList *prev = NULL;
HANDLE dir;
WIN32_FIND_DATA ent;
char *SearchPath;
@@ -328,43 +328,29 @@
free(w_SearchPath);
free(SearchPath);
- if(dir == INVALID_HANDLE_VALUE)
- {
- return NULL;
- }
+ if (dir == INVALID_HANDLE_VALUE)
+ return;
do
{
+ const char *str;
+
if (wcscmp(ent.cFileName, L".") == 0)
continue;
if (wcscmp(ent.cFileName, L"..") == 0)
continue;
- l = (LinkedStringList *) malloc(sizeof (LinkedStringList));
- if (l == NULL)
+ /* !!! FIXME: avoid malloc in UnicodeToAsc? */
+ str = UnicodeToAsc(ent.cFileName);
+ if (str == NULL)
break;
- l->str=UnicodeToAsc(ent.cFileName);
-
- if (l->str == NULL)
- {
- free(l);
- break;
- }
-
-
- if (retval == NULL)
- retval = l;
- else
- prev->next = l;
-
- prev = l;
- l->next = NULL;
+ callback(callbackdata, str);
+ free(str);
} while (FindNextFile(dir, &ent) != 0);
FindClose(dir);
- return(retval);
} /* __PHYSFS_platformEnumerateFiles */
@@ -381,7 +367,6 @@
strcpy(retval,path);
return(retval);
-
} /* __PHYSFS_platformRealPath */
--- a/platform/posix.c Wed Sep 29 06:03:44 2004 +0000
+++ b/platform/posix.c Wed Sep 29 06:09:29 2004 +0000
@@ -225,22 +225,24 @@
-LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks)
+void __PHYSFS_platformEnumerateFiles(const char *dirname,
+ int omitSymLinks,
+ PHYSFS_StringCallback callback,
+ void *callbackdata)
{
- LinkedStringList *retval = NULL, *p = NULL;
DIR *dir;
struct dirent *ent;
int bufsize = 0;
char *buf = NULL;
int dlen = 0;
- if (omitSymLinks)
+ if (omitSymLinks) /* !!! FIXME: this malloc sucks. */
{
dlen = strlen(dirname);
bufsize = dlen + 256;
buf = (char *) malloc(bufsize);
- BAIL_IF_MACRO(buf == NULL, ERR_OUT_OF_MEMORY, NULL);
+ if (buf == NULL)
+ return;
strcpy(buf, dirname);
if (buf[dlen - 1] != '/')
{
@@ -255,7 +257,7 @@
{
if (buf != NULL)
free(buf);
- BAIL_IF_MACRO(1, strerror(errno), NULL);
+ return;
} /* if */
while ((ent = readdir(dir)) != NULL)
@@ -284,14 +286,13 @@
continue;
} /* if */
- retval = __PHYSFS_addToLinkedStringList(retval, &p, ent->d_name, -1);
+ callback(callbackdata, ent->d_name);
} /* while */
if (buf != NULL)
free(buf);
closedir(dir);
- return(retval);
} /* __PHYSFS_platformEnumerateFiles */
--- a/platform/skeleton.c Wed Sep 29 06:03:44 2004 +0000
+++ b/platform/skeleton.c Wed Sep 29 06:09:29 2004 +0000
@@ -32,9 +32,8 @@
} /* __PHYSFS_platformDeinit */
-char **__PHYSFS_platformDetectAvailableCDs(void)
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
- BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformDetectAvailableCDs */
@@ -105,10 +104,11 @@
} /* __PHYSFS_platformTimeslice */
-LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks)
+void __PHYSFS_platformEnumerateFiles(const char *dirname,
+ int omitSymLinks,
+ PHYSFS_StringCallback callback,
+ void *callbackdata)
{
- BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformEnumerateFiles */
--- a/platform/unix.c Wed Sep 29 06:03:44 2004 +0000
+++ b/platform/unix.c Wed Sep 29 06:09:29 2004 +0000
@@ -76,12 +76,8 @@
#ifdef PHYSFS_NO_CDROM_SUPPORT
/* Stub version for platforms without CD-ROM support. */
-char **__PHYSFS_platformDetectAvailableCDs(void)
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
- char **retval = (char **) malloc(sizeof (char *));
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
- *retval = NULL;
- return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
@@ -166,13 +162,11 @@
} /* darwinIsMountedDisc */
-char **__PHYSFS_platformDetectAvailableCDs(void)
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
const char *devPrefix = "/dev/";
int prefixLen = strlen(devPrefix);
mach_port_t masterPort = 0;
- char **retval = (char **) malloc(sizeof (char *));
- int cd_count = 1; /* We count the NULL entry. */
struct statfs *mntbufp;
int i, mounts;
@@ -191,38 +185,17 @@
dev += prefixLen;
if (darwinIsMountedDisc(dev, masterPort))
- {
- char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
- if (tmp)
- {
- retval = tmp;
- retval[cd_count - 1] = (char *) malloc(strlen(mnt) + 1);
- if (retval[cd_count - 1])
- {
- strcpy(retval[cd_count - 1], mnt);
- cd_count++;
- } /* if */
- } /* if */
- } /* if */
+ cb(data, mnt);
} /* for */
-
- retval[cd_count - 1] = NULL;
- return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
#elif (defined PHYSFS_HAVE_SYS_UCRED_H)
-char **__PHYSFS_platformDetectAvailableCDs(void)
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
- char **retval = (char **) malloc(sizeof (char *));
- int cd_count = 1; /* We count the NULL entry. */
+ int i;
struct statfs *mntbufp = NULL;
- int mounts;
- int i;
-
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- mounts = getmntinfo(&mntbufp, MNT_WAIT);
+ int mounts = getmntinfo(&mntbufp, MNT_WAIT);
for (i = 0; i < mounts; i++)
{
@@ -236,40 +209,23 @@
/* add other mount types here */
if (add_it)
- {
- char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
- if (tmp)
- {
- retval = tmp;
- retval[cd_count - 1] = (char *)
- malloc(strlen(mntbufp[i].f_mntonname) + 1);
- if (retval[cd_count - 1])
- {
- strcpy(retval[cd_count - 1], mntbufp[i].f_mntonname);
- cd_count++;
- } /* if */
- } /* if */
- } /* if */
+ cb(data, mntbufp[i].f_mntonname);
} /* for */
-
- retval[cd_count - 1] = NULL;
- return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
#elif (defined PHYSFS_HAVE_MNTENT_H)
-char **__PHYSFS_platformDetectAvailableCDs(void)
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
- char **retval = (char **) malloc(sizeof (char *));
- int cd_count = 1; /* We count the NULL entry. */
FILE *mounts = NULL;
struct mntent *ent = NULL;
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
-
- *retval = NULL;
mounts = setmntent("/etc/mtab", "r");
- BAIL_IF_MACRO(mounts == NULL, ERR_IO_ERROR, retval);
+ if (mounts == NULL)
+ {
+ __PHYSFS_setError(ERR_IO_ERROR);
+ return;
+ } /* if */
while ( (ent = getmntent(mounts)) != NULL )
{
@@ -280,25 +236,11 @@
/* add other mount types here */
if (add_it)
- {
- char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
- if (tmp)
- {
- retval = tmp;
- retval[cd_count-1] = (char *) malloc(strlen(ent->mnt_dir) + 1);
- if (retval[cd_count - 1])
- {
- strcpy(retval[cd_count - 1], ent->mnt_dir);
- cd_count++;
- } /* if */
- } /* if */
- } /* if */
+ cb(data, ent->mnt_dir);
} /* while */
endmntent(mounts);
- retval[cd_count - 1] = NULL;
- return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
#endif
--- a/platform/win32.c Wed Sep 29 06:03:44 2004 +0000
+++ b/platform/win32.c Wed Sep 29 06:09:29 2004 +0000
@@ -268,33 +268,17 @@
} /* mediaInDrive */
-char **__PHYSFS_platformDetectAvailableCDs(void)
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
- char **retval = (char **) malloc(sizeof (char *));
- int cd_count = 1; /* We count the NULL entry. */
char drive_str[4] = "x:\\";
-
- for (drive_str[0] = 'A'; drive_str[0] <= 'Z'; drive_str[0]++)
+ char ch;
+ for (ch = 'A'; ch <= 'Z'; ch++)
{
+ drive_str[0] = ch;
if (GetDriveType(drive_str) == DRIVE_CDROM && mediaInDrive(drive_str))
- {
- char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));
- if (tmp)
- {
- retval = tmp;
- retval[cd_count - 1] = (char *) malloc(4);
- if (retval[cd_count - 1])
- {
- strcpy(retval[cd_count - 1], drive_str);
- cd_count++;
- } /* if */
- } /* if */
- } /* if */
+ cb(data, drive_str);
} /* for */
-
- retval[cd_count - 1] = NULL;
- return(retval);
-} /* __PHYSFS_detectAvailableCDs */
+} /* __PHYSFS_platformDetectAvailableCDs */
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
@@ -454,18 +438,20 @@
} /* __PHYSFS_platformTimeslice */
-LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
- int omitSymLinks)
+void __PHYSFS_platformEnumerateFiles(const char *dirname,
+ int omitSymLinks,
+ PHYSFS_StringCallback callback,
+ void *callbackdata)
{
- LinkedStringList *retval = NULL, *p = NULL;
HANDLE dir;
WIN32_FIND_DATA ent;
+ size_t len = strlen(dirname);
char *SearchPath;
- size_t len = strlen(dirname);
/* Allocate a new string for path, maybe '\\', "*", and NULL terminator */
SearchPath = (char *) alloca(len + 3);
- BAIL_IF_MACRO(SearchPath == NULL, ERR_OUT_OF_MEMORY, NULL);
+ if (SearchPath == NULL)
+ return;
/* Copy current dirname */
strcpy(SearchPath, dirname);
@@ -481,11 +467,8 @@
strcat(SearchPath, "*");
dir = FindFirstFile(SearchPath, &ent);
- BAIL_IF_MACRO
- (
- dir == INVALID_HANDLE_VALUE,
- win32strerror(), NULL
- );
+ if (dir == INVALID_HANDLE_VALUE)
+ return;
do
{
@@ -495,11 +478,10 @@
if (strcmp(ent.cFileName, "..") == 0)
continue;
- retval = __PHYSFS_addToLinkedStringList(retval, &p, ent.cFileName, -1);
+ callback(callbackdata, ent.cFileName);
} while (FindNextFile(dir, &ent) != 0);
FindClose(dir);
- return(retval);
} /* __PHYSFS_platformEnumerateFiles */