Added callback APIs and ripped up the internals everywhere to use them.
This commit is contained in:
parent
80535e9b83
commit
c2765f8571
|
@ -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
2
TODO
|
@ -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.
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
205
physfs.c
|
@ -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 ... */
|
||||||
|
|
||||||
|
|
16
physfs.h
16
physfs.h
|
@ -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. */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue