[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