summaryrefslogtreecommitdiffstats
path: root/raul
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-05-13 04:05:32 +0000
committerDavid Robillard <d@drobilla.net>2009-05-13 04:05:32 +0000
commit1e9ca17f0d335df448eda7c0fd89ee94a2068b61 (patch)
tree81774f84ab5168173b226ba0ed9d64633dff7d02 /raul
parent7cd522a148551384fac536e883a595ecc35aadb6 (diff)
downloadraul-1e9ca17f0d335df448eda7c0fd89ee94a2068b61.tar.gz
raul-1e9ca17f0d335df448eda7c0fd89ee94a2068b61.tar.bz2
raul-1e9ca17f0d335df448eda7c0fd89ee94a2068b61.zip
The great ID refactoring of 2009.
Path is now actually URI (scheme path: for now). Therefore ingen nodes and such live in the same namespace as ... well, everything. Including plugins. Thar be profit, laddies. git-svn-id: http://svn.drobilla.net/lad/trunk/raul@1992 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'raul')
-rw-r--r--raul/Path.hpp63
-rw-r--r--raul/URI.hpp111
2 files changed, 157 insertions, 17 deletions
diff --git a/raul/Path.hpp b/raul/Path.hpp
index b6b0b60..bb666de 100644
--- a/raul/Path.hpp
+++ b/raul/Path.hpp
@@ -25,6 +25,7 @@
#include <cassert>
#include "raul/Symbol.hpp"
+#include "raul/URI.hpp"
namespace Raul {
@@ -43,11 +44,23 @@ namespace Raul {
*
* \ingroup raul
*/
-class Path : public std::basic_string<char> {
+class Path : public URI {
public:
+ class BadPath : public std::exception {
+ public:
+ BadPath(const std::string& path) : _path(path) {}
+ ~BadPath() throw() {}
+ const char* what() const throw() { return _path.c_str(); }
+ private:
+ std::string _path;
+ };
+
+ static const std::string prefix;
+ static const size_t prefix_len;
+ static const std::string root_uri;
/** Construct an uninitialzed path, because the STL is annoying. */
- Path() : std::basic_string<char>("/") {}
+ Path() : URI(root_uri) {}
/** Construct a Path from an std::string.
*
@@ -55,21 +68,22 @@ public:
* use is_valid first to check.
*/
Path(const std::basic_string<char>& path)
- : std::basic_string<char>(path)
+ : URI((path.find(":") == std::string::npos) ? prefix + path : path)
{
- assert(is_valid(path));
+ if (!is_valid(str()))
+ throw BadPath(str());
}
-
/** 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<char>(cpath)
+ : URI((std::string(cpath).find(":") == std::string::npos) ? prefix + cpath : cpath)
{
- assert(is_valid(cpath));
+ if (!is_valid(str()))
+ throw BadPath(str());
}
static bool is_valid(const std::basic_string<char>& path);
@@ -82,18 +96,28 @@ public:
static std::string pathify(const std::basic_string<char>& str);
static std::string nameify(const std::basic_string<char>& str);
- static void replace_invalid_chars(std::string& str, bool replace_slash = false);
+ static void replace_invalid_chars(std::string& str, size_t start, bool replace_slash = false);
+ bool is_root() const { return str() == root_uri; }
+
bool is_child_of(const Path& parent) const;
bool is_parent_of(const Path& child) const;
+
+ Path child(const std::string& s) const {
+ if (is_valid(s))
+ return std::string(base()) + Path(s).chop_scheme().substr(1);
+ else
+ return std::string(base()) + s;
+ }
+ Path operator+(const Path& p) const { return child(p); }
/** Return the name of this object (everything after the last '/').
* This is the "method name" for OSC paths.
* The empty string may be returned (if the path is "/").
*/
inline std::string name() const {
- if ((*this) == "/")
+ if (str() == root_uri)
return "";
else
return substr(find_last_of("/")+1);
@@ -115,15 +139,19 @@ public:
* This is the (deepest) "container path" for OSC paths.
*/
inline Path parent() const {
- std::basic_string<char> parent = substr(0, find_last_of("/"));
- return (parent == "") ? "/" : parent;
+ if (str() == root_uri) {
+ return str();
+ } else {
+ size_t last_slash = find_last_of("/");
+ return (last_slash == prefix_len) ? root_uri : substr(0, last_slash);
+ }
}
- /** Return path relative to soe base path (chop prefix)
+ /** Return path relative to some base path (chop prefix)
*/
inline Path relative_to_base(const Path& base) const {
- if ((*this) == base) {
+ if (str() == base) {
return "/";
} else {
assert(length() > base.length());
@@ -138,17 +166,18 @@ public:
* child path can be made using parent.base() + child_name.
*/
inline const std::string base() const {
- if ((*this) == "/")
- return *this;
+ if (str() == root_uri)
+ return str();
else
- return (*this) + "/";
+ return str() + "/";
}
+
/** 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()] == '/'))) );
+ && (parent.str() == root_uri || child[parent.length()] == '/'))) );
}
};
diff --git a/raul/URI.hpp b/raul/URI.hpp
new file mode 100644
index 0000000..5967609
--- /dev/null
+++ b/raul/URI.hpp
@@ -0,0 +1,111 @@
+/* This file is part of Raul.
+ * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
+ *
+ * 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_URI_HPP
+#define RAUL_URI_HPP
+
+#include <string>
+#include <exception>
+#include <ostream>
+
+namespace Raul {
+
+
+/** Simple wrapper around standard string with useful URI-specific methods.
+ *
+ * This "should" be used for proper URIs (RFC3986), but not much support or
+ * validation is built-in yet. The URI string MUST have a scheme though.
+ */
+class URI : protected std::basic_string<char> {
+public:
+ class BadURI : public std::exception {
+ public:
+ BadURI(const std::string& uri) : _uri(uri) {}
+ ~BadURI() throw() {}
+ const char* what() const throw() { return _uri.c_str(); }
+ private:
+ std::string _uri;
+ };
+
+ /** Construct a URI from an std::string.
+ *
+ * It is a fatal error to construct a URI from an invalid string,
+ * use is_valid first to check.
+ */
+ URI(const std::basic_string<char>& uri) : std::basic_string<char>(uri) {
+ if (!is_valid(uri))
+ throw BadURI(uri);
+ }
+
+ /** Construct a URI from a C string.
+ *
+ * It is a fatal error to construct a URI from an invalid string,
+ * use is_valid first to check.
+ */
+ URI(const char* uri) : std::basic_string<char>(uri) {
+ if (!is_valid(uri))
+ throw BadURI(uri);
+ }
+
+ static bool is_valid(const std::basic_string<char>& uri) {
+ return uri.find(":") != std::string::npos;
+ }
+
+ /** Return path with every up to and including the first occurence of str */
+ inline const std::string chop_start(const std::string& str) const {
+ return substr(find(str) + str.length());
+ }
+
+ /** Return the URI with the scheme removed (as a string) */
+ std::string chop_scheme() const { return chop_start(":"); }
+
+ /** Return the URI scheme (everything before the first ':') */
+ inline std::string name() const { return substr(0, find(":")); }
+
+ inline const std::string& str() const { return *this; }
+ inline const char* c_str() const { return str().c_str(); }
+
+ inline operator const std::string() const { return str(); }
+ inline operator std::string() { return str(); }
+
+ inline std::string substr(size_t start, size_t end=std::string::npos) const {
+ return str().substr(start, end);
+ }
+
+ inline bool operator<(const URI& uri) const { return str() < uri; }
+ inline bool operator<=(const URI& uri) const { return str() <= uri; }
+ inline bool operator>(const URI& uri) const { return str() > uri; }
+ inline bool operator>=(const URI& uri) const { return str() >= uri; }
+ inline bool operator==(const URI& uri) const { return str() == uri; }
+ inline bool operator!=(const URI& uri) const { return str() != uri; }
+
+ inline size_t length() const { return str().length(); }
+ inline size_t find(const std::string& s) const { return str().find(s); }
+ inline size_t find_last_of(const std::string& s) const { return str().find_last_of(s); }
+};
+
+static inline
+std::ostream&
+operator<<(std::ostream& os, const URI& uri)
+{
+ return (os << uri.str());
+}
+
+} // namespace Raul
+
+#endif // RAUL_URI_HPP
+