OpenMW
|
00001 #ifndef FILE_FINDER_MAIN_H 00002 #define FILE_FINDER_MAIN_H 00003 00004 #include <map> 00005 00006 #include "search.hpp" 00007 #include "filename_less.hpp" 00008 #include <components/files/multidircollection.hpp> 00009 00010 namespace FileFinder 00011 { 00012 00013 template <typename LESS> 00014 class FileFinderT 00015 { 00016 typedef std::map<std::string, std::string, LESS> TableContainer; 00017 TableContainer table; 00018 00019 struct Inserter : ReturnPath 00020 { 00021 FileFinderT<LESS> *owner; 00022 int cut; 00023 00024 void add(const boost::filesystem::path &pth) 00025 { 00026 std::string file = pth.string(); 00027 std::string key = file.substr(cut); 00028 owner->table[key] = file; 00029 } 00030 }; 00031 00032 Inserter inserter; 00033 00034 public: 00035 FileFinderT(const boost::filesystem::path &path, bool recurse=true) 00036 { 00037 inserter.owner = this; 00038 00039 // Remember the original path length, so we can cut it away from 00040 // the relative paths used as keys 00041 const std::string& pstring = path.string(); 00042 inserter.cut = pstring.size(); 00043 00044 // If the path does not end in a slash, then boost will add one 00045 // later, which means one more character we have to remove. 00046 char last = *pstring.rbegin(); 00047 if(last != '\\' && last != '/') 00048 inserter.cut++; 00049 00050 // Fill the map 00051 find(path, inserter, recurse); 00052 } 00053 00054 bool has(const std::string& file) const 00055 { 00056 return table.find(file) != table.end(); 00057 } 00058 00059 // Find the full path from a relative path. 00060 const std::string &lookup(const std::string& file) const 00061 { 00062 static std::string empty; 00063 typename TableContainer::const_iterator it = table.find(file); 00064 return (it != table.end()) ? it->second : empty; 00065 } 00066 }; 00067 00068 template 00069 < 00070 class LESS 00071 > 00072 struct TreeFileFinder 00073 { 00074 typedef TreeFileFinder<LESS> finder_t; 00075 00076 TreeFileFinder(const Files::PathContainer& paths, bool recurse = true) 00077 { 00078 struct : ReturnPath 00079 { 00080 finder_t *owner; 00081 int cut; 00082 00083 void add(const boost::filesystem::path &pth) 00084 { 00085 std::string file = pth.string(); 00086 std::string key = file.substr(cut); 00087 owner->mTable[key] = file; 00088 } 00089 } inserter; 00090 00091 inserter.owner = this; 00092 00093 for (Files::PathContainer::const_iterator it = paths.begin(); it != paths.end(); ++it) 00094 { 00095 00096 // Remember the original path length, so we can cut it away from 00097 // the relative paths used as keys 00098 const std::string& pstring = it->string(); 00099 inserter.cut = pstring.size(); 00100 00101 // If the path does not end in a slash, then boost will add one 00102 // later, which means one more character we have to remove. 00103 char last = *pstring.rbegin(); 00104 if (last != '\\' && last != '/') 00105 { 00106 inserter.cut++; 00107 } 00108 00109 // Fill the map 00110 find(*it, inserter, recurse); 00111 } 00112 } 00113 00114 bool has(const std::string& file) const 00115 { 00116 return mTable.find(file) != mTable.end(); 00117 } 00118 00119 const std::string& lookup(const std::string& file) const 00120 { 00121 static std::string empty; 00122 typename TableContainer::const_iterator it = mTable.find(file); 00123 return (it != mTable.end()) ? it->second : empty; 00124 } 00125 00126 private: 00127 typedef std::map<std::string, std::string, LESS> TableContainer; 00128 TableContainer mTable; 00129 00130 // Inserter inserter; 00131 }; 00132 00133 00134 // The default is to use path_less for equality checks 00135 typedef FileFinderT<path_less> FileFinder; 00136 typedef FileFinderT<path_slash> FileFinderStrict; 00137 00138 typedef TreeFileFinder<path_less> LessTreeFileFinder; 00139 typedef TreeFileFinder<path_slash> StrictTreeFileFinder; 00140 00141 } /* namespace FileFinder */ 00142 #endif /* FILE_FINDER_MAIN_H */