/* This file is part of Raul. * Copyright (C) 2007 Dave Robillard * * Raul is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * Raul is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef RAUL_PATH_HPP #define RAUL_PATH_HPP #include #include #include #include #include #include namespace Raul { /** Simple wrapper around standard string with useful path-specific methods. * * This enforces that a Path is a valid OSC path (though it is used for * GraphObject paths, which aren't directly OSC paths but a portion of one). * * A path is divided by slashes (/). The first character MUST be a slash, and * the last character MUST NOT be a slash (except in the special case of the * root path "/", which is the only valid single-character path). * * Valid characters are the 95 printable ASCII characters (32-126), excluding: * space # * , ? [ ] { } * * \ingroup raul */ class Path : public std::basic_string { public: /** Construct an uninitialzed path, because the STL is annoying. */ Path() : std::basic_string("/") {} /** Construct a Path from an std::string. * * It is a fatal error to construct a Path from an invalid string, * use is_valid first to check. */ Path(const std::basic_string& path) : std::basic_string(path) { assert(is_valid(path)); } /** Construct a Path from a C string. * * It is a fatal error to construct a Path from an invalid string, * use is_valid first to check. */ Path(const char* cpath) : std::basic_string(cpath) { assert(is_valid(cpath)); } static bool is_valid(const std::basic_string& path); static bool is_valid_name(const std::basic_string& name) { return name.length() > 0 && is_valid(std::string("/").append(name)); } static std::string pathify(const std::basic_string& str); static std::string nameify(const std::basic_string& str); static void replace_invalid_chars(std::string& str, bool replace_slash = false); bool is_child_of(const Path& parent) const; bool is_parent_of(const Path& child) const; /** Return the name of this object (everything after the last '/'). * This is the "method name" for OSC paths. */ inline Symbol name() const { if ((*this) == "/") return ""; else return substr(find_last_of("/")+1); } /** Return the parent's path. * * Calling this on the path "/" will return "/". * This is the (deepest) "container path" for OSC paths. */ inline Path parent() const { std::basic_string parent = substr(0, find_last_of("/")); return (parent == "") ? "/" : parent; } /** Return path with a trailing "/". * * Returned value is guaranteed to be a valid parent path, i.e. a valid * child path can be made using parent.base() + child_name. */ inline const std::string base() const { if ((*this) == "/") return *this; else return (*this) + "/"; } /** Return true if \a child is equal to, or a descendant of \a parent */ static bool descendant_comparator(const Path& parent, const Path& child) { return ( child == parent || (child.length() > parent.length() && (!std::strncmp(parent.c_str(), child.c_str(), parent.length()) && (parent == "/" || child[parent.length()] == '/'))) ); } }; } // namespace Raul #endif // RAUL_PATH_HPP