RAUL 0.8.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 00104 Path(const Path& copy) : URI(copy) {} 00105 00106 static bool is_valid(const std::basic_string<char>& path); 00107 00108 static bool is_valid_name(const std::basic_string<char>& name) { 00109 return name.length() > 0 && name.find("/") == std::string::npos 00110 && is_valid(std::string("/").append(name)); 00111 } 00112 00113 static std::string pathify(const std::basic_string<char>& str); 00114 static std::string nameify(const std::basic_string<char>& str); 00115 00116 static void replace_invalid_chars(std::string& str, size_t start, bool replace_slash = false); 00117 00118 bool is_root() const { return (*this) == root(); } 00119 00120 bool is_child_of(const Path& parent) const; 00121 bool is_parent_of(const Path& child) const; 00122 00123 Path child(const std::string& s) const { 00124 if (is_valid(s)) 00125 return base() + Path(s).chop_scheme().substr(1); 00126 else 00127 return base() + s; 00128 } 00129 00130 Path child(const Path& p) const { 00131 return base() + p.chop_scheme().substr(1); 00132 } 00133 00134 Path operator+(const Path& p) const { return child(p); } 00135 00141 inline const char* symbol() const { 00142 if ((*this) != root()) { 00143 const char* last_slash = strrchr(c_str(), '/'); 00144 if (last_slash) { 00145 return last_slash + 1; 00146 } 00147 } 00148 return ""; 00149 } 00150 00156 inline Path parent() const { 00157 if ((*this) == root()) { 00158 return *this; 00159 } else { 00160 const std::string str(this->str()); 00161 const size_t first_slash = str.find('/'); 00162 const size_t last_slash = str.find_last_of('/'); 00163 return (first_slash == last_slash) ? root() : str.substr(0, last_slash); 00164 } 00165 } 00166 00167 00170 inline Path child(const Raul::Symbol& symbol) const { 00171 return base() + symbol.c_str(); 00172 } 00173 00174 00177 inline Path relative_to_base(const Path& base) const { 00178 if ((*this) == base) { 00179 return "/"; 00180 } else { 00181 assert(length() > base.length()); 00182 return substr(base.length() - 1); 00183 } 00184 } 00185 00186 00192 inline const std::string base() const { 00193 std::string ret = str(); 00194 if ((*this) == root() && ret[ret.length() - 1] == '/') 00195 return ret; 00196 else 00197 return ret + '/'; 00198 } 00199 00205 inline const std::string base_no_scheme() const { 00206 return base().substr(find(":") + 1); 00207 } 00208 00209 00211 static bool descendant_comparator(const Path& parent, const Path& child) { 00212 return ( child == parent || (child.length() > parent.length() && 00213 (!std::strncmp(parent.c_str(), child.c_str(), parent.length()) 00214 && (parent == root() || child.str()[parent.length()] == '/'))) ); 00215 } 00216 00217 private: 00218 inline Path(bool unchecked, const URI& uri) : URI(uri) {} 00219 }; 00220 00221 00222 } // namespace Raul 00223 00224 #endif // RAUL_PATH_HPP