summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Holder <thomas@thomas-holder.de>2018-12-09 14:45:59 +0000
committerThomas Holder <thomas@thomas-holder.de>2018-12-09 14:45:59 +0000
commitd1d8708fb64eab13695177aab5214e1db4564b24 (patch)
tree17b0fdeaa7568509f7b8ede606be25cf3746014c
parentfix poppler 0.72.0 build (diff)
downloadinkscape-d1d8708fb64eab13695177aab5214e1db4564b24.tar.gz
inkscape-d1d8708fb64eab13695177aab5214e1db4564b24.zip
fix, test, and document more Inkscape::URI methods
-rw-r--r--src/object/uri.cpp56
-rw-r--r--src/object/uri.h33
-rw-r--r--testfiles/src/uri-test.cpp110
3 files changed, 175 insertions, 24 deletions
diff --git a/src/object/uri.cpp b/src/object/uri.cpp
index 94546aec7..5f9a38c5f 100644
--- a/src/object/uri.cpp
+++ b/src/object/uri.cpp
@@ -141,9 +141,29 @@ void URI::Impl::unreference() {
}
}
+// From RFC 2396:
+//
+// URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]
+// absoluteURI = scheme ":" ( hier_part | opaque_part )
+// relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]
+//
+// hier_part = ( net_path | abs_path ) [ "?" query ]
+// opaque_part = uric_no_slash *uric
+//
+// uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
+// "&" | "=" | "+" | "$" | ","
+//
+// net_path = "//" authority [ abs_path ]
+// abs_path = "/" path_segments
+// rel_path = rel_segment [ abs_path ]
+//
+// rel_segment = 1*( unreserved | escaped |
+// ";" | "@" | "&" | "=" | "+" | "$" | "," )
+//
+// authority = server | reg_name
+
bool URI::Impl::isOpaque() const {
- bool opq = !isRelative() && (getOpaque() != nullptr);
- return opq;
+ return getOpaque() != nullptr;
}
bool URI::Impl::isRelative() const {
@@ -151,33 +171,23 @@ bool URI::Impl::isRelative() const {
}
bool URI::Impl::isNetPath() const {
- bool isNet = false;
- if ( isRelative() )
- {
- const gchar *path = getPath();
- isNet = path && path[0] == '\\' && path[1] == '\\';
- }
- return isNet;
+ return isRelative() && _uri->server;
}
bool URI::Impl::isRelativePath() const {
- bool isRel = false;
- if ( isRelative() )
- {
+ if (isRelative() && !_uri->server) {
const gchar *path = getPath();
- isRel = !path || path[0] != '\\';
+ return path && path[0] != '/';
}
- return isRel;
+ return false;
}
bool URI::Impl::isAbsolutePath() const {
- bool isAbs = false;
- if ( isRelative() )
- {
+ if (isRelative() && !_uri->server) {
const gchar *path = getPath();
- isAbs = path && path[0] == '\\'&& path[1] != '\\';
+ return path && path[0] == '/';
}
- return isAbs;
+ return false;
}
const gchar *URI::Impl::getScheme() const {
@@ -197,7 +207,13 @@ const gchar *URI::Impl::getFragment() const {
}
const gchar *URI::Impl::getOpaque() const {
- return (gchar *)_uri->opaque;
+ if (!isRelative() && !_uri->server) {
+ const gchar *path = getPath();
+ if (path && path[0] != '/') {
+ return path;
+ }
+ }
+ return nullptr;
}
/*
diff --git a/src/object/uri.h b/src/object/uri.h
index 98b1a21af..f8a28726b 100644
--- a/src/object/uri.h
+++ b/src/object/uri.h
@@ -103,18 +103,46 @@ public:
*/
bool isAbsolutePath() const { return _impl->isAbsolutePath(); }
+ /**
+ * Return the scheme, e.g.\ "http", or \c NULL if this is not an absolute URI.
+ */
const char *getScheme() const { return _impl->getScheme(); }
+ /**
+ * Return the path.
+ *
+ * Example: "http://host/foo/bar?query#frag" -> "/foo/bar"
+ *
+ * For an opaque URI, this is identical to getOpaque()
+ */
const char *getPath() const { return _impl->getPath(); }
+ /**
+ * Return the query, which is the part between "?" and the optional fragment hash ("#")
+ */
const char *getQuery() const { return _impl->getQuery(); }
+ /**
+ * Return the fragment, which is everything after "#"
+ */
const char *getFragment() const { return _impl->getFragment(); }
+ /**
+ * For an opaque URI, return everything between the scheme colon (":") and the optional
+ * fragment hash ("#"). For non-opaque URIs, return NULL.
+ */
const char *getOpaque() const { return _impl->getOpaque(); }
+ /**
+ * @deprecated The regular constructor auto-detects UTF-8 characters and percent-encodes them.
+ *
+ * @todo remove, it's unused and percent-encodes most reserved characters, including "%", ":", "?", "#".
+ */
static URI fromUtf8( char const* path );
+ /**
+ * Construct a "file" URI from an absolute filename.
+ */
static URI from_native_filename(char const *path);
/**
@@ -128,6 +156,11 @@ public:
*/
static URI from_href_and_basedir(char const *href, char const *basedir);
+ /**
+ * @deprecated Use ::toNativeFilename() instead
+ *
+ * @todo remove
+ */
const std::string getFullPath(std::string const &base) const;
/**
diff --git a/testfiles/src/uri-test.cpp b/testfiles/src/uri-test.cpp
index 847bc4953..eb7257afa 100644
--- a/testfiles/src/uri-test.cpp
+++ b/testfiles/src/uri-test.cpp
@@ -23,11 +23,19 @@ using Inkscape::URI;
char const *DATA_BASE64_HELLO_WORLD = DATA_BASE64_HEADER BASE64_HELLO_WORLD_P1 BASE64_HELLO_WORLD_P2;
char const *DATA_BASE64_HELLO_WORLD_WRAPPED = DATA_BASE64_HEADER BASE64_HELLO_WORLD_P1 "\n" BASE64_HELLO_WORLD_P2;
+char const *win_url_unc = "file://laptop/My%20Documents/FileSchemeURIs.doc";
+char const *win_url_local = "file:///C:/Documents%20and%20Settings/davris/FileSchemeURIs.doc";
+char const *win_filename_local = "C:\\Documents and Settings\\davris\\FileSchemeURIs.doc";
+
TEST(UriTest, GetPath)
{
ASSERT_STREQ(URI("foo.svg").getPath(), "foo.svg");
ASSERT_STREQ(URI("foo.svg#bar").getPath(), "foo.svg");
ASSERT_STREQ(URI("#bar").getPath(), nullptr);
+ ASSERT_STREQ(URI("scheme://host").getPath(), nullptr);
+ ASSERT_STREQ(URI("scheme://host/path").getPath(), "/path");
+ ASSERT_STREQ(URI("scheme://host/path?query").getPath(), "/path");
+ ASSERT_STREQ(URI("scheme:/path").getPath(), "/path");
}
TEST(UriTest, FromDir)
@@ -70,16 +78,13 @@ TEST(UriTest, Str)
ASSERT_EQ(URI("file:///C:/b").str("file:///D:/"), "file:///C:/b"); // special case
ASSERT_EQ(URI("file:///C:/a/b").str("file:///C:/b/"), "../a/b");
- const char *win_url_unc = "file://laptop/My%20Documents/FileSchemeURIs.doc";
- const char *win_url_local = "file:///C:/Documents%20and%20Settings/davris/FileSchemeURIs.doc";
-
ASSERT_EQ(URI(win_url_unc).str(), win_url_unc);
ASSERT_EQ(URI(win_url_unc).str("file://laptop/My%20Documents/"), "FileSchemeURIs.doc");
ASSERT_EQ(URI(win_url_local).str(), win_url_local);
ASSERT_EQ(URI(win_url_local).str("file:///C:/Documents%20and%20Settings/"), "davris/FileSchemeURIs.doc");
ASSERT_EQ(URI(win_url_local).str(win_url_unc), win_url_local);
#ifdef _WIN32
- ASSERT_EQ(URI(win_url_local).toNativeFilename(), "C:\\Documents and Settings\\davris\\FileSchemeURIs.doc");
+ ASSERT_EQ(URI(win_url_local).toNativeFilename(), win_filename_local);
#else
ASSERT_EQ(URI("file:///tmp/uri.svg").toNativeFilename(), "/tmp/uri.svg");
ASSERT_EQ(URI("file:///tmp/x%20y.svg").toNativeFilename(), "/tmp/x y.svg");
@@ -149,6 +154,103 @@ TEST(UriTest, HasScheme)
ASSERT_TRUE(URI::from_href_and_basedir("data:,white\nspace", "/tmp").hasScheme("data"));
}
+TEST(UriTest, isOpaque)
+{
+ ASSERT_FALSE(URI("file:///uri.svg").isOpaque());
+ ASSERT_FALSE(URI("/uri.svg").isOpaque());
+ ASSERT_FALSE(URI("uri.svg").isOpaque());
+ ASSERT_FALSE(URI("foo://bar/baz").isOpaque());
+ ASSERT_FALSE(URI("foo://bar").isOpaque());
+ ASSERT_FALSE(URI("foo:/bar").isOpaque());
+
+ ASSERT_TRUE(URI("foo:bar").isOpaque());
+ ASSERT_TRUE(URI("mailto:user@host.xy").isOpaque());
+ ASSERT_TRUE(URI("news:comp.lang.java").isOpaque());
+}
+
+TEST(UriTest, isRelative)
+{
+ ASSERT_FALSE(URI("http://web/uri.svg").isRelative());
+ ASSERT_FALSE(URI("file:///uri.svg").isRelative());
+ ASSERT_FALSE(URI("mailto:user@host.xy").isRelative());
+ ASSERT_FALSE(URI("data:,").isRelative());
+
+ ASSERT_TRUE(URI("//web/uri.svg").isRelative());
+ ASSERT_TRUE(URI("/uri.svg").isRelative());
+ ASSERT_TRUE(URI("uri.svg").isRelative());
+ ASSERT_TRUE(URI("./uri.svg").isRelative());
+ ASSERT_TRUE(URI("../uri.svg").isRelative());
+}
+
+TEST(UriTest, isNetPath)
+{
+ ASSERT_FALSE(URI("http://web/uri.svg").isNetPath());
+ ASSERT_FALSE(URI("file:///uri.svg").isNetPath());
+ ASSERT_FALSE(URI("/uri.svg").isNetPath());
+ ASSERT_FALSE(URI("uri.svg").isNetPath());
+
+ ASSERT_TRUE(URI("//web/uri.svg").isNetPath());
+}
+
+TEST(UriTest, isRelativePath)
+{
+ ASSERT_FALSE(URI("http://web/uri.svg").isRelativePath());
+ ASSERT_FALSE(URI("//web/uri.svg").isRelativePath());
+ ASSERT_FALSE(URI("/uri.svg").isRelativePath());
+
+ ASSERT_TRUE(URI("uri.svg").isRelativePath());
+ ASSERT_TRUE(URI("./uri.svg").isRelativePath());
+ ASSERT_TRUE(URI("../uri.svg").isRelativePath());
+}
+
+TEST(UriTest, isAbsolutePath)
+{
+ ASSERT_FALSE(URI("http://web/uri.svg").isAbsolutePath());
+ ASSERT_FALSE(URI("//web/uri.svg").isAbsolutePath());
+ ASSERT_FALSE(URI("uri.svg").isAbsolutePath());
+ ASSERT_FALSE(URI("../uri.svg").isAbsolutePath());
+
+ ASSERT_TRUE(URI("/uri.svg").isAbsolutePath());
+}
+
+TEST(UriTest, getScheme)
+{
+ ASSERT_STREQ(URI("https://web/uri.svg").getScheme(), "https");
+ ASSERT_STREQ(URI("file:///uri.svg").getScheme(), "file");
+ ASSERT_STREQ(URI("data:,").getScheme(), "data");
+
+ ASSERT_STREQ(URI("data").getScheme(), nullptr);
+}
+
+TEST(UriTest, getQuery)
+{
+ ASSERT_STREQ(URI("uri.svg?a=b&c=d").getQuery(), "a=b&c=d");
+ ASSERT_STREQ(URI("?a=b&c=d#hash").getQuery(), "a=b&c=d");
+}
+
+TEST(UriTest, getFragment)
+{
+ ASSERT_STREQ(URI("uri.svg").getFragment(), nullptr);
+ ASSERT_STREQ(URI("uri.svg#hash").getFragment(), "hash");
+ ASSERT_STREQ(URI("?a=b&c=d#hash").getFragment(), "hash");
+ ASSERT_STREQ(URI("urn:isbn:096139210x#hash").getFragment(), "hash");
+}
+
+TEST(UriTest, getOpaque)
+{
+ ASSERT_STREQ(URI("urn:isbn:096139210x#hash").getOpaque(), "isbn:096139210x");
+ ASSERT_STREQ(URI("data:,foo").getOpaque(), ",foo");
+}
+
+TEST(UriTest, from_native_filename)
+{
+#ifdef _WIN32
+ ASSERT_EQ(URI::from_native_filename(win_filename_local).str(), win_url_local);
+#else
+ ASSERT_EQ(URI::from_native_filename("/tmp/uri.svg").str(), "file:///tmp/uri.svg");
+ ASSERT_EQ(URI::from_native_filename("/tmp/x y.svg").str(), "file:///tmp/x%20y.svg");
+#endif
+}
/*
Local Variables: