summaryrefslogtreecommitdiffstats
path: root/raul/URI.hpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-08-14 04:22:07 +0000
committerDavid Robillard <d@drobilla.net>2012-08-14 04:22:07 +0000
commit2a429ca76b97cca197f105b665271360b74f6917 (patch)
treed25d206910bd4a84050918693816240c26d7d0ae /raul/URI.hpp
parent8bf87dc2367caf9d82dbda0382363cda400971dc (diff)
downloadraul-2a429ca76b97cca197f105b665271360b74f6917.tar.gz
raul-2a429ca76b97cca197f105b665271360b74f6917.tar.bz2
raul-2a429ca76b97cca197f105b665271360b74f6917.zip
Remove glib dependency.
Make Symbol, URI, and Path simpler derivatives of std::string. 100% test coverage by line for Symbol, URI, Path, AtomicInt, and AtomicPtr. Add Raul::Exception. git-svn-id: http://svn.drobilla.net/lad/trunk/raul@4686 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'raul/URI.hpp')
-rw-r--r--raul/URI.hpp115
1 files changed, 51 insertions, 64 deletions
diff --git a/raul/URI.hpp b/raul/URI.hpp
index 83454ca..b2ccad7 100644
--- a/raul/URI.hpp
+++ b/raul/URI.hpp
@@ -18,39 +18,30 @@
#define RAUL_URI_HPP
#include <string>
-#include <cstring>
-#include <exception>
-#include <ostream>
-#include <glib.h>
-#include "raul/Path.hpp"
+#include "raul/Exception.hpp"
namespace Raul {
-/** Simple wrapper around standard string with useful URI-specific methods.
+/** A URI (RFC3986) string.
*
- * 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.
- * \ingroup raul
+ * @ingroup raul
*/
-class URI {
+class URI : public std::basic_string<char> {
public:
- class BadURI : public std::exception {
+ /** Attempt to construct an invalid URI. */
+ class BadURI : public Exception {
public:
- explicit BadURI(const std::string& uri) : _uri(uri) {}
- ~BadURI() throw() {}
- const char* what() const throw() { return _uri.c_str(); }
- private:
- const std::string _uri;
+ explicit BadURI(const std::string& uri) : Exception(uri) {}
};
- /** Construct a URI from an std::string.
+ /** 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.
+ * This will throw an exception if @p uri is invalid. To avoid this, use
+ * is_valid() first to check.
*/
- URI(const std::basic_string<char>& uri="nil:0") throw(BadURI)
- : _str(g_intern_string(uri.c_str()))
+ explicit URI(const std::basic_string<char>& uri)
+ : std::basic_string<char>(uri)
{
if (!is_valid(uri)) {
throw BadURI(uri);
@@ -59,67 +50,63 @@ public:
/** 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.
+ * This will throw an exception if @p uri is invalid. To avoid this, use
+ * is_valid() first to check.
*/
- URI(const char* uri) throw(BadURI)
- : _str(g_intern_string(uri))
+ explicit URI(const char* uri)
+ : std::basic_string<char>(uri)
{
- if (!is_valid(uri))
+ if (!is_valid(uri)) {
throw BadURI(uri);
+ }
}
- /** Construct a URI from a base URI and a Path. */
- URI(const URI& base, const Path& path)
- : _str(g_intern_string((base.str() + path.c_str()).c_str()))
+ /** Copy a URI.
+ *
+ * Note this is faster than constructing a URI from another URI's string
+ * since validation is unnecessary.
+ */
+ URI(const URI& uri)
+ : std::basic_string<char>(uri)
{}
- static bool is_valid(const std::basic_string<char>& uri) {
- return uri.find(":") != std::string::npos;
+ /** Return true iff @p c is a valid URI start character. */
+ static inline bool is_valid_start_char(char c) {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
- /** Return path with everything up to and including the first occurence of str chopped */
- inline const std::string chop_start(const std::string& str) const {
- return substr(find(str) + str.length());
+ /** Return true iff @p c is a valid URI scheme character. */
+ static inline bool is_valid_scheme_char(char c) {
+ // S3.1: scheme ::= ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+ return is_valid_start_char(c) || (c >= '0' && c <= '9') ||
+ c == '+' || c == '-' || c == '.';
}
- /** 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 scheme() const { return substr(0, find(":")); }
+ /** Return true iff @p str is a valid URI.
+ *
+ * Currently this only checks that @p starts with a valid URI scheme.
+ */
+ static inline bool is_valid(const std::basic_string<char>& str) {
+ if (!is_valid_start_char(str[0])) {
+ return false; // Must start with a-z A-Z
+ }
- inline const std::string str() const { return _str; }
- inline const char* c_str() const { return _str; }
+ for (size_t i = 1; i < str.length(); ++i) {
+ if (str[i] == ':') {
+ return true; // Starts with a valid scheme
+ } else if (!is_valid_scheme_char(str[i])) {
+ return false; // Invalid scheme character encountered
+ }
+ }
- inline std::string substr(size_t start, size_t end=std::string::npos) const {
- return str().substr(start, end);
+ return false; // Must start with a scheme followed by ':'
}
- inline bool operator<(const URI& uri) const { return strcmp(_str, uri.c_str()) < 0; }
- inline bool operator<=(const URI& uri) const { return (*this) == uri || (*this) < uri; }
- inline bool operator==(const URI& uri) const { return _str == uri._str; }
- inline bool operator!=(const URI& uri) const { return _str != uri._str; }
-
- inline char operator[](int i) const { return _str[i]; }
-
- 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(char c) const { return str().find_last_of(c); }
-
-private:
- const char* _str;
+ /** Return the URI scheme (everything before the first ':') */
+ inline std::string scheme() const { return substr(0, find(":")); }
};
} // namespace Raul
-static inline
-std::ostream&
-operator<<(std::ostream& os, const Raul::URI& uri)
-{
- return (os << uri.c_str());
-}
-
-
#endif // RAUL_URI_HPP