Reduce searches in locateOneElement
This commit is contained in:
parent
3817394b79
commit
705777db05
|
@ -50,42 +50,50 @@ static int caseInsensitiveStringCompare(const char *x, const char *y)
|
|||
return(0);
|
||||
} /* caseInsensitiveStringCompare */
|
||||
|
||||
namespace {
|
||||
|
||||
static int locateOneElement(char *buf)
|
||||
class search_deleter
|
||||
{
|
||||
public:
|
||||
void operator()(char **v) const
|
||||
{
|
||||
PHYSFS_freeList(v);
|
||||
}
|
||||
};
|
||||
|
||||
class search_result_t : public std::unique_ptr<char *[], search_deleter>
|
||||
{
|
||||
typedef std::unique_ptr<char *[], search_deleter> base_ptr;
|
||||
public:
|
||||
search_result_t(char *ptr, const char *buf) :
|
||||
base_ptr(PHYSFS_enumerateFiles(ptr ? (*ptr = 0, buf) : "/"))
|
||||
{
|
||||
if (ptr)
|
||||
*ptr = '/';
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static int locateOneElement(char *const sptr, char *const ptr, const char *buf)
|
||||
{
|
||||
char *ptr;
|
||||
char **rc;
|
||||
char **i;
|
||||
|
||||
if (PHYSFSX_exists(buf,0))
|
||||
if (PHYSFS_exists(buf))
|
||||
return(1); /* quick rejection: exists in current case. */
|
||||
|
||||
ptr = strrchr(buf, '/'); /* find entry at end of path. */
|
||||
if (ptr == NULL)
|
||||
{
|
||||
rc = PHYSFS_enumerateFiles("/");
|
||||
ptr = buf;
|
||||
} /* if */
|
||||
else
|
||||
{
|
||||
*ptr = '\0';
|
||||
rc = PHYSFS_enumerateFiles(buf);
|
||||
*ptr = '/';
|
||||
ptr++; /* point past dirsep to entry itself. */
|
||||
} /* else */
|
||||
search_result_t rc{ptr, buf};
|
||||
|
||||
for (i = rc; *i != NULL; i++)
|
||||
for (i = rc.get(); *i != NULL; i++)
|
||||
{
|
||||
if (caseInsensitiveStringCompare(*i, ptr) == 0)
|
||||
if (caseInsensitiveStringCompare(*i, sptr) == 0)
|
||||
{
|
||||
strcpy(ptr, *i); /* found a match. Overwrite with this case. */
|
||||
PHYSFS_freeList(rc);
|
||||
strcpy(sptr, *i); /* found a match. Overwrite with this case. */
|
||||
return(1);
|
||||
} /* if */
|
||||
} /* for */
|
||||
|
||||
/* no match at all... */
|
||||
PHYSFS_freeList(rc);
|
||||
return(0);
|
||||
} /* locateOneElement */
|
||||
|
||||
|
@ -93,31 +101,32 @@ static int locateOneElement(char *buf)
|
|||
int PHYSFSEXT_locateCorrectCase(char *buf)
|
||||
{
|
||||
int rc;
|
||||
char *ptr;
|
||||
char *prevptr;
|
||||
|
||||
while (*buf == '/') /* skip any '/' at start of string... */
|
||||
buf++;
|
||||
|
||||
ptr = prevptr = buf;
|
||||
if (*ptr == '\0')
|
||||
if (!*buf)
|
||||
return(0); /* Uh...I guess that's success. */
|
||||
|
||||
while ((ptr = strchr(ptr + 1, '/')))
|
||||
char *prevptr = nullptr;
|
||||
const auto a = [&]{
|
||||
return locateOneElement(prevptr ? prevptr + 1 : buf, prevptr, buf);
|
||||
};
|
||||
for (auto ptr = buf; (ptr = strchr(ptr + 1, '/')); prevptr = ptr)
|
||||
{
|
||||
*ptr = '\0'; /* block this path section off */
|
||||
rc = locateOneElement(buf);
|
||||
rc = a();
|
||||
*ptr = '/'; /* restore path separator */
|
||||
if (!rc)
|
||||
return(-2); /* missing element in path. */
|
||||
} /* while */
|
||||
|
||||
/* check final element... */
|
||||
return(locateOneElement(buf) ? 0 : -1);
|
||||
return a() ? 0 : -1;
|
||||
} /* PHYSFSEXT_locateCorrectCase */
|
||||
|
||||
|
||||
#ifdef TEST_PHYSFSEXT_LOCATECORRECTCASE
|
||||
#define con_printf(A,B,...) printf(B "\n", ##__VA_ARGS__)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
|
Loading…
Reference in a new issue