Refactoring
This commit is contained in:
parent
91efcfa06d
commit
316457b988
|
@ -500,21 +500,20 @@ static const PHYSFS_Archiver RGSS_Archiver =
|
||||||
|
|
||||||
struct FileSystemPrivate
|
struct FileSystemPrivate
|
||||||
{
|
{
|
||||||
/* All keys are lower case */
|
/* Maps: lower case filename, To: actual (mixed case) filename.
|
||||||
|
* This is for compatibility with games that take Windows'
|
||||||
|
* case insensitivity for granted */
|
||||||
BoostHash<std::string, std::string> pathCache;
|
BoostHash<std::string, std::string> pathCache;
|
||||||
|
bool havePathCache;
|
||||||
|
|
||||||
std::vector<std::string> extensions[FileSystem::Undefined+1];
|
std::vector<std::string> extensions[FileSystem::Undefined+1];
|
||||||
|
|
||||||
// FIXME Need to find a better way to do this..
|
|
||||||
char pathBuffer[512];
|
|
||||||
bool havePathCache;
|
|
||||||
|
|
||||||
/* Attempt to locate an extension string in a filename.
|
/* Attempt to locate an extension string in a filename.
|
||||||
* Either a pointer into the input string pointing at the
|
* Either a pointer into the input string pointing at the
|
||||||
* extension, or null is returned */
|
* extension, or null is returned */
|
||||||
const char *findExt(const char *filename)
|
const char *findExt(const char *filename)
|
||||||
{
|
{
|
||||||
int len;
|
size_t len;
|
||||||
|
|
||||||
for (len = strlen(filename); len > 0; --len)
|
for (len = strlen(filename); len > 0; --len)
|
||||||
{
|
{
|
||||||
|
@ -528,105 +527,124 @@ struct FileSystemPrivate
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *completeFileName(const char *filename,
|
/* Complete filename via regular physfs lookup */
|
||||||
|
bool completeFilenameReg(const char *filename,
|
||||||
FileSystem::FileType type,
|
FileSystem::FileType type,
|
||||||
|
char *outBuffer,
|
||||||
|
size_t outN,
|
||||||
const char **foundExt)
|
const char **foundExt)
|
||||||
{
|
{
|
||||||
if (!havePathCache)
|
/* Try supplementing extensions to find an existing path */
|
||||||
|
const std::vector<std::string> &extList = extensions[type];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < extList.size(); ++i)
|
||||||
{
|
{
|
||||||
|
const char *ext = extList[i].c_str();
|
||||||
|
|
||||||
|
snprintf(outBuffer, outN, "%s.%s", filename, ext);
|
||||||
|
|
||||||
|
if (PHYSFS_exists(outBuffer))
|
||||||
|
{
|
||||||
|
if (foundExt)
|
||||||
|
*foundExt = ext;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Doing the check without supplemented extension
|
||||||
|
* fits the usage pattern of RMXP games */
|
||||||
if (PHYSFS_exists(filename))
|
if (PHYSFS_exists(filename))
|
||||||
{
|
{
|
||||||
|
strncpy(outBuffer, filename, outN);
|
||||||
|
|
||||||
if (foundExt)
|
if (foundExt)
|
||||||
*foundExt = findExt(filename);
|
*foundExt = findExt(filename);
|
||||||
|
|
||||||
return filename;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Complete filename via path cache */
|
||||||
|
bool completeFilenamePC(const char *filename,
|
||||||
|
FileSystem::FileType type,
|
||||||
|
char *outBuffer,
|
||||||
|
size_t outN,
|
||||||
|
const char **foundExt)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
char lowCase[512];
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(lowCase)-1 && filename[i]; ++i)
|
||||||
|
lowCase[i] = tolower(filename[i]);
|
||||||
|
|
||||||
|
lowCase[i] = '\0';
|
||||||
|
|
||||||
|
std::string key;
|
||||||
|
|
||||||
const std::vector<std::string> &extList = extensions[type];
|
const std::vector<std::string> &extList = extensions[type];
|
||||||
|
|
||||||
for (size_t i = 0; i < extList.size(); ++i)
|
for (size_t i = 0; i < extList.size(); ++i)
|
||||||
{
|
{
|
||||||
const char *ext = extList[i].c_str();
|
const char *ext = extList[i].c_str();
|
||||||
|
|
||||||
snprintf(pathBuffer, sizeof(pathBuffer), "%s.%s", filename, ext);
|
snprintf(outBuffer, outN, "%s.%s", lowCase, ext);
|
||||||
|
key = outBuffer;
|
||||||
|
|
||||||
if (PHYSFS_exists(pathBuffer))
|
if (pathCache.contains(key))
|
||||||
{
|
{
|
||||||
|
strncpy(outBuffer, pathCache[key].c_str(), outN);
|
||||||
|
|
||||||
if (foundExt)
|
if (foundExt)
|
||||||
*foundExt = ext;
|
*foundExt = ext;
|
||||||
|
|
||||||
return pathBuffer;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is this even necessary?
|
key = lowCase;
|
||||||
if (foundExt)
|
|
||||||
*foundExt = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char buff[512];
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(buff) && filename[i]; ++i)
|
|
||||||
buff[i] = tolower(filename[i]);
|
|
||||||
|
|
||||||
buff[i] = '\0';
|
|
||||||
|
|
||||||
std::string key(buff);
|
|
||||||
|
|
||||||
/* If the path was already complete,
|
|
||||||
* we are done at this point */
|
|
||||||
if (pathCache.contains(key))
|
if (pathCache.contains(key))
|
||||||
{
|
{
|
||||||
/* The extension might already be included here,
|
strncpy(outBuffer, pathCache[key].c_str(), outN);
|
||||||
* so try to find it */
|
|
||||||
if (foundExt)
|
if (foundExt)
|
||||||
*foundExt = findExt(filename);
|
*foundExt = findExt(filename);
|
||||||
|
|
||||||
return pathCache[key].c_str();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buff2[512];
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Try supplementing extensions
|
/* Try to complete 'filename' with file extensions
|
||||||
* to find an existing path */
|
* based on 'type'. If no combination could be found,
|
||||||
if (type != FileSystem::Undefined)
|
* returns false, and 'foundExt' is untouched */
|
||||||
|
bool completeFileName(const char *filename,
|
||||||
|
FileSystem::FileType type,
|
||||||
|
char *outBuffer,
|
||||||
|
size_t outN,
|
||||||
|
const char **foundExt)
|
||||||
{
|
{
|
||||||
std::vector<std::string> &extList = extensions[type];
|
if (havePathCache)
|
||||||
for (size_t i = 0; i < extList.size(); ++i)
|
return completeFilenamePC(filename, type, outBuffer, outN, foundExt);
|
||||||
{
|
else
|
||||||
const char *ext = extList[i].c_str();
|
return completeFilenameReg(filename, type, outBuffer, outN, foundExt);
|
||||||
|
|
||||||
snprintf(buff2, sizeof(buff2), "%s.%s", buff, ext);
|
|
||||||
key = buff2;
|
|
||||||
|
|
||||||
if (pathCache.contains(key))
|
|
||||||
{
|
|
||||||
if (foundExt)
|
|
||||||
*foundExt = ext;
|
|
||||||
|
|
||||||
return pathCache[key].c_str();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundExt)
|
PHYSFS_File *openReadHandle(const char *filename,
|
||||||
*foundExt = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PHYSFS_File *openReadInt(const char *filename,
|
|
||||||
FileSystem::FileType type,
|
FileSystem::FileType type,
|
||||||
const char **foundExt)
|
const char **foundExt)
|
||||||
{
|
{
|
||||||
const char *foundName = completeFileName(filename, type, foundExt);
|
char found[512];
|
||||||
|
|
||||||
if (!foundName)
|
if (!completeFileName(filename, type, found, sizeof(found), foundExt))
|
||||||
throw Exception(Exception::NoFileError, "%s", filename);
|
throw Exception(Exception::NoFileError, "%s", filename);
|
||||||
|
|
||||||
PHYSFS_File *handle = PHYSFS_openRead(foundName);
|
PHYSFS_File *handle = PHYSFS_openRead(found);
|
||||||
|
|
||||||
if (!handle)
|
if (!handle)
|
||||||
throw Exception(Exception::PHYSFSError, "PhysFS: %s", PHYSFS_getLastError());
|
throw Exception(Exception::PHYSFSError, "PhysFS: %s", PHYSFS_getLastError());
|
||||||
|
|
||||||
|
@ -826,7 +844,7 @@ void FileSystem::openRead(SDL_RWops &ops,
|
||||||
bool freeOnClose,
|
bool freeOnClose,
|
||||||
const char **foundExt)
|
const char **foundExt)
|
||||||
{
|
{
|
||||||
PHYSFS_File *handle = p->openReadInt(filename, type, foundExt);
|
PHYSFS_File *handle = p->openReadHandle(filename, type, foundExt);
|
||||||
|
|
||||||
ops.size = SDL_RWopsSize;
|
ops.size = SDL_RWopsSize;
|
||||||
ops.seek = SDL_RWopsSeek;
|
ops.seek = SDL_RWopsSeek;
|
||||||
|
@ -844,7 +862,7 @@ void FileSystem::openRead(SDL_RWops &ops,
|
||||||
|
|
||||||
bool FileSystem::exists(const char *filename, FileType type)
|
bool FileSystem::exists(const char *filename, FileType type)
|
||||||
{
|
{
|
||||||
const char *foundName = p->completeFileName(filename, type, 0);
|
char found[512];
|
||||||
|
|
||||||
return (foundName != 0);
|
return p->completeFileName(filename, type, found, sizeof(found), 0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue