summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1
-rw-r--r--sord/sord.h11
-rw-r--r--sord/sordmm.hpp11
-rw-r--r--src/sord.c20
-rw-r--r--src/sord_test.c18
5 files changed, 58 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index f61ad68..ddc3241 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,7 @@ sord (UNRELEASED) unstable; urgency=low
* Support compilation as C++ under MSVC++.
* Add sord_iter_get_node()
* Refuse to intern relative URIs in sord_new_uri*()
+ * Add sord_new_relative_uri()
-- David Robillard <d@drobilla.net> (UNRELEASED)
diff --git a/sord/sord.h b/sord/sord.h
index 7d3412e..0d71d99 100644
--- a/sord/sord.h
+++ b/sord/sord.h
@@ -161,7 +161,16 @@ sord_world_free(SordWorld* world);
*/
SORD_API
SordNode*
-sord_new_uri(SordWorld* world, const uint8_t* str);
+sord_new_uri(SordWorld* world, const uint8_t* uri);
+
+/**
+ Get a URI node from a relative URI string.
+*/
+SORD_API
+SordNode*
+sord_new_relative_uri(SordWorld* world,
+ const uint8_t* str,
+ const uint8_t* base_uri);
/**
Get a blank node from a string.
diff --git a/sord/sordmm.hpp b/sord/sordmm.hpp
index 5f71f09..8a08c83 100644
--- a/sord/sordmm.hpp
+++ b/sord/sordmm.hpp
@@ -221,6 +221,11 @@ class URI : public Node {
public:
inline URI(World& world, const std::string& s)
: Node(world, Node::URI, s) {}
+ inline URI(World& world, const std::string& s, const std::string& base)
+ : Node(world, sord_new_relative_uri(world.world(),
+ (const uint8_t*)s.c_str(),
+ (const uint8_t*)base.c_str()))
+ {}
};
class Curie : public Node {
@@ -406,13 +411,15 @@ public:
const std::string& uri,
SerdSyntax syntax = SERD_TURTLE,
SerdStyle style = (SerdStyle)(SERD_STYLE_ABBREVIATED
- |SERD_STYLE_CURIED));
+ |SERD_STYLE_CURIED
+ |SERD_STYLE_RESOLVED));
inline std::string write_to_string(
const std::string& base_uri,
SerdSyntax syntax = SERD_TURTLE,
SerdStyle style = (SerdStyle)(SERD_STYLE_ABBREVIATED
- |SERD_STYLE_CURIED));
+ |SERD_STYLE_CURIED
+ |SERD_STYLE_RESOLVED));
inline void add_statement(const Node& subject,
const Node& predicate,
diff --git a/src/sord.c b/src/sord.c
index 2ffa414..5fab21e 100644
--- a/src/sord.c
+++ b/src/sord.c
@@ -959,6 +959,7 @@ sord_new_uri_counted(SordWorld* world, const uint8_t* str,
size_t n_bytes, size_t n_chars, bool copy)
{
if (!serd_uri_string_has_scheme(str)) {
+ fprintf(stderr, "Attempt to map invalid URI `%s'.\n", str);
return NULL; // Can't intern relative URIs
}
@@ -985,6 +986,25 @@ sord_new_uri(SordWorld* world, const uint8_t* str)
return sord_new_uri_counted(world, str, node.n_bytes, node.n_chars, true);
}
+SordNode*
+sord_new_relative_uri(SordWorld* world,
+ const uint8_t* str,
+ const uint8_t* base_str)
+{
+ if (serd_uri_string_has_scheme(str)) {
+ return sord_new_uri(world, str);
+ }
+ SerdURI buri = SERD_URI_NULL;
+ SerdNode base = serd_node_new_uri_from_string(base_str, NULL, &buri);
+ SerdNode node = serd_node_new_uri_from_string(str, &buri, NULL);
+
+ SordNode* ret = sord_new_uri_counted(
+ world, node.buf, node.n_bytes, node.n_chars, false);
+
+ serd_node_free(&base);
+ return ret;
+}
+
static SordNode*
sord_new_blank_counted(SordWorld* world, const uint8_t* str,
size_t n_bytes, size_t n_chars)
diff --git a/src/sord_test.c b/src/sord_test.c
index 15d4ad6..9d5f008 100644
--- a/src/sord_test.c
+++ b/src/sord_test.c
@@ -437,6 +437,24 @@ main(int argc, char** argv)
goto fail;
}
+ // Check relative URI construction
+ SordNode* reluri = sord_new_relative_uri(
+ world, USTR("a/b"), USTR("http://example.org/"));
+ if (strcmp((const char*)sord_node_get_string(reluri),
+ "http://example.org/a/b")) {
+ fprintf(stderr, "Fail: Bad relative URI constructed: <%s>\n",
+ sord_node_get_string(reluri));
+ goto fail;
+ }
+ SordNode* reluri2 = sord_new_relative_uri(
+ world, USTR("http://drobilla.net/"), USTR("http://example.org/"));
+ if (strcmp((const char*)sord_node_get_string(reluri2),
+ "http://drobilla.net/")) {
+ fprintf(stderr, "Fail: Bad relative URI constructed: <%s>\n",
+ sord_node_get_string(reluri));
+ goto fail;
+ }
+
// Check comparison with NULL
sord_node_free(world, uri_id);
sord_node_free(world, blank_id);