mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-07 03:12:36 +01:00
Rewrite findPathRealCase to use boost::filesystem, move it to FileIndex
This commit is contained in:
parent
196f9f6d25
commit
40705a6666
@ -14,65 +14,13 @@
|
||||
#include <loaders/LoaderGXT.hpp>
|
||||
#include <loaders/BackgroundLoader.hpp>
|
||||
#include <core/Logger.hpp>
|
||||
#include <platform/FileIndex.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#ifndef RW_WINDOWS
|
||||
#include <dirent.h>
|
||||
#else
|
||||
#include <platform/msdirent.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
/**
|
||||
* Finds the 'real' case for a path, to get around the fact that Rockstar's data is usually the wrong case.
|
||||
* @param base The base of the path to start looking from.
|
||||
* @param path the lowercase path.
|
||||
*/
|
||||
std::string findPathRealCase(const std::string& base, const std::string& path)
|
||||
{
|
||||
#ifndef RW_WINDOWS
|
||||
size_t endslash = path.find("/");
|
||||
bool isDirectory = true;
|
||||
if(endslash == path.npos) {
|
||||
isDirectory = false;
|
||||
}
|
||||
std::string orgFileName = isDirectory ? path.substr(0, endslash) : path;
|
||||
std::transform(orgFileName.begin(), orgFileName.end(), orgFileName.begin(), ::tolower);
|
||||
std::string realName;
|
||||
|
||||
// Open the current "base" path (i.e. the real path)
|
||||
DIR* dp = opendir(base.c_str());
|
||||
dirent* ep;
|
||||
|
||||
if( dp != NULL) {
|
||||
while( (ep = readdir(dp)) ) {
|
||||
realName = ep->d_name;
|
||||
std::string lowerRealName = realName;
|
||||
std::transform(lowerRealName.begin(), lowerRealName.end(), lowerRealName.begin(), ::tolower);
|
||||
if( lowerRealName == orgFileName) {
|
||||
closedir(dp);
|
||||
if( isDirectory) {
|
||||
return findPathRealCase(base + "/" + realName, path.substr(endslash+1));
|
||||
}
|
||||
else {
|
||||
return base + "/" + realName;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
}
|
||||
|
||||
return "";
|
||||
#else
|
||||
// Is anything other than Windows likely to fall here?
|
||||
return base + "/" + path;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Yet another hack function to fix these paths
|
||||
std::string fixPath(std::string path) {
|
||||
for( size_t t = 0; t < path.size(); ++t) {
|
||||
@ -84,7 +32,6 @@ std::string fixPath(std::string path) {
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
GameData::GameData(Logger* log, WorkContext* work, const std::string& path)
|
||||
: datpath(path), logger(log), workContext(work), engine(nullptr)
|
||||
{
|
||||
|
@ -6,6 +6,43 @@
|
||||
|
||||
using namespace boost::filesystem;
|
||||
|
||||
/**
|
||||
* Finds the 'real' case for a path, to get around the fact that Rockstar's data is usually the wrong case.
|
||||
* @param base The base of the path to start looking from.
|
||||
* @param path the lowercase path.
|
||||
*/
|
||||
std::string findPathRealCase(const std::string& base_src, const std::string& path_src)
|
||||
{
|
||||
path base(base_src);
|
||||
path searchpath(path_src);
|
||||
|
||||
// Iterate over each component of the path
|
||||
for(const path& path_component : searchpath) {
|
||||
std::string cmp_lower = path_component.string();
|
||||
std::transform(cmp_lower.begin(), cmp_lower.end(), cmp_lower.begin(), ::tolower);
|
||||
|
||||
// Search the current base path for a filename matching the component we're searching for
|
||||
bool found = false;
|
||||
for(const directory_entry& entry : directory_iterator(base)) {
|
||||
std::string lowerName = entry.path().filename().string();
|
||||
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), ::tolower);
|
||||
|
||||
if(lowerName == cmp_lower) {
|
||||
// We got a match, so add it to base and continue
|
||||
base /= lowerName;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
throw std::runtime_error("Can't find real path case of " + path_src);
|
||||
}
|
||||
}
|
||||
|
||||
return base.string();
|
||||
}
|
||||
|
||||
void FileIndex::indexTree(const std::string& root)
|
||||
{
|
||||
for(const auto& entry : recursive_directory_iterator(root)) {
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
std::string findPathRealCase(const std::string& base_src, const std::string& path_src);
|
||||
|
||||
class FileIndex
|
||||
{
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user