|
libpsynth 0.2.1
|
00001 00011 /* 00012 * Copyright (C) 2008 Juan Pedro BolĂvar Puente 00013 * 00014 * This file is part of Psychosynth. 00015 * 00016 * Psychosynth is free software: you can redistribute it and/or modify 00017 * it under the terms of the GNU General Public License as published by 00018 * the Free Software Foundation, either version 3 of the License, or 00019 * (at your option) any later version. 00020 * 00021 * Psychosynth is distributed in the hope that it will be useful, 00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00024 * GNU General Public License for more details. 00025 * 00026 * You should have received a copy of the GNU General Public License 00027 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00028 * 00029 */ 00030 00031 #ifndef PSYNTH_FILE_FINDER_H 00032 #define PSYNTH_FILE_FINDER_H 00033 00034 #include <iostream> 00035 #include <list> 00036 #include <map> 00037 #include <string> 00038 #include <cstdlib> 00039 00040 #include <boost/filesystem.hpp> 00041 #include <psynth/base/misc.hpp> 00042 00043 namespace psynth 00044 { 00045 namespace base 00046 { 00047 00048 class path_predicate 00049 { 00050 public: 00051 virtual bool operator () (const boost::filesystem::path& str) = 0; 00052 }; 00053 00054 template <class IterType> 00055 class has_extension : public path_predicate 00056 { 00057 IterType m_first; 00058 IterType m_last; 00059 00060 public: 00061 has_extension (IterType first, IterType last) : 00062 m_first(first), 00063 m_last(last) 00064 {}; 00065 00066 bool operator () (const boost::filesystem::path& path) { 00067 for (IterType i = m_first; i != m_last; ++i) 00068 if (extension (path) != *i) 00069 return true; 00070 return false; 00071 } 00072 }; 00073 00074 00075 template<class IterType> 00076 has_extension <IterType> make_has_extension (IterType first, IterType last) 00077 { 00078 return has_extension <IterType> (first, last); 00079 } 00080 00081 class file_finder 00082 { 00083 public: 00084 typedef std::list <boost::filesystem::path> path_list; 00085 typedef std::map <boost::filesystem::path, 00086 boost::filesystem::path> path_map; 00087 00088 file_finder () 00089 : m_cache_updated (false) 00090 , m_cache_auto (false) 00091 {} 00092 00093 void add_path (const boost::filesystem::path& path); 00094 void del_path (const boost::filesystem::path& path); 00095 void build_cache (bool autoupdate); 00096 void clear_cache (); 00097 void clear (); 00098 00099 boost::filesystem::path 00100 find (const boost::filesystem::path& file) const; 00101 00102 template <class PathPredicate> 00103 void find_if (PathPredicate pred, path_list & res) const; 00104 00105 private: 00106 path_list m_paths; 00107 path_map m_cache; 00108 00109 bool m_cache_updated; 00110 bool m_cache_auto; 00111 00112 void cache_path (const boost::filesystem::path& path); 00113 void uncache_path (const boost::filesystem::path& path); 00114 00115 boost::filesystem::path find_in (const boost::filesystem::path& path, 00116 const boost::filesystem::path& file) const; 00117 00118 template<class path_predicate> 00119 int get_file_list (const boost::filesystem::path& folder, 00120 path_list& res, 00121 path_predicate pred) const; 00122 }; 00123 00124 00125 template<class path_predicate> 00126 int file_finder::get_file_list (const boost::filesystem::path& folder, 00127 path_list& res, 00128 path_predicate pred) const 00129 { 00130 int n = 0; 00131 00132 if (!boost::filesystem::exists (folder)) 00133 return n; 00134 00135 boost::filesystem::directory_iterator end_itr; 00136 for (boost::filesystem::directory_iterator itr (folder); 00137 itr != end_itr; 00138 ++itr) { 00139 if (pred (itr->path ())) { 00140 res.push_back (itr->path ()); 00141 ++n; 00142 } 00143 } 00144 00145 return n; 00146 } 00147 00148 template<class path_predicate> 00149 void file_finder::find_if (path_predicate pred, path_list& result) const 00150 { 00151 if (!m_cache_updated) { 00152 path_list::const_iterator iter; 00153 for (iter = m_paths.begin(); iter != m_paths.end(); ++iter) 00154 get_file_list (*iter, result, pred); 00155 } else { 00156 path_map::const_iterator iter; 00157 for (iter = m_cache.begin(); iter != m_cache.end(); ++iter) 00158 if (pred (iter->first)) 00159 result.push_back (iter->second); 00160 } 00161 } 00162 00163 } /* namespace base */ 00164 } /* namespace psynth */ 00165 00166 #endif /* PSYNTH_FILEFINDER_H */
1.7.4