diff options
-rw-r--r-- | serd/serd.h | 16 | ||||
-rw-r--r-- | src/node.c | 25 | ||||
-rw-r--r-- | src/serdi.c | 53 |
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 @@ -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; |