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/LoaderGXT.hpp>
|
||||||
#include <loaders/BackgroundLoader.hpp>
|
#include <loaders/BackgroundLoader.hpp>
|
||||||
#include <core/Logger.hpp>
|
#include <core/Logger.hpp>
|
||||||
|
#include <platform/FileIndex.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#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
|
// Yet another hack function to fix these paths
|
||||||
std::string fixPath(std::string path) {
|
std::string fixPath(std::string path) {
|
||||||
for( size_t t = 0; t < path.size(); ++t) {
|
for( size_t t = 0; t < path.size(); ++t) {
|
||||||
@ -84,7 +32,6 @@ std::string fixPath(std::string path) {
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GameData::GameData(Logger* log, WorkContext* work, const std::string& path)
|
GameData::GameData(Logger* log, WorkContext* work, const std::string& path)
|
||||||
: datpath(path), logger(log), workContext(work), engine(nullptr)
|
: datpath(path), logger(log), workContext(work), engine(nullptr)
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,43 @@
|
|||||||
|
|
||||||
using namespace boost::filesystem;
|
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)
|
void FileIndex::indexTree(const std::string& root)
|
||||||
{
|
{
|
||||||
for(const auto& entry : recursive_directory_iterator(root)) {
|
for(const auto& entry : recursive_directory_iterator(root)) {
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
std::string findPathRealCase(const std::string& base_src, const std::string& path_src);
|
||||||
|
|
||||||
class FileIndex
|
class FileIndex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user