• Main Page
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

Path.hpp

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

Generated on Tue Jan 11 2011 18:26:17 for RAUL by  doxygen 1.7.1