[physfs] Getting every instance of overlapping files
Haydn Harach
hharach at gmail.com
Mon Aug 25 20:55:17 EDT 2014
Alrighty, here are the additions I've made to my physfs.c:
PHYSFS_File **PHYSFS_openReadMulti(const char *_fname)
{
char *fname;
size_t len;
BAIL_IF_MACRO(_fname == NULL, ERR_INVALID_ARGUMENT, 0);
len = strlen(_fname) + 1;
fname = (char *) __PHYSFS_smallAlloc(len);
BAIL_IF_MACRO(fname == NULL, ERR_OUT_OF_MEMORY, 0);
FileHandle** ret = NULL;
unsigned int retcount = 0;
if (sanitizePlatformIndependentPath(_fname, fname))
{
int fileExists = 0;
DirHandle *i = NULL;
fvoid *opaque = NULL;
__PHYSFS_platformGrabMutex(stateLock);
GOTO_IF_MACRO(!searchPath, ERR_NO_SUCH_PATH, openReadEnd);
/* !!! FIXME: Why aren't we using a for loop here? */
i = searchPath;
do
{
char *arcfname = fname;
if (verifyPath(i, &arcfname, 0))
{
opaque = i->funcs->openRead(i->opaque, arcfname,
&fileExists);
if (opaque)
{
// We found a valid file, let's prepare it.
FileHandle* h =
(FileHandle*)allocator.Malloc(sizeof(FileHandle));
if (h == NULL)
{
i->funcs->fileClose(opaque);
GOTO_MACRO(ERR_OUT_OF_MEMORY, openReadEnd);
}
memset(h, 0, sizeof(FileHandle));
h->opaque = opaque;
h->forReading = 1;
h->dirHandle = i;
h->funcs = i->funcs;
h->next = openReadList;
openReadList = h;
// Add the file to the list
FileHandle** temp =
(FileHandle**)allocator.Malloc(sizeof(FileHandle) * (retcount + 1));
if (temp == NULL)
{
allocator.Free(h);
i->funcs->fileClose(opaque);
GOTO_MACRO(ERR_OUT_OF_MEMORY, openReadEnd);
}
if (ret != NULL)
{
memcpy(temp, ret, sizeof(FileHandle) * retcount);
allocator.Free(ret);
}
temp[retcount] = h;
++retcount;
ret = temp;
}
} /* if */
i = i->next;
} while ((i != NULL) && (!fileExists));
// Add a null terminator to the list
if (ret != NULL)
{
FileHandle** temp =
(FileHandle**)allocator.Malloc(sizeof(FileHandle) * (retcount + 1));
if (temp == NULL)
GOTO_MACRO(ERR_OUT_OF_MEMORY, openReadEnd);
memcpy(temp, ret, sizeof(FileHandle) * retcount);
allocator.Free(ret);
temp[retcount] = NULL;
ret = temp;
}
openReadEnd:
__PHYSFS_platformReleaseMutex(stateLock);
} /* if */
__PHYSFS_smallFree(fname);
return ret;
} /* PHYSFS_openReadMulti */
int PHYSFS_closeList(PHYSFS_file** list)
{
int retval = 1;
for (PHYSFS_file** i = list; *i != NULL; ++i)
{
if (PHYSFS_close(*i) == 0)
retval = 0;
}
allocator.Free(list);
return retval;
}
Is there anything not immediately obvious that I'm missing?
On Mon, Aug 25, 2014 at 6:11 PM, Edward Rudd <urkle at outoforder.cc> wrote:
> On Aug 25, 2014, at 8:06 PM, Haydn Harach <hharach at gmail.com> wrote:
>
> > Looking at PHYSFS_openRead() in physfs.c, I've found this little snippet:
> >
> > do
> > {
> > char *arcfname = fname;
> > if (verifyPath(i, &arcfname, 0))
> > {
> > opaque = i->funcs->openRead(i->opaque, arcfname,
> &fileExists);
> > if (opaque)
> > break;
> > } /* if */
> > i = i->next;
> > } while ((i != NULL) && (!fileExists));
> >
> > Now, from what I can see, this loop goes through all the paths, and the
> first one that satisfies the function and returns some data (from the
> openRead function) and causes 'opaque' to not be NULL, and thus breaks out
> of the loop.
> >
> > So, if I replaced "if (opaque) break;" with "if (opaque)
> someVector.emplace_back(opaque, i);", then did some cleanup to ensure that
> I have a vector of FileHandle's instead of one, and return that, this
> should be exactly what I'm looking for, yes?
>
> More or less, yes that would be exactly what you were looking for.
> _______________________________________________
> physfs mailing list
> physfs at icculus.org
> http://icculus.org/mailman/listinfo/physfs
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://icculus.org/pipermail/physfs/attachments/20140825/d729490d/attachment-0001.html>
More information about the physfs
mailing list