mirror of https://github.com/OpenMW/openmw.git
Added file_finder component. Used by sound system.
parent
104f3fdd50
commit
3127602c57
@ -0,0 +1,62 @@
|
|||||||
|
#ifndef FILE_FINDER_MAIN_H
|
||||||
|
#define FILE_FINDER_MAIN_H
|
||||||
|
|
||||||
|
#include "search.hpp"
|
||||||
|
#include "filename_less.hpp"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace FileFinder
|
||||||
|
{
|
||||||
|
|
||||||
|
class FileFinder
|
||||||
|
{
|
||||||
|
std::map<std::string, std::string, path_less> table;
|
||||||
|
|
||||||
|
struct Inserter : ReturnPath
|
||||||
|
{
|
||||||
|
FileFinder *owner;
|
||||||
|
int cut;
|
||||||
|
|
||||||
|
void add(const boost::filesystem::path &pth)
|
||||||
|
{
|
||||||
|
std::string file = pth.file_string();
|
||||||
|
std::string key = file.substr(cut);
|
||||||
|
owner->table[key] = file;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Inserter inserter;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FileFinder(const boost::filesystem::path &path, bool recurse=true)
|
||||||
|
{
|
||||||
|
inserter.owner = this;
|
||||||
|
|
||||||
|
// Remember the original path length, so we can cut it away from
|
||||||
|
// the relative paths used as keys
|
||||||
|
std::string pstring = path.file_string();
|
||||||
|
inserter.cut = pstring.size();
|
||||||
|
|
||||||
|
// If the path does not end in a slash, then boost will add one
|
||||||
|
// later, which means one more character we have to remove.
|
||||||
|
char last = pstring[pstring.size()-1];
|
||||||
|
if(last != '\\' && last != '/')
|
||||||
|
inserter.cut++;
|
||||||
|
|
||||||
|
// Fill the map
|
||||||
|
find(path, inserter, recurse);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has(const std::string& file) const
|
||||||
|
{
|
||||||
|
return table.find(file) != table.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the full path from a relative path.
|
||||||
|
const std::string &lookup(const std::string& file) const
|
||||||
|
{
|
||||||
|
return table.find(file)->second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
@ -0,0 +1,49 @@
|
|||||||
|
#ifndef FILE_FINDER_LESS_H
|
||||||
|
#define FILE_FINDER_LESS_H
|
||||||
|
|
||||||
|
#include <libs/platform/strings.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace FileFinder{
|
||||||
|
|
||||||
|
// Used for maps of file paths. Compares file paths, but ignores case
|
||||||
|
// AND treats \ and / as the same character.
|
||||||
|
struct path_less
|
||||||
|
{
|
||||||
|
int compareChar(char a, char b) const
|
||||||
|
{
|
||||||
|
if(a>b) return 1;
|
||||||
|
else if(a<b) return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int comparePathChar(char a, char b) const
|
||||||
|
{
|
||||||
|
if(a >= 'a' && a <= 'z') a += 'A'-'a';
|
||||||
|
else if(a == '\\') a = '/';
|
||||||
|
if(b >= 'a' && b <= 'z') b += 'A'-'a';
|
||||||
|
else if(b == '\\') b = '/';
|
||||||
|
return compareChar(a,b);
|
||||||
|
}
|
||||||
|
|
||||||
|
int compareString(const char *a, const char *b) const
|
||||||
|
{
|
||||||
|
while(*a && *b)
|
||||||
|
{
|
||||||
|
int i = comparePathChar(*a,*b);
|
||||||
|
if(i != 0) return i;
|
||||||
|
a++; b++;
|
||||||
|
}
|
||||||
|
// At this point, one or both of the chars is a null terminator.
|
||||||
|
// Normal char comparison will get the correct final result here.
|
||||||
|
return compareChar(*a,*b);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator() (const std::string& a, const std::string& b) const
|
||||||
|
{
|
||||||
|
return compareString(a.c_str(), b.c_str()) < 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
@ -0,0 +1,28 @@
|
|||||||
|
#include "search.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace boost::filesystem;
|
||||||
|
|
||||||
|
void FileFinder::find(const path & dir_path, ReturnPath &ret, bool recurse)
|
||||||
|
{
|
||||||
|
if ( !exists( dir_path ) )
|
||||||
|
{
|
||||||
|
cout << "Path " << dir_path << " not found\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
directory_iterator end_itr; // default construction yields past-the-end
|
||||||
|
for ( directory_iterator itr(dir_path);
|
||||||
|
itr != end_itr;
|
||||||
|
++itr )
|
||||||
|
{
|
||||||
|
if ( is_directory( *itr ) )
|
||||||
|
{
|
||||||
|
if(recurse) find(*itr, ret);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret.add(*itr);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef FILE_FINDER_SEARCH_H
|
||||||
|
#define FILE_FINDER_SEARCH_H
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace FileFinder
|
||||||
|
{
|
||||||
|
struct ReturnPath
|
||||||
|
{
|
||||||
|
virtual void add(const boost::filesystem::path &pth) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Search the given path and return all file paths through 'ret'. If
|
||||||
|
recurse==true, all files in subdirectories are returned as well.
|
||||||
|
*/
|
||||||
|
void find(const boost::filesystem::path & dir_path, ReturnPath &ret, bool recurse=true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue