00001 #ifndef s11n_net_S11N_PLUGIN_PATHFINDER_HPP_INCLUDED 00002 #define s11n_net_S11N_PLUGIN_PATHFINDER_HPP_INCLUDED 00003 // Author: stephan beal <stephan@s11n.net> 00004 // License: Public Domain 00005 00006 00007 00008 #include <string> 00009 #include <list> 00010 #include <map> 00011 #include <iostream> 00012 00013 namespace s11n { namespace plugin { 00014 /** 00015 path_finder searches for keys using a set of prefixes 00016 (paths) and suffixes (file extensions). 00017 00018 Example: 00019 00020 <pre> 00021 path_finder p; 00022 p.path( "/lib:/usr/lib" ); 00023 p.extensions( ".a:.so" ); 00024 std::cout << p.find( "libz" ) << std::endl; 00025 </pre> 00026 00027 That would print an empty string if it finds nothing, or a 00028 string if it finds any of the following: 00029 00030 - libz (that is, if the value passed is an existing file, 00031 it is returned as-is). 00032 - /lib/libz 00033 - /lib/libz.a 00034 - /lib/libz.so 00035 - /usr/lib/libz 00036 - /usr/lib/libz.a 00037 - /usr/lib/libz.so 00038 00039 00040 Maintainer's note: 00041 00042 This cide was one of my very first STL-based classes, and 00043 the implementation probably shows that very clearly. That 00044 said, it has worked well for me for some four years now 00045 without any appeciable maintenance. :) 00046 */ 00047 class path_finder 00048 { 00049 public: 00050 00051 /** 00052 A list type returned by some functions. 00053 */ 00054 typedef std::list<std::string> string_list; 00055 00056 00057 /** 00058 Creates object with the given path/extension list. 00059 */ 00060 path_finder( const std::string & path = std::string(), const std::string & ext = std::string(), const std::string & pathsep = ":" ); 00061 00062 virtual ~path_finder(); 00063 00064 /** 00065 Returns a ":"-separated string of all paths added via add/path(). 00066 */ 00067 std::string path_string() const; 00068 00069 /** 00070 Sets the string used as a separator for the 00071 string-based variants of path(), extentions(), etc. 00072 */ 00073 void path_separator( const std::string & sep ); 00074 00075 /** 00076 Returns the path separator string. Default is ":"; 00077 */ 00078 const std::string & path_separator() const; 00079 00080 /** 00081 Sets the path to p, which should be a path_separator()-delimited string. 00082 Returns the number of path elements parsed from p. 00083 */ 00084 virtual std::size_t path( const std::string & p ); 00085 00086 /** 00087 Sets the path to the given list of directories. 00088 Returns the number of elements in the list. 00089 */ 00090 virtual std::size_t path( const string_list & p ); 00091 00092 /** 00093 Adds p to the path. May be path_separtor()-delimited. 00094 */ 00095 virtual void add_path( const std::string & p ); 00096 00097 /** 00098 Adds a "search extension." Sample: 00099 finder.extension( ".txt:.TXT" ); Will now try all 00100 path combinations with the rightmost characters 00101 matching ".txt" or ".TXT" (in that order). Be sure 00102 to include a period if you want that searched - 00103 that is so this class can be used to find non-files 00104 and those with non-traditional extensions, like 00105 "foo_EXT". 00106 */ 00107 virtual void add_extension( const std::string & ext = std::string() ); 00108 /** 00109 like add_extension(), but overwrites extension list. 00110 Returns the number of entries parsed from the string. 00111 */ 00112 virtual std::size_t extensions( const std::string & ext ); 00113 /** 00114 Sets the extensions list to the given list. 00115 Returns the number of entries in p. 00116 */ 00117 virtual std::size_t extensions( const string_list & p ); 00118 00119 /** 00120 Returns the path_separator()-delimited listed of file 00121 suffixes to use when searching for a path. 00122 */ 00123 std::string extensions_string() const; 00124 /** 00125 Returns this object's extensions list. 00126 */ 00127 const string_list & extensions() const; 00128 00129 /** Non-const overload, intended for serialization. */ 00130 string_list & extensions(); 00131 00132 /** 00133 Helper function to collapse a list into a string. 00134 00135 This function was changed from a normal member to 00136 static member in s11n version 1.1.3. 00137 */ 00138 static std::string join_list( const string_list & list, const std::string & separator ); 00139 00140 /** 00141 Returns true if path is readable. 00142 */ 00143 static bool is_accessible( const std::string & path ); 00144 00145 /** 00146 Returns the "base name" of the given string: any part 00147 following the final directory separator character. 00148 */ 00149 static std::string basename( const std::string & ); 00150 00151 /** 00152 Returns a platform-dependent path separator. This 00153 is set when the class is compiled. 00154 */ 00155 static std::string dir_separator(); 00156 00157 /** 00158 Returns the full path of the given resource, 00159 provided it could be found using the available 00160 lookup paths/extensions and is readable. Note that 00161 this might return a relative path, especially if 00162 the resourcename passed to it immediately resolves 00163 to an existing resource. It returns an empty 00164 string if the resourcename cannot be found in the 00165 filesystem tree (or is otherwise unaccessible). 00166 00167 If check_cache is false then this function ignores 00168 its lookup cache and searches again, otherwise it 00169 uses a cache. When caching it will always return 00170 the same result for any given resourcename. 00171 */ 00172 std::string find( const std::string & resourcename, bool check_cache = true ) const; 00173 00174 /** 00175 Empties the hit-cache used by find(). 00176 */ 00177 void clear_cache(); 00178 00179 /** 00180 Returns a list of all items added via add_path() and path(). 00181 */ 00182 const string_list & path() const; 00183 /** Non-const overload, intended for serialization. */ 00184 string_list & path(); 00185 00186 00187 /** Returns true if this object has no paths or extensions. */ 00188 bool empty() const; 00189 00190 private: 00191 string_list paths; 00192 string_list exts; 00193 std::string pathseparator; 00194 typedef std::map < std::string, std::string > StringStringMap; 00195 typedef StringStringMap::iterator StringStringIterator; 00196 mutable StringStringMap hitcache; 00197 }; 00198 00199 00200 }} // namespace 00201 00202 #endif // s11n_net_S11N_PLUGIN_PATHFINDER_HPP_INCLUDED