diff options
| author | Thomas Holder <thomas@thomas-holder.de> | 2018-12-09 14:45:59 +0000 |
|---|---|---|
| committer | Thomas Holder <thomas@thomas-holder.de> | 2018-12-09 14:45:59 +0000 |
| commit | d1d8708fb64eab13695177aab5214e1db4564b24 (patch) | |
| tree | 17b0fdeaa7568509f7b8ede606be25cf3746014c | |
| parent | fix poppler 0.72.0 build (diff) | |
| download | inkscape-d1d8708fb64eab13695177aab5214e1db4564b24.tar.gz inkscape-d1d8708fb64eab13695177aab5214e1db4564b24.zip | |
fix, test, and document more Inkscape::URI methods
| -rw-r--r-- | src/object/uri.cpp | 56 | ||||
| -rw-r--r-- | src/object/uri.h | 33 | ||||
| -rw-r--r-- | testfiles/src/uri-test.cpp | 110 |
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: |
