Tier1: optimize V_GetFileExtension()

If we are going to do a strlen to do a reverse check, then just check from the start and avoid another loop.
This commit is contained in:
Kawe Mazidjatari 2024-02-19 21:20:36 +01:00
parent 2bed5d4437
commit 12485342ae
2 changed files with 25 additions and 19 deletions

View File

@ -41,6 +41,8 @@
#define V_strdup _strdup
#define V_strcat strcat
#define V_strcasecmp V_stricmp
#define Q_vsnprintf V_vsnprintf
#define Q_snprintf V_snprintf
#define Q_strlower V_strlower
@ -159,7 +161,7 @@ void V_StripExtension(const char* in, char* out, size_t outLen);
void V_ExtractFileExtension(const char* path, char* dest, size_t destSize);
// Returns a pointer to the file extension or NULL if one doesn't exist
const char* V_GetFileExtension(const char* path);
const char* V_GetFileExtension(const char* path, const bool keepDot = false);
// Extracts the base name of a file (no path, no extension, assumes '/' or '\' as path separator)
void V_FileBase(const char* in, OUT_Z_CAP(maxlen) char* out, size_t maxlen);

View File

@ -1114,7 +1114,7 @@ const char* V_UnqualifiedFileName(const char* in)
if (PATHSEPARATOR(*in))
{
// +1 to skip the slash
out = in + 1;;
out = in + 1;
}
in++;
@ -1198,30 +1198,34 @@ void V_ExtractFileExtension(const char* path, char* dest, size_t destSize)
//-----------------------------------------------------------------------------
// Purpose: Returns a pointer to the file extension within a file name string
// Input: in - file name
// Output: pointer to beginning of extension (after the "."), or NULL
// if there is no extension
// Output: pointer to beginning of extension (after the "."), or the passed
// in string if there is no extension
//-----------------------------------------------------------------------------
const char* V_GetFileExtension(const char* path)
const char* V_GetFileExtension(const char* path, const bool keepDot)
{
size_t len = V_strlen(path);
if (len <= 1)
return NULL;
Assert(path);
const char* src = path + len - 1;
const char* out = nullptr;
//
// back up until a . or the start
//
while (src != path && *(src - 1) != '.')
src--;
// check to see if the '.' is part of a pathname
if (src == path || PATHSEPARATOR(*src))
while (*path)
{
return NULL; // no extension
if (*path == '.')
{
out = path;
if (!keepDot)
out++;
}
else if (PATHSEPARATOR(*path))
{
// didn't reach the file name yet, reset
out = nullptr;
}
path++;
}
return src;
return out ? out : path;
}