RAUL
0.7.0
|
00001 /* This file is part of Raul. 00002 * Copyright (C) 2007-2009 David Robillard <http://drobilla.net> 00003 * 00004 * Raul is free software; you can redistribute it and/or modify it under the 00005 * terms of the GNU General Public License as published by the Free Software 00006 * Foundation; either version 2 of the License, or (at your option) any later 00007 * version. 00008 * 00009 * Raul is distributed in the hope that it will be useful, but WITHOUT ANY 00010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00011 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. 00012 * 00013 * You should have received a copy of the GNU General Public License along 00014 * with this program; if not, write to the Free Software Foundation, Inc., 00015 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00016 */ 00017 00018 #ifndef RAUL_PATH_HPP 00019 #define RAUL_PATH_HPP 00020 00021 #include <iostream> 00022 #include <cctype> 00023 #include <string> 00024 #include <cstring> 00025 #include <cassert> 00026 00027 #include "raul/Symbol.hpp" 00028 #include "raul/URI.hpp" 00029 00030 namespace Raul { 00031 00032 00046 class Path : public URI { 00047 public: 00048 class BadPath : public std::exception { 00049 public: 00050 BadPath(const std::string& path) : _path(path) {} 00051 ~BadPath() throw() {} 00052 const char* what() const throw() { return _path.c_str(); } 00053 private: 00054 std::string _path; 00055 }; 00056 00063 static const Path root(); 00064 00078 static void set_root(const Raul::URI& uri); 00079 00080 static bool is_path(const Raul::URI& uri); 00081 00083 Path() : URI(root()) {} 00084 00090 Path(const std::basic_string<char>& path); 00091 00097 Path(const char* cpath); 00098 00099 00105 Path(const Path& copy) : URI(copy) {} 00106 00107 static bool is_valid(const std::basic_string<char>& path); 00108 00109 static bool is_valid_name(const std::basic_string<char>& name) { 00110 return name.length() > 0 && name.find("/") == std::string::npos 00111 && is_valid(std::string("/").append(name)); 00112 } 00113 00114 static std::string pathify(const std::basic_string<char>& str); 00115 static std::string nameify(const std::basic_string<char>& str); 00116 00117 static void replace_invalid_chars(std::string& str, size_t start, bool replace_slash = false); 00118 00119 bool is_root() const { return (*this) == root(); } 00120 00121 bool is_child_of(const Path& parent) const; 00122 bool is_parent_of(const Path& child) const; 00123 00124 Path child(const std::string& s) const { 00125 if (is_valid(s)) 00126 return base() + Path(s).chop_scheme().substr(1); 00127 else 00128 return base() + s; 00129 } 00130 00131 Path child(const Path& p) const { 00132 return base() + p.chop_scheme().substr(1); 00133 } 00134 00135 Path operator+(const Path& p) const { return child(p); } 00136 00142 inline const char* symbol() const { 00143 if ((*this) != root()) { 00144 const char* last_slash = strrchr(c_str(), '/'); 00145 if (last_slash) { 00146 return last_slash + 1; 00147 } 00148 } 00149 return ""; 00150 } 00151 00157 inline Path parent() const { 00158 if ((*this) == root()) { 00159 return *this; 00160 } else { 00161 const std::string str(this->str()); 00162 const size_t first_slash = str.find('/'); 00163 const size_t last_slash = str.find_last_of('/'); 00164 return (first_slash == last_slash) ? root() : str.substr(0, last_slash); 00165 } 00166 } 00167 00168 00171 inline Path child(const Raul::Symbol& symbol) const { 00172 return base() + symbol.c_str(); 00173 } 00174 00175 00178 inline Path relative_to_base(const Path& base) const { 00179 if ((*this) == base) { 00180 return "/"; 00181 } else { 00182 assert(length() > base.length()); 00183 return substr(base.length() - 1); 00184 } 00185 } 00186 00187 00193 inline const std::string base() const { 00194 std::string ret = str(); 00195 if ((*this) == root() && ret[ret.length() - 1] == '/') 00196 return ret; 00197 else 00198 return ret + '/'; 00199 } 00200 00206 inline const std::string base_no_scheme() const { 00207 return base().substr(find(":") + 1); 00208 } 00209 00210 00212 static bool descendant_comparator(const Path& parent, const Path& child) { 00213 return ( child == parent || (child.length() > parent.length() && 00214 (!std::strncmp(parent.c_str(), child.c_str(), parent.length()) 00215 && (parent == root() || child.str()[parent.length()] == '/'))) ); 00216 } 00217 00218 private: 00219 inline Path(bool unchecked, const URI& uri) : URI(uri) {} 00220 }; 00221 00222 00223 } // namespace Raul 00224 00225 #endif // RAUL_PATH_HPP