Added callback APIs and ripped up the internals everywhere to use them.

This commit is contained in:
Ryan C. Gordon 2004-09-29 06:09:29 +00:00
parent 80535e9b83
commit c2765f8571
21 changed files with 492 additions and 468 deletions

View File

@ -2,6 +2,13 @@
* CHANGELOG. * 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 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 this triggered massive tweaking in physfs.c. A lot of code got
little cleanups, which was nice. Less malloc pressure, too, since little cleanups, which was nice. Less malloc pressure, too, since

2
TODO
View File

@ -22,7 +22,6 @@ Some might be dupes, some might be done already.
- Cygwin should use unix/posix and not win32 platform code. - Cygwin should use unix/posix and not win32 platform code.
- Add "mount points" - Add "mount points"
- Expose the archiver registration mechanism to the outside world. - 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. - Allow the application to provide allocation services.
- Find some way to relax or remove the security model for external tools. - Find some way to relax or remove the security model for external tools.
- Non-blocking I/O - Non-blocking I/O
@ -41,7 +40,6 @@ Some might be dupes, some might be done already.
- Deprecate PHYSFS_setSaneConfig and move it to extras? - Deprecate PHYSFS_setSaneConfig and move it to extras?
- (Re)move the profiling code in physfs.c. - (Re)move the profiling code in physfs.c.
- Why is physfsrwops.c cut-and-pasted into the ruby bindings? - Why is physfsrwops.c cut-and-pasted into the ruby bindings?
- Get rid of addToLinkedStringList
- Replace code from SDL... - Replace code from SDL...
- MIX grabs all archives that no other archivers claim. - MIX grabs all archives that no other archivers claim.
- MIX enumerates files as hash values. - MIX enumerates files as hash values.

View File

@ -29,9 +29,9 @@ static PHYSFS_sint64 DIR_fileLength(fvoid *opaque);
static int DIR_fileClose(fvoid *opaque); static int DIR_fileClose(fvoid *opaque);
static int DIR_isArchive(const char *filename, int forWriting); static int DIR_isArchive(const char *filename, int forWriting);
static void *DIR_openArchive(const char *name, int forWriting); static void *DIR_openArchive(const char *name, int forWriting);
static LinkedStringList *DIR_enumerateFiles(dvoid *opaque, static void DIR_enumerateFiles(dvoid *opaque, const char *dname,
const char *dname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks); void *callbackdata);
static int DIR_exists(dvoid *opaque, const char *name); static int DIR_exists(dvoid *opaque, const char *name);
static int DIR_isDirectory(dvoid *opaque, const char *name, int *fileExists); static int DIR_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int DIR_isSymLink(dvoid *opaque, const char *name, int *fileExists); static int DIR_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -165,17 +165,16 @@ static void *DIR_openArchive(const char *name, int forWriting)
} /* DIR_openArchive */ } /* DIR_openArchive */
static LinkedStringList *DIR_enumerateFiles(dvoid *opaque, static void DIR_enumerateFiles(dvoid *opaque, const char *dname,
const char *dname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks) void *callbackdata)
{ {
char *d = __PHYSFS_platformCvtToDependent((char *)opaque, dname, NULL); char *d = __PHYSFS_platformCvtToDependent((char *)opaque, dname, NULL);
LinkedStringList *retval; if (d != NULL)
{
BAIL_IF_MACRO(d == NULL, NULL, NULL); __PHYSFS_platformEnumerateFiles(d, omitSymLinks, cb, callbackdata);
retval = __PHYSFS_platformEnumerateFiles(d, omitSymLinks); free(d);
free(d); } /* if */
return(retval);
} /* DIR_enumerateFiles */ } /* DIR_enumerateFiles */

View File

@ -72,9 +72,9 @@ static PHYSFS_sint64 GRP_fileLength(fvoid *opaque);
static int GRP_fileClose(fvoid *opaque); static int GRP_fileClose(fvoid *opaque);
static int GRP_isArchive(const char *filename, int forWriting); static int GRP_isArchive(const char *filename, int forWriting);
static void *GRP_openArchive(const char *name, int forWriting); static void *GRP_openArchive(const char *name, int forWriting);
static LinkedStringList *GRP_enumerateFiles(dvoid *opaque, static void GRP_enumerateFiles(dvoid *opaque, const char *dname,
const char *dirname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks); void *callbackdata);
static int GRP_exists(dvoid *opaque, const char *name); static int GRP_exists(dvoid *opaque, const char *name);
static int GRP_isDirectory(dvoid *opaque, const char *name, int *fileExists); static int GRP_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int GRP_isSymLink(dvoid *opaque, const char *name, int *fileExists); static int GRP_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -359,23 +359,21 @@ GRP_openArchive_failed:
} /* GRP_openArchive */ } /* GRP_openArchive */
static LinkedStringList *GRP_enumerateFiles(dvoid *opaque, static void GRP_enumerateFiles(dvoid *opaque, const char *dname,
const char *dirname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks) 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. */ /* no directories in GRP files. */
BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL); if (*dname != '\0')
{
GRPinfo *info = (GRPinfo *) opaque;
GRPentry *entry = info->entries;
PHYSFS_uint32 max = info->entryCount;
PHYSFS_uint32 i;
for (i = 0; i < max; i++, entry++) for (i = 0; i < max; i++, entry++)
retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1); cb(callbackdata, entry->name);
} /* if */
return(retval);
} /* GRP_enumerateFiles */ } /* GRP_enumerateFiles */

View File

@ -86,9 +86,9 @@ static PHYSFS_sint64 HOG_fileLength(fvoid *opaque);
static int HOG_fileClose(fvoid *opaque); static int HOG_fileClose(fvoid *opaque);
static int HOG_isArchive(const char *filename, int forWriting); static int HOG_isArchive(const char *filename, int forWriting);
static void *HOG_openArchive(const char *name, int forWriting); static void *HOG_openArchive(const char *name, int forWriting);
static LinkedStringList *HOG_enumerateFiles(dvoid *opaque, static void HOG_enumerateFiles(dvoid *opaque, const char *dname,
const char *dirname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks); void *callbackdata);
static int HOG_exists(dvoid *opaque, const char *name); static int HOG_exists(dvoid *opaque, const char *name);
static int HOG_isDirectory(dvoid *opaque, const char *name, int *fileExists); static int HOG_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int HOG_isSymLink(dvoid *opaque, const char *name, int *fileExists); static int HOG_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -398,23 +398,21 @@ HOG_openArchive_failed:
} /* HOG_openArchive */ } /* HOG_openArchive */
static LinkedStringList *HOG_enumerateFiles(dvoid *opaque, static void HOG_enumerateFiles(dvoid *opaque, const char *dname,
const char *dirname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks) 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. */ /* no directories in HOG files. */
BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL); if (*dname != '\0')
{
HOGinfo *info = (HOGinfo *) opaque;
HOGentry *entry = info->entries;
PHYSFS_uint32 max = info->entryCount;
PHYSFS_uint32 i;
for (i = 0; i < max; i++, entry++) for (i = 0; i < max; i++, entry++)
retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1); cb(callbackdata, entry->name);
} /* if */
return(retval);
} /* HOG_enumerateFiles */ } /* HOG_enumerateFiles */

View File

@ -91,9 +91,9 @@ static PHYSFS_sint64 MIX_fileLength(fvoid *opaque);
static int MIX_fileClose(fvoid *opaque); static int MIX_fileClose(fvoid *opaque);
static int MIX_isArchive(const char *filename, int forWriting); static int MIX_isArchive(const char *filename, int forWriting);
static void *MIX_openArchive(const char *name, int forWriting); static void *MIX_openArchive(const char *name, int forWriting);
static LinkedStringList *MIX_enumerateFiles(dvoid *opaque, static void MIX_enumerateFiles(dvoid *opaque, const char *dname,
const char *dirname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks); void *callbackdata)
static int MIX_exists(dvoid *opaque, const char *name); static int MIX_exists(dvoid *opaque, const char *name);
static int MIX_isDirectory(dvoid *opaque, const char *name, int *fileExists); static int MIX_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int MIX_isSymLink(dvoid *opaque, const char *name, int *fileExists); static int MIX_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -354,23 +354,24 @@ MIX_openArchive_failed:
} /* MIX_openArchive */ } /* MIX_openArchive */
static LinkedStringList *MIX_enumerateFiles(dvoid *opaque, static void MIX_enumerateFiles(dvoid *opaque, const char *dname,
const char *dirname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks) void *callbackdata)
{ {
LinkedStringList *retval = NULL, *p = NULL; /* no directories in MIX files. */
MIXinfo *info = (MIXinfo*) opaque; if (*dirname != '\0')
MIXentry *entry = info->entry;
int i;
char buffer[32];
for (i = 0; i < info->header.num_files; i++, entry++)
{ {
sprintf(buffer, "%X", entry->hash); MIXinfo *info = (MIXinfo*) opaque;
retval = __PHYSFS_addToLinkedStringList(retval, &p, buffer, -1); MIXentry *entry = info->entry;
} /* for */ int i;
char buffer[32];
return(retval);
for (i = 0; i < info->header.num_files; i++, entry++)
{
sprintf(buffer, "%X", entry->hash);
cb(callbackdata, buffer);
} /* for */
} /* if */
} /* MIX_enumerateFiles */ } /* MIX_enumerateFiles */

View File

@ -75,9 +75,9 @@ static PHYSFS_sint64 MVL_fileLength(fvoid *opaque);
static int MVL_fileClose(fvoid *opaque); static int MVL_fileClose(fvoid *opaque);
static int MVL_isArchive(const char *filename, int forWriting); static int MVL_isArchive(const char *filename, int forWriting);
static void *MVL_openArchive(const char *name, int forWriting); static void *MVL_openArchive(const char *name, int forWriting);
static LinkedStringList *MVL_enumerateFiles(dvoid *opaque, static void MVL_enumerateFiles(dvoid *opaque, const char *dname,
const char *dirname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks); void *callbackdata);
static int MVL_exists(dvoid *opaque, const char *name); static int MVL_exists(dvoid *opaque, const char *name);
static int MVL_isDirectory(dvoid *opaque, const char *name, int *fileExists); static int MVL_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int MVL_isSymLink(dvoid *opaque, const char *name, int *fileExists); static int MVL_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -356,23 +356,21 @@ MVL_openArchive_failed:
} /* MVL_openArchive */ } /* MVL_openArchive */
static LinkedStringList *MVL_enumerateFiles(dvoid *opaque, static void MVL_enumerateFiles(dvoid *opaque, const char *dname,
const char *dirname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks) 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. */ /* no directories in MVL files. */
BAIL_IF_MACRO(*dirname != '\0', ERR_NOT_A_DIR, NULL); if (*dname != '\0')
{
MVLinfo *info = ((MVLinfo *) opaque);
MVLentry *entry = info->entries;
PHYSFS_uint32 max = info->entryCount;
PHYSFS_uint32 i;
for (i = 0; i < max; i++, entry++) for (i = 0; i < max; i++, entry++)
retval = __PHYSFS_addToLinkedStringList(retval, &p, entry->name, -1); cb(callbackdata, entry->name);
} /* if */
return(retval);
} /* MVL_enumerateFiles */ } /* MVL_enumerateFiles */

View File

@ -89,9 +89,9 @@ static PHYSFS_sint64 QPAK_fileLength(fvoid *opaque);
static int QPAK_fileClose(fvoid *opaque); static int QPAK_fileClose(fvoid *opaque);
static int QPAK_isArchive(const char *filename, int forWriting); static int QPAK_isArchive(const char *filename, int forWriting);
static void *QPAK_openArchive(const char *name, int forWriting); static void *QPAK_openArchive(const char *name, int forWriting);
static LinkedStringList *QPAK_enumerateFiles(dvoid *opaque, static void QPAK_enumerateFiles(dvoid *opaque, const char *dname,
const char *dirname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks); void *callbackdata);
static int QPAK_exists(dvoid *opaque, const char *name); static int QPAK_exists(dvoid *opaque, const char *name);
static int QPAK_isDirectory(dvoid *opaque, const char *name, int *fileExists); static int QPAK_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int QPAK_isSymLink(dvoid *opaque, const char *name, int *fileExists); static int QPAK_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -443,19 +443,36 @@ static PHYSFS_sint32 qpak_find_start_of_dir(QPAKinfo *info, const char *path,
} /* qpak_find_start_of_dir */ } /* qpak_find_start_of_dir */
static LinkedStringList *QPAK_enumerateFiles(dvoid *opaque, /*
const char *dirname, * Moved to seperate function so we can use alloca then immediately throw
int omitSymLinks) * 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); QPAKinfo *info = ((QPAKinfo *) opaque);
LinkedStringList *retval = NULL, *p = NULL;
PHYSFS_sint32 dlen, dlen_inc, max, i; PHYSFS_sint32 dlen, dlen_inc, max, i;
i = qpak_find_start_of_dir(info, dirname, 0); i = qpak_find_start_of_dir(info, dname, 0);
BAIL_IF_MACRO(i == -1, ERR_NO_SUCH_FILE, NULL); if (i == -1) /* no such directory. */
return;
dlen = strlen(dirname); dlen = strlen(dname);
if ((dlen > 0) && (dirname[dlen - 1] == '/')) /* ignore trailing slash. */ if ((dlen > 0) && (dname[dlen - 1] == '/')) /* ignore trailing slash. */
dlen--; dlen--;
dlen_inc = ((dlen > 0) ? 1 : 0) + dlen; dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
@ -466,13 +483,13 @@ static LinkedStringList *QPAK_enumerateFiles(dvoid *opaque,
char *ptr; char *ptr;
PHYSFS_sint32 ln; PHYSFS_sint32 ln;
char *e = info->entries[i].name; 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. */ break; /* past end of this dir; we're done. */
add = e + dlen_inc; add = e + dlen_inc;
ptr = strchr(add, '/'); ptr = strchr(add, '/');
ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(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... */ ln += dlen_inc; /* point past entry to children... */
/* increment counter and skip children of subdirs... */ /* increment counter and skip children of subdirs... */
@ -483,8 +500,6 @@ static LinkedStringList *QPAK_enumerateFiles(dvoid *opaque,
break; break;
} /* while */ } /* while */
} /* while */ } /* while */
return(retval);
} /* QPAK_enumerateFiles */ } /* QPAK_enumerateFiles */

View File

@ -91,9 +91,9 @@ static PHYSFS_sint64 WAD_fileLength(fvoid *opaque);
static int WAD_fileClose(fvoid *opaque); static int WAD_fileClose(fvoid *opaque);
static int WAD_isArchive(const char *filename, int forWriting); static int WAD_isArchive(const char *filename, int forWriting);
static void *WAD_openArchive(const char *name, int forWriting); static void *WAD_openArchive(const char *name, int forWriting);
static LinkedStringList *WAD_enumerateFiles(dvoid *opaque, static void WAD_enumerateFiles(dvoid *opaque, const char *dname,
const char *dirname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks); void *callbackdata);
static int WAD_exists(dvoid *opaque, const char *name); static int WAD_exists(dvoid *opaque, const char *name);
static int WAD_isDirectory(dvoid *opaque, const char *name, int *fileExists); static int WAD_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int WAD_isSymLink(dvoid *opaque, const char *name, int *fileExists); static int WAD_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -386,45 +386,39 @@ WAD_openArchive_failed:
} /* WAD_openArchive */ } /* WAD_openArchive */
static LinkedStringList *WAD_enumerateFiles(dvoid *opaque, static void WAD_enumerateFiles(dvoid *opaque, const char *dname,
const char *dirname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks) void *callbackdata)
{ {
WADinfo *info = ((WADinfo *) opaque); WADinfo *info = ((WADinfo *) opaque);
WADentry *entry = info->entries; WADentry *entry = info->entries;
LinkedStringList *retval = NULL, *p = NULL;
PHYSFS_uint32 max = info->entryCount; PHYSFS_uint32 max = info->entryCount;
PHYSFS_uint32 i; PHYSFS_uint32 i;
const char *name;
char *sep; char *sep;
if (dirname[0] == 0) if (*dname == '\0') /* root directory enumeration? */
{ {
for (i = 0; i < max; i++, entry++) for (i = 0; i < max; i++, entry++)
{ {
if (strchr(entry->name, '/') == NULL) name = entry->name;
{ if (strchr(name, '/') == NULL)
retval = __PHYSFS_addToLinkedStringList(retval, &p, cb(callbackdata, name);
entry->name, -1);
} /* if */
} /* for */ } /* for */
} /* if */ } /* if */
else else
{ {
for (i = 0; i < max; i++, entry++) for (i = 0; i < max; i++, entry++)
{ {
sep = strchr(entry->name, '/'); name = entry->name;
sep = strchr(name, '/');
if (sep != NULL) if (sep != NULL)
{ {
if (strncmp(dirname, entry->name, (sep-entry->name)) == 0) if (strncmp(dname, name, (sep - name)) == 0)
{ cb(callbackdata, sep + 1);
retval = __PHYSFS_addToLinkedStringList(retval, &p,
sep + 1, -1);
} /* if */
} /* if */ } /* if */
} /* for */ } /* for */
} /* else */ } /* else */
return(retval);
} /* WAD_enumerateFiles */ } /* WAD_enumerateFiles */

View File

@ -127,9 +127,9 @@ static PHYSFS_sint64 ZIP_fileLength(fvoid *opaque);
static int ZIP_fileClose(fvoid *opaque); static int ZIP_fileClose(fvoid *opaque);
static int ZIP_isArchive(const char *filename, int forWriting); static int ZIP_isArchive(const char *filename, int forWriting);
static void *ZIP_openArchive(const char *name, int forWriting); static void *ZIP_openArchive(const char *name, int forWriting);
static LinkedStringList *ZIP_enumerateFiles(dvoid *opaque, static void ZIP_enumerateFiles(dvoid *opaque, const char *dname,
const char *dirname, int omitSymLinks, PHYSFS_StringCallback cb,
int omitSymLinks); void *callbackdata);
static int ZIP_exists(dvoid *opaque, const char *name); static int ZIP_exists(dvoid *opaque, const char *name);
static int ZIP_isDirectory(dvoid *opaque, const char *name, int *fileExists); static int ZIP_isDirectory(dvoid *opaque, const char *name, int *fileExists);
static int ZIP_isSymLink(dvoid *opaque, const char *name, int *fileExists); static int ZIP_isSymLink(dvoid *opaque, const char *name, int *fileExists);
@ -1235,19 +1235,36 @@ static PHYSFS_sint32 zip_find_start_of_dir(ZIPinfo *info, const char *path,
} /* zip_find_start_of_dir */ } /* zip_find_start_of_dir */
static LinkedStringList *ZIP_enumerateFiles(dvoid *opaque, /*
const char *dirname, * Moved to seperate function so we can use alloca then immediately throw
int omitSymLinks) * 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); ZIPinfo *info = ((ZIPinfo *) opaque);
LinkedStringList *retval = NULL, *p = NULL;
PHYSFS_sint32 dlen, dlen_inc, max, i; PHYSFS_sint32 dlen, dlen_inc, max, i;
i = zip_find_start_of_dir(info, dirname, 0); i = zip_find_start_of_dir(info, dname, 0);
BAIL_IF_MACRO(i == -1, ERR_NO_SUCH_FILE, NULL); if (i == -1) /* no such directory. */
return;
dlen = strlen(dirname); dlen = strlen(dname);
if ((dlen > 0) && (dirname[dlen - 1] == '/')) /* ignore trailing slash. */ if ((dlen > 0) && (dname[dlen - 1] == '/')) /* ignore trailing slash. */
dlen--; dlen--;
dlen_inc = ((dlen > 0) ? 1 : 0) + dlen; dlen_inc = ((dlen > 0) ? 1 : 0) + dlen;
@ -1255,7 +1272,7 @@ static LinkedStringList *ZIP_enumerateFiles(dvoid *opaque,
while (i < max) while (i < max)
{ {
char *e = info->entries[i].name; 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. */ break; /* past end of this dir; we're done. */
if ((omitSymLinks) && (zip_entry_is_symlink(&info->entries[i]))) if ((omitSymLinks) && (zip_entry_is_symlink(&info->entries[i])))
@ -1265,7 +1282,7 @@ static LinkedStringList *ZIP_enumerateFiles(dvoid *opaque,
char *add = e + dlen_inc; char *add = e + dlen_inc;
char *ptr = strchr(add, '/'); char *ptr = strchr(add, '/');
PHYSFS_sint32 ln = (PHYSFS_sint32) ((ptr) ? ptr-add : strlen(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... */ ln += dlen_inc; /* point past entry to children... */
/* increment counter and skip children of subdirs... */ /* increment counter and skip children of subdirs... */
@ -1277,8 +1294,6 @@ static LinkedStringList *ZIP_enumerateFiles(dvoid *opaque,
} /* while */ } /* while */
} /* else */ } /* else */
} /* while */ } /* while */
return(retval);
} /* ZIP_enumerateFiles */ } /* ZIP_enumerateFiles */

205
physfs.c
View File

@ -189,6 +189,54 @@ static PHYSFS_Allocator allocator;
/* functions ... */ /* 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, static void __PHYSFS_bubble_sort(void *a, PHYSFS_uint32 lo, PHYSFS_uint32 hi,
int (*cmpfn)(void *, PHYSFS_uint32, PHYSFS_uint32), int (*cmpfn)(void *, PHYSFS_uint32, PHYSFS_uint32),
void (*swapfn)(void *, PHYSFS_uint32, PHYSFS_uint32)) void (*swapfn)(void *, PHYSFS_uint32, PHYSFS_uint32))
@ -838,7 +886,6 @@ static int closeFileHandleList(FileHandle **list)
{ {
FileHandle *i; FileHandle *i;
FileHandle *next = NULL; FileHandle *next = NULL;
FileHandle *h;
for (i = *list; i != NULL; i = next) for (i = *list; i != NULL; i = next)
{ {
@ -937,10 +984,16 @@ const char *PHYSFS_getDirSeparator(void)
char **PHYSFS_getCdRomDirs(void) char **PHYSFS_getCdRomDirs(void)
{ {
return(__PHYSFS_platformDetectAvailableCDs()); return(doEnumStringList(__PHYSFS_platformDetectAvailableCDs));
} /* PHYSFS_getCdRomDirs */ } /* PHYSFS_getCdRomDirs */
void PHYSFS_getCdRomDirsCallback(PHYSFS_StringCallback callback, void *data)
{
__PHYSFS_platformDetectAvailableCDs(callback, data);
} /* PHYSFS_getCdRomDirsCallback */
const char *PHYSFS_getBaseDir(void) const char *PHYSFS_getBaseDir(void)
{ {
return(baseDir); /* this is calculated in PHYSFS_init()... */ return(baseDir); /* this is calculated in PHYSFS_init()... */
@ -1060,42 +1113,21 @@ int PHYSFS_removeFromSearchPath(const char *oldDir)
char **PHYSFS_getSearchPath(void) char **PHYSFS_getSearchPath(void)
{ {
int count = 1; return(doEnumStringList(PHYSFS_getSearchPathCallback));
int x; } /* PHYSFS_getSearchPath */
void PHYSFS_getSearchPathCallback(PHYSFS_StringCallback callback, void *data)
{
DirHandle *i; DirHandle *i;
char **retval;
__PHYSFS_platformGrabMutex(stateLock); __PHYSFS_platformGrabMutex(stateLock);
for (i = searchPath; i != NULL; i = i->next) for (i = searchPath; i != NULL; i = i->next)
count++; callback(data, i->dirName);
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 */
__PHYSFS_platformReleaseMutex(stateLock); __PHYSFS_platformReleaseMutex(stateLock);
return(retval); } /* PHYSFS_getSearchPathCallback */
} /* PHYSFS_getSearchPath */
int PHYSFS_setSaneConfig(const char *organization, const char *appName, int PHYSFS_setSaneConfig(const char *organization, const char *appName,
@ -1441,7 +1473,7 @@ const char *PHYSFS_getRealDir(const char *filename)
return(retval); return(retval);
} /* PHYSFS_getRealDir */ } /* PHYSFS_getRealDir */
#if 0
static int countList(LinkedStringList *list) static int countList(LinkedStringList *list)
{ {
int retval = 0; int retval = 0;
@ -1529,34 +1561,114 @@ static void interpolateStringLists(LinkedStringList **final,
newList = next; newList = next;
} /* while */ } /* while */
} /* interpolateStringLists */ } /* 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) char **PHYSFS_enumerateFiles(const char *path)
{ {
DirHandle *i; EnumStringListCallbackData ecd;
char **retval = NULL; memset(&ecd, '\0', sizeof (ecd));
LinkedStringList *rc; ecd.list = (char **) malloc(sizeof (char *));
LinkedStringList *finalList = NULL; BAIL_IF_MACRO(ecd.list == NULL, ERR_OUT_OF_MEMORY, NULL);
int omitSymLinks = !allowSymLinks; 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;
int noSyms;
if ((path == NULL) || (callback == NULL))
return;
BAIL_IF_MACRO(path == NULL, ERR_INVALID_ARGUMENT, NULL);
while (*path == '/') while (*path == '/')
path++; path++;
__PHYSFS_platformGrabMutex(stateLock); __PHYSFS_platformGrabMutex(stateLock);
noSyms = !allowSymLinks;
for (i = searchPath; i != NULL; i = i->next) for (i = searchPath; i != NULL; i = i->next)
{ {
if (__PHYSFS_verifySecurity(i, path, 0)) if (__PHYSFS_verifySecurity(i, path, 0))
{ i->funcs->enumerateFiles(i->opaque, path, noSyms, callback, data);
rc = i->funcs->enumerateFiles(i->opaque, path, omitSymLinks);
interpolateStringLists(&finalList, rc);
} /* if */
} /* for */ } /* for */
__PHYSFS_platformReleaseMutex(stateLock); __PHYSFS_platformReleaseMutex(stateLock);
} /* PHYSFS_enumerateFilesCallback */
retval = convertStringListToPhysFSList(finalList);
return(retval);
} /* PHYSFS_enumerateFiles */
int PHYSFS_exists(const char *fname) int PHYSFS_exists(const char *fname)
@ -2077,6 +2189,5 @@ PHYSFS_Allocator *__PHYSFS_getAllocator(void)
return(&allocator); return(&allocator);
} /* __PHYFS_getAllocator */ } /* __PHYFS_getAllocator */
/* end of physfs.c ... */ /* end of physfs.c ... */

View File

@ -1874,6 +1874,22 @@ typedef struct
__EXPORT__ int PHYSFS_setAllocator(PHYSFS_Allocator *allocator); __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. */ /* Everything above this line is part of the PhysicsFS 2.0 API. */

View File

@ -979,17 +979,18 @@ typedef struct
void *(*openArchive)(const char *name, int forWriting); void *(*openArchive)(const char *name, int forWriting);
/* /*
* Returns a list of all files in dirname. Each element of this list * List all files in (dirname). Each file is passed to (callback),
* (and its "str" field) will be deallocated with the system's free() * where a copy is made if appropriate, so you should dispose of
* function by the caller, so be sure to explicitly malloc() each * it properly upon return from the callback.
* chunk. Omit symlinks if (omitSymLinks) is non-zero. * You should omit symlinks if (omitSymLinks) is non-zero.
* If you have a memory failure, return as much as you can. * If you have a failure, report as much as you can.
* This dirname is in platform-independent notation. * (dirname) is in platform-independent notation.
*/ */
LinkedStringList *(*enumerateFiles)(dvoid *opaque, void (*enumerateFiles)(dvoid *opaque,
const char *dirname, const char *dirname,
int omitSymLinks); int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata);
/* /*
* Returns non-zero if filename can be opened for reading. * Returns non-zero if filename can be opened for reading.
@ -1445,10 +1446,13 @@ int __PHYSFS_platformFlush(void *opaque);
int __PHYSFS_platformClose(void *opaque); int __PHYSFS_platformClose(void *opaque);
/* /*
* Platform implementation of PHYSFS_getCdRomDirs()... * Platform implementation of PHYSFS_getCdRomDirsCallback()...
* See physfs.h. The retval should be freeable via PHYSFS_freeList(). * 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. * Calculate the base dir, if your platform needs special consideration.
@ -1559,8 +1563,10 @@ void __PHYSFS_platformTimeslice(void);
* uses platform-independent notation. Note that ".", "..", and other * uses platform-independent notation. Note that ".", "..", and other
* metaentries should always be ignored. * metaentries should always be ignored.
*/ */
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname, void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks); int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata);
/* /*

View File

@ -47,20 +47,6 @@ int __PHYSFS_platformDeinit(void)
} /* __PHYSFS_platformDeinit */ } /* __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) static char *getMountPoint(const char *devname)
{ {
BVolumeRoster mounts; BVolumeRoster mounts;
@ -101,10 +87,10 @@ static char *getMountPoint(const char *devname)
* This function is lifted from Simple Directmedia Layer (SDL): * This function is lifted from Simple Directmedia Layer (SDL):
* http://www.libsdl.org/ * 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; BDirectory dir;
dir.SetTo(dirname); dir.SetTo(d);
if (dir.InitCheck() != B_NO_ERROR) if (dir.InitCheck() != B_NO_ERROR)
return; return;
@ -127,7 +113,7 @@ static void tryDir(const char *dirname, char ***discs, int *disccount)
if (entry.IsDirectory()) if (entry.IsDirectory())
{ {
if (strcmp(e.name, "floppy") != 0) if (strcmp(e.name, "floppy") != 0)
tryDir(name, discs, disccount); tryDir(name, callback, data);
} /* if */ } /* if */
else else
@ -147,7 +133,10 @@ static void tryDir(const char *dirname, char ***discs, int *disccount)
{ {
char *mntpnt = getMountPoint(name); char *mntpnt = getMountPoint(name);
if (mntpnt != NULL) if (mntpnt != NULL)
addDisc(mntpnt, discs, disccount); {
callback(data, mntpnt);
free(mntpnt); /* !!! FIXME: lose this malloc! */
} /* if */
} /* if */ } /* if */
} /* if */ } /* if */
} /* if */ } /* if */
@ -159,14 +148,9 @@ static void tryDir(const char *dirname, char ***discs, int *disccount)
} /* tryDir */ } /* tryDir */
char **__PHYSFS_platformDetectAvailableCDs(void) void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{ {
char **retval = (char **) malloc(sizeof (char *)); tryDir("/dev/disk", cb, data);
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);
} /* __PHYSFS_platformDetectAvailableCDs */ } /* __PHYSFS_platformDetectAvailableCDs */

View File

@ -177,17 +177,12 @@ int __PHYSFS_platformDeinit(void)
* CD detection code is borrowed from Apple Technical Q&A DV18. * CD detection code is borrowed from Apple Technical Q&A DV18.
* http://developer.apple.com/qa/dv/dv18.html * http://developer.apple.com/qa/dv/dv18.html
*/ */
char **__PHYSFS_platformDetectAvailableCDs(void) void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{ {
DriverGestaltParam pb; DriverGestaltParam pb;
DrvQEl *dqp; DrvQEl *dqp;
OSErr status; 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.csCode = kDriverGestaltCode;
pb.driverGestaltSelector = kdgDeviceType; pb.driverGestaltSelector = kdgDeviceType;
@ -201,6 +196,7 @@ char **__PHYSFS_platformDetectAvailableCDs(void)
if ((status == noErr) && (pb.driverGestaltResponse == kdgCDType)) if ((status == noErr) && (pb.driverGestaltResponse == kdgCDType))
{ {
Str63 volName; Str63 volName;
size_t size;
HParamBlockRec hpbr; HParamBlockRec hpbr;
memset(&hpbr, '\0', sizeof (HParamBlockRec)); memset(&hpbr, '\0', sizeof (HParamBlockRec));
hpbr.volumeParam.ioNamePtr = volName; hpbr.volumeParam.ioNamePtr = volName;
@ -208,27 +204,15 @@ char **__PHYSFS_platformDetectAvailableCDs(void)
hpbr.volumeParam.ioVolIndex = 0; hpbr.volumeParam.ioVolIndex = 0;
if (PBHGetVInfoSync(&hpbr) == noErr) if (PBHGetVInfoSync(&hpbr) == noErr)
{ {
char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1)); size = (size_t) volName[0]; /* convert to ASCIZ string... */
if (tmp) memmove(&volName[0], &volName[1], size);
{ volName[size] = '\0';
char *str = (char *) malloc(volName[0] + 1); cb(data, volName);
retval = tmp;
if (str != NULL)
{
memcpy(str, &volName[1], volName[0]);
str[volName[0]] = '\0';
retval[cd_count-1] = str;
cd_count++;
} /* if */
} /* if */
} /* if */ } /* if */
} /* if */ } /* if */
dqp = (DrvQEl *) dqp->qLink; dqp = (DrvQEl *) dqp->qLink;
} /* while */ } /* while */
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */ } /* __PHYSFS_platformDetectAvailableCDs */
@ -577,10 +561,12 @@ void __PHYSFS_platformTimeslice(void)
} /* __PHYSFS_platformTimeslice */ } /* __PHYSFS_platformTimeslice */
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname, /* returns int so we can use BAIL*MACRO... */
int omitSymLinks) static int macClassicEnumerateFiles(const char *dirname,
int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{ {
LinkedStringList *ret = NULL, *p = NULL;
UInt16 i; UInt16 i;
UInt16 max; UInt16 max;
FSSpec spec; FSSpec spec;
@ -606,6 +592,7 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
for (i = 1; i <= max; i++) for (i = 1; i <= max; i++)
{ {
size_t size;
FSSpec aliasspec; FSSpec aliasspec;
Boolean alias = 0; Boolean alias = 0;
Boolean folder = 0; Boolean folder = 0;
@ -629,10 +616,20 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
continue; continue;
/* still here? Add it to the list. */ /* 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 */ } /* for */
} /* macClassicEnumerateFiles */
return(ret);
void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{
macClassicEnumerateFiles(dirname, omitSymLinks, callback, callbackdata);
} /* __PHYSFS_platformEnumerateFiles */ } /* __PHYSFS_platformEnumerateFiles */

View File

@ -254,20 +254,12 @@ static int is_cdrom_drive(ULONG drive)
} /* is_cdrom_drive */ } /* is_cdrom_drive */
char **__PHYSFS_platformDetectAvailableCDs(void) void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{ {
ULONG dummy; ULONG dummy = 0;
ULONG drivemap; ULONG drivemap = 0;
ULONG i, bit; ULONG i, bit;
APIRET rc; APIRET rc = DosQueryCurrentDisk(&dummy, &drivemap);
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);
BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, retval); BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, retval);
for (i = 0, bit = 1; i < 26; i++, bit <<= 1) for (i = 0, bit = 1; i < 26; i++, bit <<= 1)
@ -276,27 +268,12 @@ char **__PHYSFS_platformDetectAvailableCDs(void)
{ {
if ((is_cdrom_drive(i)) && (disc_is_inserted(i))) if ((is_cdrom_drive(i)) && (disc_is_inserted(i)))
{ {
char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1)); char drive[4] = "x:\\";
if (tmp) drive[0] = ('A' + i);
{ cb(data, drive);
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 */
} /* if */ } /* if */
} /* if */ } /* if */
} /* for */ } /* for */
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */ } /* __PHYSFS_platformDetectAvailableCDs */
@ -417,11 +394,12 @@ char *__PHYSFS_platformCvtToDependent(const char *prepend,
} /* __PHYSFS_platformCvtToDependent */ } /* __PHYSFS_platformCvtToDependent */
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname, void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks) int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{ {
char spec[CCHMAXPATH]; char spec[CCHMAXPATH];
LinkedStringList *ret = NULL, *p = NULL;
FILEFINDBUF3 fb; FILEFINDBUF3 fb;
HDIR hdir = HDIR_CREATE; HDIR hdir = HDIR_CREATE;
ULONG count = 1; ULONG count = 1;
@ -439,13 +417,12 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
while (count == 1) while (count == 1)
{ {
if ((strcmp(fb.achName, ".") != 0) && (strcmp(fb.achName, "..") != 0)) 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); DosFindNext(hdir, &fb, sizeof (fb), &count);
} /* while */ } /* while */
DosFindClose(hdir); DosFindClose(hdir);
return(ret);
} /* __PHYSFS_platformEnumerateFiles */ } /* __PHYSFS_platformEnumerateFiles */

View File

@ -67,52 +67,53 @@ static const char *win32strerror(void)
static char *UnicodeToAsc(const wchar_t *w_str) 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; int len = wcslen(w_str) + 1;
str=(char *)malloc(len); str = (char *) malloc(len);
if(WideCharToMultiByte(CP_ACP,0,w_str,-1,str,len,NULL,NULL)==0) if (WideCharToMultiByte(CP_ACP,0,w_str,-1,str,len,NULL,NULL) == 0)
{ //Conversion failed { /*Conversion failed */
free(str); free(str);
return(NULL);
} /* if */
else
{ /* Conversion successful */
return(str);
} /* else */
} /* if */
else
{ /* Given NULL string */
return NULL; return NULL;
} }
else } /* UnicodeToAsc */
{ //Conversion successful
return(str);
}
}
else
{ //Given NULL string
return NULL;
}
}
static wchar_t *AscToUnicode(const char *str) static wchar_t *AscToUnicode(const char *str)
{ {
wchar_t *w_str=NULL; wchar_t *w_str = NULL;
if(str!=NULL) if (str != NULL)
{ {
int len=strlen(str)+1; int len = strlen(str) + 1;
w_str=(wchar_t *)malloc(sizeof(wchar_t)*len); w_str = (wchar_t *) malloc(sizeof (wchar_t) * len);
if(MultiByteToWideChar(CP_ACP,0,str,-1,w_str,len)==0) if (MultiByteToWideChar(CP_ACP,0,str,-1,w_str,len) == 0)
{ {
free(w_str); free(w_str);
return NULL; return(NULL);
} } /* if */
else
{
return(w_str);
} /* else */
} /* if */
else else
{ {
return(w_str); return(NULL);
} } /* else */
} } /* AscToUnicode */
else
{
return NULL;
}
}
static char *getExePath() static char *getExePath()
@ -177,9 +178,9 @@ int __PHYSFS_platformDeinit(void)
} /* __PHYSFS_platformDeinit */ } /* __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 */ } /* __PHYSFS_platformDetectAvailableCDs */
@ -293,12 +294,11 @@ void __PHYSFS_platformTimeslice(void)
} /* __PHYSFS_platformTimeslice */ } /* __PHYSFS_platformTimeslice */
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname, void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks) int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{ {
LinkedStringList *retval = NULL;
LinkedStringList *l = NULL;
LinkedStringList *prev = NULL;
HANDLE dir; HANDLE dir;
WIN32_FIND_DATA ent; WIN32_FIND_DATA ent;
char *SearchPath; char *SearchPath;
@ -328,43 +328,29 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
free(w_SearchPath); free(w_SearchPath);
free(SearchPath); free(SearchPath);
if(dir == INVALID_HANDLE_VALUE) if (dir == INVALID_HANDLE_VALUE)
{ return;
return NULL;
}
do do
{ {
const char *str;
if (wcscmp(ent.cFileName, L".") == 0) if (wcscmp(ent.cFileName, L".") == 0)
continue; continue;
if (wcscmp(ent.cFileName, L"..") == 0) if (wcscmp(ent.cFileName, L"..") == 0)
continue; continue;
l = (LinkedStringList *) malloc(sizeof (LinkedStringList)); /* !!! FIXME: avoid malloc in UnicodeToAsc? */
if (l == NULL) str = UnicodeToAsc(ent.cFileName);
if (str == NULL)
break; break;
l->str=UnicodeToAsc(ent.cFileName); callback(callbackdata, str);
free(str);
if (l->str == NULL)
{
free(l);
break;
}
if (retval == NULL)
retval = l;
else
prev->next = l;
prev = l;
l->next = NULL;
} while (FindNextFile(dir, &ent) != 0); } while (FindNextFile(dir, &ent) != 0);
FindClose(dir); FindClose(dir);
return(retval);
} /* __PHYSFS_platformEnumerateFiles */ } /* __PHYSFS_platformEnumerateFiles */
@ -381,7 +367,6 @@ char *__PHYSFS_platformRealPath(const char *path)
strcpy(retval,path); strcpy(retval,path);
return(retval); return(retval);
} /* __PHYSFS_platformRealPath */ } /* __PHYSFS_platformRealPath */

View File

@ -225,22 +225,24 @@ char *__PHYSFS_platformCvtToDependent(const char *prepend,
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname, void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks) int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{ {
LinkedStringList *retval = NULL, *p = NULL;
DIR *dir; DIR *dir;
struct dirent *ent; struct dirent *ent;
int bufsize = 0; int bufsize = 0;
char *buf = NULL; char *buf = NULL;
int dlen = 0; int dlen = 0;
if (omitSymLinks) if (omitSymLinks) /* !!! FIXME: this malloc sucks. */
{ {
dlen = strlen(dirname); dlen = strlen(dirname);
bufsize = dlen + 256; bufsize = dlen + 256;
buf = (char *) malloc(bufsize); buf = (char *) malloc(bufsize);
BAIL_IF_MACRO(buf == NULL, ERR_OUT_OF_MEMORY, NULL); if (buf == NULL)
return;
strcpy(buf, dirname); strcpy(buf, dirname);
if (buf[dlen - 1] != '/') if (buf[dlen - 1] != '/')
{ {
@ -255,7 +257,7 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
{ {
if (buf != NULL) if (buf != NULL)
free(buf); free(buf);
BAIL_IF_MACRO(1, strerror(errno), NULL); return;
} /* if */ } /* if */
while ((ent = readdir(dir)) != NULL) while ((ent = readdir(dir)) != NULL)
@ -284,14 +286,13 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
continue; continue;
} /* if */ } /* if */
retval = __PHYSFS_addToLinkedStringList(retval, &p, ent->d_name, -1); callback(callbackdata, ent->d_name);
} /* while */ } /* while */
if (buf != NULL) if (buf != NULL)
free(buf); free(buf);
closedir(dir); closedir(dir);
return(retval);
} /* __PHYSFS_platformEnumerateFiles */ } /* __PHYSFS_platformEnumerateFiles */

View File

@ -32,9 +32,8 @@ int __PHYSFS_platformDeinit(void)
} /* __PHYSFS_platformDeinit */ } /* __PHYSFS_platformDeinit */
char **__PHYSFS_platformDetectAvailableCDs(void) void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{ {
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformDetectAvailableCDs */ } /* __PHYSFS_platformDetectAvailableCDs */
@ -105,10 +104,11 @@ void __PHYSFS_platformTimeslice(void)
} /* __PHYSFS_platformTimeslice */ } /* __PHYSFS_platformTimeslice */
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname, void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks) int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{ {
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformEnumerateFiles */ } /* __PHYSFS_platformEnumerateFiles */

View File

@ -76,12 +76,8 @@ int __PHYSFS_platformDeinit(void)
#ifdef PHYSFS_NO_CDROM_SUPPORT #ifdef PHYSFS_NO_CDROM_SUPPORT
/* Stub version for platforms without CD-ROM 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 */ } /* __PHYSFS_platformDetectAvailableCDs */
@ -166,13 +162,11 @@ static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
} /* darwinIsMountedDisc */ } /* darwinIsMountedDisc */
char **__PHYSFS_platformDetectAvailableCDs(void) void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{ {
const char *devPrefix = "/dev/"; const char *devPrefix = "/dev/";
int prefixLen = strlen(devPrefix); int prefixLen = strlen(devPrefix);
mach_port_t masterPort = 0; mach_port_t masterPort = 0;
char **retval = (char **) malloc(sizeof (char *));
int cd_count = 1; /* We count the NULL entry. */
struct statfs *mntbufp; struct statfs *mntbufp;
int i, mounts; int i, mounts;
@ -191,38 +185,17 @@ char **__PHYSFS_platformDetectAvailableCDs(void)
dev += prefixLen; dev += prefixLen;
if (darwinIsMountedDisc(dev, masterPort)) if (darwinIsMountedDisc(dev, masterPort))
{ cb(data, mnt);
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 */
} /* for */ } /* for */
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */ } /* __PHYSFS_platformDetectAvailableCDs */
#elif (defined PHYSFS_HAVE_SYS_UCRED_H) #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. */
struct statfs *mntbufp = NULL;
int mounts;
int i; int i;
struct statfs *mntbufp = NULL;
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); int mounts = getmntinfo(&mntbufp, MNT_WAIT);
mounts = getmntinfo(&mntbufp, MNT_WAIT);
for (i = 0; i < mounts; i++) for (i = 0; i < mounts; i++)
{ {
@ -236,40 +209,23 @@ char **__PHYSFS_platformDetectAvailableCDs(void)
/* add other mount types here */ /* add other mount types here */
if (add_it) if (add_it)
{ cb(data, mntbufp[i].f_mntonname);
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 */
} /* for */ } /* for */
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */ } /* __PHYSFS_platformDetectAvailableCDs */
#elif (defined PHYSFS_HAVE_MNTENT_H) #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; FILE *mounts = NULL;
struct mntent *ent = NULL; struct mntent *ent = NULL;
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
*retval = NULL;
mounts = setmntent("/etc/mtab", "r"); 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 ) while ( (ent = getmntent(mounts)) != NULL )
{ {
@ -280,25 +236,11 @@ char **__PHYSFS_platformDetectAvailableCDs(void)
/* add other mount types here */ /* add other mount types here */
if (add_it) if (add_it)
{ cb(data, ent->mnt_dir);
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 */
} /* while */ } /* while */
endmntent(mounts); endmntent(mounts);
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */ } /* __PHYSFS_platformDetectAvailableCDs */
#endif #endif

View File

@ -268,33 +268,17 @@ static BOOL mediaInDrive(const char *drive)
} /* mediaInDrive */ } /* 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:\\"; char drive_str[4] = "x:\\";
char ch;
for (drive_str[0] = 'A'; drive_str[0] <= 'Z'; drive_str[0]++) for (ch = 'A'; ch <= 'Z'; ch++)
{ {
drive_str[0] = ch;
if (GetDriveType(drive_str) == DRIVE_CDROM && mediaInDrive(drive_str)) if (GetDriveType(drive_str) == DRIVE_CDROM && mediaInDrive(drive_str))
{ cb(data, 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 */
} /* for */ } /* for */
} /* __PHYSFS_platformDetectAvailableCDs */
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_detectAvailableCDs */
char *__PHYSFS_platformCalcBaseDir(const char *argv0) char *__PHYSFS_platformCalcBaseDir(const char *argv0)
@ -454,18 +438,20 @@ void __PHYSFS_platformTimeslice(void)
} /* __PHYSFS_platformTimeslice */ } /* __PHYSFS_platformTimeslice */
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname, void __PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks) int omitSymLinks,
PHYSFS_StringCallback callback,
void *callbackdata)
{ {
LinkedStringList *retval = NULL, *p = NULL;
HANDLE dir; HANDLE dir;
WIN32_FIND_DATA ent; WIN32_FIND_DATA ent;
char *SearchPath;
size_t len = strlen(dirname); size_t len = strlen(dirname);
char *SearchPath;
/* Allocate a new string for path, maybe '\\', "*", and NULL terminator */ /* Allocate a new string for path, maybe '\\', "*", and NULL terminator */
SearchPath = (char *) alloca(len + 3); SearchPath = (char *) alloca(len + 3);
BAIL_IF_MACRO(SearchPath == NULL, ERR_OUT_OF_MEMORY, NULL); if (SearchPath == NULL)
return;
/* Copy current dirname */ /* Copy current dirname */
strcpy(SearchPath, dirname); strcpy(SearchPath, dirname);
@ -481,11 +467,8 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
strcat(SearchPath, "*"); strcat(SearchPath, "*");
dir = FindFirstFile(SearchPath, &ent); dir = FindFirstFile(SearchPath, &ent);
BAIL_IF_MACRO if (dir == INVALID_HANDLE_VALUE)
( return;
dir == INVALID_HANDLE_VALUE,
win32strerror(), NULL
);
do do
{ {
@ -495,11 +478,10 @@ LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
if (strcmp(ent.cFileName, "..") == 0) if (strcmp(ent.cFileName, "..") == 0)
continue; continue;
retval = __PHYSFS_addToLinkedStringList(retval, &p, ent.cFileName, -1); callback(callbackdata, ent.cFileName);
} while (FindNextFile(dir, &ent) != 0); } while (FindNextFile(dir, &ent) != 0);
FindClose(dir); FindClose(dir);
return(retval);
} /* __PHYSFS_platformEnumerateFiles */ } /* __PHYSFS_platformEnumerateFiles */