OpenMW
components/file_finder/file_finder.hpp
Go to the documentation of this file.
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 */