aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--serd/serd.h16
-rw-r--r--src/node.c25
-rw-r--r--src/serdi.c53
3 files changed, 65 insertions, 29 deletions
diff --git a/serd/serd.h b/serd/serd.h
index 25237371..7a7d0bb3 100644
--- a/serd/serd.h
+++ b/serd/serd.h
@@ -190,14 +190,28 @@ SERD_API
SerdNode
serd_node_copy(const SerdNode* node);
+/** Create a new node by resolving @a uri_node into a new node and parsed URI.
+ * This is a basic wrapper of serd_node_new_uri which first parses @a uri_node.
+ * @param uri_node The URI node to parse, resolve, and serialise.
+ * @param base Base URI to resolve @a uri_node against (or NULL).
+ * @param out (Output) set to the parsing of the new URI (i.e. points only to
+ * memory owned by the new returned node).
+ */
+SERD_API
+SerdNode
+serd_node_new_uri_from_node(const SerdNode* uri_node,
+ const SerdURI* base,
+ SerdURI* out);
+
/** Create a new node by serialising @a uri into a new string.
* @param uri The URI to parse and serialise.
+ * @param base Base URI to resolve @a uri against (or NULL for no resolution).
* @param out (Output) set to the parsing of the new URI (i.e. points only to
* memory owned by the new returned node).
*/
SERD_API
SerdNode
-serd_node_new_uri(const SerdURI* uri, SerdURI* out);
+serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out);
/** Free any data owned by @a node.
* Note that if @a node is itself dynamically allocated (which is not the case
diff --git a/src/node.c b/src/node.c
index 1c89eb6d..005e9a01 100644
--- a/src/node.c
+++ b/src/node.c
@@ -72,15 +72,34 @@ string_sink(const void* buf, size_t len, void* stream)
SERD_API
SerdNode
-serd_node_new_uri(const SerdURI* uri, SerdURI* out)
+serd_node_new_uri_from_node(const SerdNode* uri_node,
+ const SerdURI* base,
+ SerdURI* out)
{
- const size_t len = serd_uri_string_length(uri);
+ // Parse (possibly relative) URI
+ SerdURI uri;
+ if (serd_uri_parse(uri_node->buf, &uri)) {
+ return serd_node_new_uri(&uri, base, out);
+ }
+ return SERD_NODE_NULL;
+}
+
+SERD_API
+SerdNode
+serd_node_new_uri(const SerdURI* uri, const SerdURI* base, SerdURI* out)
+{
+ SerdURI abs_uri = *uri;
+ if (base) {
+ serd_uri_resolve(uri, base, &abs_uri);
+ }
+
+ const size_t len = serd_uri_string_length(&abs_uri);
uint8_t* buf = malloc(len + 1);
SerdNode node = { SERD_URI, len + 1, len, buf }; // FIXME: UTF-8
uint8_t* ptr = buf;
- const size_t actual_len = serd_uri_serialise(uri, string_sink, &ptr);
+ const size_t actual_len = serd_uri_serialise(&abs_uri, string_sink, &ptr);
buf[actual_len] = '\0';
node.n_bytes = actual_len + 1;
diff --git a/src/serdi.c b/src/serdi.c
index ed64dfb8..5d7244b2 100644
--- a/src/serdi.c
+++ b/src/serdi.c
@@ -43,22 +43,22 @@ static bool
event_base(void* handle,
const SerdNode* uri_node)
{
- State* const state = (State*)handle;
- SerdNode base_uri_node = *uri_node;
- SerdURI base_uri;
- if (!serd_uri_parse(uri_node->buf, &base_uri)) {
- return false;
- }
+ State* const state = (State*)handle;
- SerdURI abs_base_uri;
- serd_uri_resolve(&base_uri, &state->base_uri, &abs_base_uri);
- base_uri_node = serd_node_new_uri(&abs_base_uri, &base_uri);
+ // Resolve base URI and create a new node and URI for it
+ SerdURI base_uri;
+ SerdNode base_uri_node = serd_node_new_uri_from_node(
+ uri_node, &state->base_uri, &base_uri);
- serd_node_free(&state->base_uri_node);
- state->base_uri_node = base_uri_node;
- state->base_uri = base_uri;
- serd_writer_set_base_uri(state->writer, &base_uri);
- return true;
+ if (base_uri_node.buf) {
+ // Replace the current base URI
+ serd_node_free(&state->base_uri_node);
+ state->base_uri_node = base_uri_node;
+ state->base_uri = base_uri;
+ serd_writer_set_base_uri(state->writer, &base_uri);
+ return true;
+ }
+ return false;
}
static bool
@@ -67,19 +67,22 @@ event_prefix(void* handle,
const SerdNode* uri_node)
{
State* const state = (State*)handle;
- if (!serd_uri_string_has_scheme(uri_node->buf)) {
- SerdURI uri;
- if (!serd_uri_parse(uri_node->buf, &uri)) {
+ if (serd_uri_string_has_scheme(uri_node->buf)) {
+ // Set prefix to absolute URI
+ serd_env_add(state->env, name, uri_node);
+ } else {
+ // Resolve relative URI and create a new node and URI for it
+ SerdURI abs_uri;
+ SerdNode abs_uri_node = serd_node_new_uri_from_node(
+ uri_node, &state->base_uri, &abs_uri);
+
+ if (!abs_uri_node.buf) {
return false;
}
- SerdURI abs_uri;
- serd_uri_resolve(&uri, &state->base_uri, &abs_uri);
- SerdURI base_uri;
- SerdNode base_uri_node = serd_node_new_uri(&abs_uri, &base_uri);
- serd_env_add(state->env, name, &base_uri_node);
- serd_node_free(&base_uri_node);
- } else {
- serd_env_add(state->env, name, uri_node);
+
+ // Set prefix to resolved (absolute) URI
+ serd_env_add(state->env, name, &abs_uri_node);
+ serd_node_free(&abs_uri_node);
}
serd_writer_set_prefix(state->writer, name, uri_node);
return true;