diff options
author | David Robillard <d@drobilla.net> | 2021-03-02 11:09:33 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2022-01-13 23:04:04 -0500 |
commit | aca4640882aab7da0193ee2f5767ecd6d9506b0c (patch) | |
tree | bffe2871b838e6db98838e82cc5ff01d1661922f | |
parent | 9b344f6425657b2a077c3948289199155f490ff9 (diff) | |
download | serd-aca4640882aab7da0193ee2f5767ecd6d9506b0c.tar.gz serd-aca4640882aab7da0193ee2f5767ecd6d9506b0c.tar.bz2 serd-aca4640882aab7da0193ee2f5767ecd6d9506b0c.zip |
Simplify SerdEnv API
-rw-r--r-- | include/serd/serd.h | 26 | ||||
-rw-r--r-- | src/env.c | 51 | ||||
-rw-r--r-- | src/env.h | 21 | ||||
-rw-r--r-- | src/writer.c | 4 | ||||
-rw-r--r-- | test/test_env.c | 74 |
5 files changed, 105 insertions, 71 deletions
diff --git a/include/serd/serd.h b/include/serd/serd.h index 6abadf04..da4291c6 100644 --- a/include/serd/serd.h +++ b/include/serd/serd.h @@ -1437,26 +1437,16 @@ serd_env_set_prefix(SerdEnv* SERD_NONNULL env, SerdStringView name, SerdStringView uri); -/// Qualify `uri` into a CURIE if possible -SERD_API -bool -serd_env_qualify(const SerdEnv* SERD_NULLABLE env, - const SerdNode* SERD_NONNULL uri, - const SerdNode* SERD_NULLABLE* SERD_NONNULL prefix, - SerdStringView* SERD_NONNULL suffix); - /** - Expand `curie`. + Qualify `uri` into a CURIE if possible. - Errors: SERD_ERR_BAD_ARG if `curie` is not valid, or SERD_ERR_BAD_CURIE if - prefix is not defined in `env`. + Returns null if `uri` can not be qualified (usually because no corresponding + prefix is defined). */ SERD_API -SerdStatus -serd_env_expand(const SerdEnv* SERD_NULLABLE env, - const SerdNode* SERD_NULLABLE curie, - SerdStringView* SERD_NONNULL uri_prefix, - SerdStringView* SERD_NONNULL uri_suffix); +SerdNode* SERD_ALLOCATED +serd_env_qualify(const SerdEnv* SERD_NULLABLE env, + const SerdNode* SERD_NULLABLE uri); /** Expand `node`, which must be a CURIE or URI, to a full URI. @@ -1465,8 +1455,8 @@ serd_env_expand(const SerdEnv* SERD_NULLABLE env, */ SERD_API SerdNode* SERD_ALLOCATED -serd_env_expand_node(const SerdEnv* SERD_NULLABLE env, - const SerdNode* SERD_NONNULL node); +serd_env_expand(const SerdEnv* SERD_NULLABLE env, + const SerdNode* SERD_NULLABLE node); /// Write all prefixes in `env` to `sink` SERD_API @@ -161,15 +161,11 @@ serd_env_set_prefix(SerdEnv* const env, } bool -serd_env_qualify(const SerdEnv* const env, - const SerdNode* const uri, - const SerdNode** const prefix, - SerdStringView* const suffix) +serd_env_qualify_in_place(const SerdEnv* const env, + const SerdNode* const uri, + const SerdNode** const prefix, + SerdStringView* const suffix) { - if (!env) { - return false; - } - for (size_t i = 0; i < env->n_prefixes; ++i) { const SerdNode* const prefix_uri = env->prefixes[i].uri; if (uri->length >= prefix_uri->length) { @@ -187,16 +183,35 @@ serd_env_qualify(const SerdEnv* const env, return false; } -SerdStatus -serd_env_expand(const SerdEnv* const env, - const SerdNode* const curie, - SerdStringView* const uri_prefix, - SerdStringView* const uri_suffix) +SerdNode* +serd_env_qualify(const SerdEnv* const env, const SerdNode* const uri) { - if (!env || !curie) { - return SERD_ERR_BAD_CURIE; + if (!env || !uri) { + return NULL; + } + + const SerdNode* prefix = NULL; + SerdStringView suffix = {NULL, 0}; + if (serd_env_qualify_in_place(env, uri, &prefix, &suffix)) { + const size_t prefix_len = serd_node_length(prefix); + const size_t length = prefix_len + 1 + suffix.len; + SerdNode* node = serd_node_malloc(length, 0, SERD_CURIE); + memcpy(serd_node_buffer(node), serd_node_string(prefix), prefix_len); + serd_node_buffer(node)[prefix_len] = ':'; + memcpy(serd_node_buffer(node) + 1 + prefix_len, suffix.buf, suffix.len); + node->length = length; + return node; } + return NULL; +} + +SerdStatus +serd_env_expand_in_place(const SerdEnv* const env, + const SerdNode* const curie, + SerdStringView* const uri_prefix, + SerdStringView* const uri_suffix) +{ const char* const str = serd_node_string(curie); const char* const colon = (const char*)memchr(str, ':', curie->length + 1); if (curie->type != SERD_CURIE || !colon) { @@ -216,9 +231,9 @@ serd_env_expand(const SerdEnv* const env, } SerdNode* -serd_env_expand_node(const SerdEnv* const env, const SerdNode* const node) +serd_env_expand(const SerdEnv* const env, const SerdNode* const node) { - if (!env) { + if (!env || !node) { return NULL; } @@ -230,7 +245,7 @@ serd_env_expand_node(const SerdEnv* const env, const SerdNode* const node) case SERD_CURIE: { SerdStringView prefix; SerdStringView suffix; - if (serd_env_expand(env, node, &prefix, &suffix)) { + if (serd_env_expand_in_place(env, node, &prefix, &suffix)) { return NULL; } @@ -19,6 +19,27 @@ #include "serd/serd.h" +#include <stdbool.h> + +/// Qualify `uri` into a CURIE if possible +bool +serd_env_qualify_in_place(const SerdEnv* env, + const SerdNode* uri, + const SerdNode** prefix, + SerdStringView* suffix); + +/** + Expand `curie`. + + Errors: SERD_ERR_BAD_ARG if `curie` is not valid, or SERD_ERR_BAD_CURIE if + prefix is not defined in `env`. +*/ +SerdStatus +serd_env_expand_in_place(const SerdEnv* env, + const SerdNode* curie, + SerdStringView* uri_prefix, + SerdStringView* uri_suffix); + SERD_CONST_FUNC SerdURIView serd_env_base_uri_view(const SerdEnv* env); diff --git a/src/writer.c b/src/writer.c index bd6caf1e..6a4dda34 100644 --- a/src/writer.c +++ b/src/writer.c @@ -577,7 +577,7 @@ write_uri_node(SerdWriter* const writer, } if (has_scheme && !(writer->flags & SERD_WRITE_UNQUALIFIED) && - serd_env_qualify(writer->env, node, &prefix, &suffix) && + serd_env_qualify_in_place(writer->env, node, &prefix, &suffix) && is_name(serd_node_string(prefix), serd_node_length(prefix)) && is_name(suffix.buf, suffix.len)) { write_uri_from_node(writer, prefix); @@ -629,7 +629,7 @@ write_curie(SerdWriter* const writer, const SerdNode* const node) switch (writer->syntax) { case SERD_NTRIPLES: case SERD_NQUADS: - if ((st = serd_env_expand(writer->env, node, &prefix, &suffix))) { + if ((st = serd_env_expand_in_place(writer->env, node, &prefix, &suffix))) { serd_world_errorf( writer->world, st, "undefined namespace prefix `%s'\n", node_str); return false; diff --git a/test/test_env.c b/test/test_env.c index e5be688e..efde32c5 100644 --- a/test/test_env.c +++ b/test/test_env.c @@ -34,30 +34,35 @@ count_prefixes(void* handle, const SerdEvent* event) static void test_env(void) { + static const SerdStringView prefix = SERD_STRING("eg.2"); + static const SerdStringView eg = SERD_STRING("http://example.org/"); + SerdNodes* nodes = serd_nodes_new(); - const SerdNode* u = + const SerdNode* hello = serd_nodes_string(nodes, SERD_STRING("hello\"")); + const SerdNode* rel = serd_nodes_uri(nodes, SERD_STRING("rel")); + + const SerdNode* foo_u = serd_nodes_uri(nodes, SERD_STRING("http://example.org/foo")); - const SerdNode* b = serd_nodes_curie(nodes, SERD_STRING("invalid")); - const SerdNode* e = serd_nodes_uri(nodes, SERD_EMPTY_STRING()); - const SerdNode* c = serd_nodes_curie(nodes, SERD_STRING("eg.2:b")); - const SerdNode* s = serd_nodes_string(nodes, SERD_STRING("hello")); + const SerdNode* foo_c = serd_nodes_curie(nodes, SERD_STRING("eg.2:foo")); + const SerdNode* b = serd_nodes_curie(nodes, SERD_STRING("invalid")); SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); - const SerdNode* prefix_node = NULL; - SerdStringView prefix = SERD_EMPTY_STRING(); - SerdStringView suffix = SERD_EMPTY_STRING(); - - assert(!serd_env_qualify(NULL, u, &prefix_node, &suffix)); + serd_env_set_prefix(env, prefix, eg); - assert(serd_env_expand(env, NULL, &prefix, &suffix) == SERD_ERR_BAD_CURIE); + assert(!serd_env_base_uri(NULL)); + assert(!serd_env_expand(NULL, NULL)); + assert(!serd_env_expand(NULL, foo_c)); + assert(!serd_env_expand(env, NULL)); + assert(!serd_env_qualify(NULL, NULL)); + assert(!serd_env_qualify(env, NULL)); + assert(!serd_env_qualify(NULL, foo_u)); assert(!serd_env_base_uri(env)); assert(!serd_env_set_base_uri(env, SERD_EMPTY_STRING())); assert(!serd_env_base_uri(env)); - assert(!serd_env_base_uri(env)); serd_env_set_prefix( env, SERD_STRING("eg.2"), SERD_STRING("http://example.org/")); @@ -65,53 +70,56 @@ test_env(void) assert(serd_env_set_prefix(env, SERD_STRING("eg.3"), SERD_STRING("rel")) == SERD_ERR_BAD_ARG); - assert(!serd_env_expand_node(NULL, u)); - assert(!serd_env_expand_node(env, b)); - assert(!serd_env_expand_node(env, s)); - assert(!serd_env_expand_node(env, e)); + SerdNode* xnode = serd_env_expand(env, hello); + assert(!xnode); + + assert(!serd_env_expand(env, b)); + assert(!serd_env_expand(env, hello)); assert(!serd_env_set_base_uri(env, SERD_EMPTY_STRING())); - SerdNode* xu = serd_env_expand_node(env, u); + SerdNode* xu = serd_env_expand(env, foo_c); assert(!strcmp(serd_node_string(xu), "http://example.org/foo")); serd_node_free(xu); const SerdNode* badpre = serd_nodes_curie(nodes, SERD_STRING("hm:what")); - SerdNode* xbadpre = serd_env_expand_node(env, badpre); + SerdNode* xbadpre = serd_env_expand(env, badpre); assert(!xbadpre); - SerdNode* xc = serd_env_expand_node(env, c); - assert(!strcmp(serd_node_string(xc), "http://example.org/b")); + SerdNode* xc = serd_env_expand(env, foo_c); + assert(serd_node_equals(xc, foo_u)); serd_node_free(xc); const SerdNode* blank = serd_nodes_blank(nodes, SERD_STRING("b1")); - assert(!serd_env_expand_node(env, blank)); + assert(!serd_env_expand(env, blank)); size_t n_prefixes = 0; SerdSink* const count_prefixes_sink = serd_sink_new(&n_prefixes, count_prefixes, NULL); - serd_env_set_prefix( - env, SERD_STRING("eg.2"), SERD_STRING("http://example.org/")); + serd_env_set_prefix(env, prefix, eg); serd_env_write_prefixes(env, count_prefixes_sink); assert(n_prefixes == 1); - const SerdNode* shorter_uri = serd_nodes_uri(nodes, SERD_STRING("urn:foo")); - assert(!serd_env_qualify(env, shorter_uri, &prefix_node, &suffix)); + SerdNode* qualified = serd_env_qualify(env, foo_u); + assert(serd_node_equals(qualified, foo_c)); + serd_node_free(qualified); - assert(!serd_env_set_base_uri(env, serd_node_string_view(u))); - assert(serd_node_equals(serd_env_base_uri(env), u)); + const SerdNode* unqualifiable = + serd_nodes_uri(nodes, SERD_STRING("http://drobilla.net/")); - SerdNode* xe = serd_env_expand_node(env, e); - assert(xe); - assert(!strcmp(serd_node_string(xe), "http://example.org/foo")); - serd_node_free(xe); + assert(!serd_env_qualify(env, unqualifiable)); - assert(!serd_env_set_base_uri(env, SERD_EMPTY_STRING())); - assert(!serd_env_base_uri(env)); + assert(!serd_env_expand(env, rel)); + serd_env_set_base_uri(env, SERD_STRING("http://example.org/base/")); + SerdNode* xrel = serd_env_expand(env, rel); + assert(xrel); + assert(!strcmp(serd_node_string(xrel), "http://example.org/base/rel")); + serd_node_free(xrel); serd_sink_free(count_prefixes_sink); serd_nodes_free(nodes); + serd_env_free(env); } |