aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-03-02 11:09:33 -0500
committerDavid Robillard <d@drobilla.net>2022-01-13 23:04:04 -0500
commitaca4640882aab7da0193ee2f5767ecd6d9506b0c (patch)
treebffe2871b838e6db98838e82cc5ff01d1661922f
parent9b344f6425657b2a077c3948289199155f490ff9 (diff)
downloadserd-aca4640882aab7da0193ee2f5767ecd6d9506b0c.tar.gz
serd-aca4640882aab7da0193ee2f5767ecd6d9506b0c.tar.bz2
serd-aca4640882aab7da0193ee2f5767ecd6d9506b0c.zip
Simplify SerdEnv API
-rw-r--r--include/serd/serd.h26
-rw-r--r--src/env.c51
-rw-r--r--src/env.h21
-rw-r--r--src/writer.c4
-rw-r--r--test/test_env.c74
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
diff --git a/src/env.c b/src/env.c
index c8ac437e..0b0a31a2 100644
--- a/src/env.c
+++ b/src/env.c
@@ -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;
}
diff --git a/src/env.h b/src/env.h
index 1c36b4ee..50ae82eb 100644
--- a/src/env.h
+++ b/src/env.h
@@ -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);
}