diff options
-rw-r--r-- | serd/serd.h | 30 | ||||
-rw-r--r-- | src/env.c | 78 | ||||
-rw-r--r-- | src/env.h | 28 | ||||
-rw-r--r-- | src/writer.c | 11 | ||||
-rw-r--r-- | tests/serd_test.c | 45 |
5 files changed, 115 insertions, 77 deletions
diff --git a/serd/serd.h b/serd/serd.h index 9e1c651e..14a82389 100644 --- a/serd/serd.h +++ b/serd/serd.h @@ -881,17 +881,14 @@ serd_env_get_base_uri(const SerdEnv* env); */ SERD_API SerdStatus -serd_env_set_base_uri(SerdEnv* env, - const SerdNode* uri); +serd_env_set_base_uri(SerdEnv* env, const SerdNode* uri); /** Set a namespace prefix. */ SERD_API SerdStatus -serd_env_set_prefix(SerdEnv* env, - const SerdNode* name, - const SerdNode* uri); +serd_env_set_prefix(SerdEnv* env, const SerdNode* name, const SerdNode* uri); /** Set a namespace prefix. @@ -904,26 +901,12 @@ serd_env_set_prefix_from_strings(SerdEnv* env, /** Qualify `uri` into a CURIE if possible. -*/ -SERD_API -bool -serd_env_qualify(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`. + Returns null if `node` can not be qualified. */ SERD_API -SerdStatus -serd_env_expand(const SerdEnv* env, - const SerdNode* curie, - SerdStringView* uri_prefix, - SerdStringView* uri_suffix); +SerdNode* +serd_env_qualify(const SerdEnv* env, const SerdNode* uri); /** Expand `node`, which must be a CURIE or URI, to a full URI. @@ -932,8 +915,7 @@ serd_env_expand(const SerdEnv* env, */ SERD_API SerdNode* -serd_env_expand_node(const SerdEnv* env, - const SerdNode* node); +serd_env_expand(const SerdEnv* env, const SerdNode* node); /** Call `func` for each prefix defined in `env`. @@ -155,26 +155,11 @@ serd_env_set_prefix(SerdEnv* env, return SERD_SUCCESS; } -SerdStatus -serd_env_set_prefix_from_strings(SerdEnv* env, - const char* name, - const char* uri) -{ - SerdNode* name_node = serd_new_string(name); - SerdNode* uri_node = serd_new_uri(uri); - - const SerdStatus st = serd_env_set_prefix(env, name_node, uri_node); - - serd_node_free(name_node); - serd_node_free(uri_node); - return st; -} - bool -serd_env_qualify(const SerdEnv* env, - const SerdNode* uri, - const SerdNode** prefix, - SerdStringView* suffix) +serd_env_qualify_in_place(const SerdEnv* env, + const SerdNode* uri, + const SerdNode** prefix, + SerdStringView* suffix) { for (size_t i = 0; i < env->n_prefixes; ++i) { const SerdNode* const prefix_uri = env->prefixes[i].uri; @@ -194,10 +179,46 @@ serd_env_qualify(const SerdEnv* env, } SerdStatus -serd_env_expand(const SerdEnv* env, - const SerdNode* curie, - SerdStringView* uri_prefix, - SerdStringView* uri_suffix) +serd_env_set_prefix_from_strings(SerdEnv* env, + const char* name, + const char* uri) +{ + SerdNode* name_node = serd_new_string(name); + SerdNode* uri_node = serd_new_uri(uri); + + const SerdStatus st = serd_env_set_prefix(env, name_node, uri_node); + + serd_node_free(name_node); + serd_node_free(uri_node); + return st; +} + +SerdNode* +serd_env_qualify(const SerdEnv* env, const SerdNode* uri) +{ + 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_get_length(prefix); + const size_t n_bytes = prefix_len + 1 + suffix.len; + SerdNode* node = serd_node_malloc(n_bytes, 0, SERD_CURIE); + memcpy(serd_node_buffer(node), + serd_node_get_string(prefix), + prefix_len); + serd_node_buffer(node)[prefix_len] = ':'; + memcpy(serd_node_buffer(node) + 1 + prefix_len, suffix.buf, suffix.len); + node->n_bytes = n_bytes; + return node; + } + + return NULL; +} + +SerdStatus +serd_env_expand_in_place(const SerdEnv* env, + const SerdNode* curie, + SerdStringView* uri_prefix, + SerdStringView* uri_suffix) { const char* const str = serd_node_get_string(curie); const char* const colon = (const char*)memchr(str, ':', curie->n_bytes + 1); @@ -218,14 +239,17 @@ serd_env_expand(const SerdEnv* env, } SerdNode* -serd_env_expand_node(const SerdEnv* env, - const SerdNode* node) +serd_env_expand(const SerdEnv* env, const SerdNode* node) { + if (!node) { + return NULL; + } + switch (node->type) { 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; } const size_t len = prefix.len + suffix.len; @@ -237,7 +261,7 @@ serd_env_expand_node(const SerdEnv* env, } case SERD_LITERAL: if (serd_node_get_datatype(node)) { - SerdNode* datatype = serd_env_expand_node( + SerdNode* datatype = serd_env_expand( env, serd_node_get_datatype(node)); if (datatype) { SerdNode* ret = serd_new_typed_literal( @@ -19,6 +19,30 @@ #include "serd/serd.h" -const SerdURI* serd_env_get_parsed_base_uri(const SerdEnv* env); +#include <stdbool.h> -#endif // SERD_ENV_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); + +const SerdURI* +serd_env_get_parsed_base_uri(const SerdEnv* env); + +#endif // SERD_ENV_H diff --git a/src/writer.c b/src/writer.c index 692139a6..55feb3f0 100644 --- a/src/writer.c +++ b/src/writer.c @@ -514,7 +514,7 @@ write_uri_node(SerdWriter* const writer, } else if (supports_abbrev(writer) && !strcmp(node_str, NS_RDF "nil")) { return sink("()", 2, writer) == 2; } else if (has_scheme && (writer->style & SERD_STYLE_CURIED) && - serd_env_qualify(writer->env, node, &prefix, &suffix) && + serd_env_qualify_in_place(writer->env, node, &prefix, &suffix) && is_name(suffix.buf, suffix.len)) { write_uri_from_node(writer, prefix); sink(":", 1, writer); @@ -562,9 +562,12 @@ write_curie(SerdWriter* const writer, switch (writer->syntax) { case SERD_NTRIPLES: case SERD_NQUADS: - if ((st = serd_env_expand(writer->env, node, &prefix, &suffix))) { - serd_world_errorf(writer->world, st, - "undefined namespace prefix `%s'\n", node_str); + 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; } write_sep(writer, SEP_URI_BEGIN); diff --git a/tests/serd_test.c b/tests/serd_test.c index b8b35a0b..2fddc5bf 100644 --- a/tests/serd_test.c +++ b/tests/serd_test.c @@ -409,35 +409,36 @@ main(void) return 1; } - SerdNode* u = serd_new_uri("http://example.org/foo"); - SerdNode* b = serd_new_curie("invalid"); - SerdNode* c = serd_new_curie("eg.2:b"); - SerdEnv* env = serd_env_new(NULL); - serd_env_set_prefix_from_strings(env, "eg.2", "http://example.org/"); + SerdNode* eg = serd_new_uri("http://example.org/"); + SerdNode* foo_u = serd_new_uri("http://example.org/foo"); + SerdNode* foo_c = serd_new_curie("eg.2:foo"); + SerdNode* b = serd_new_curie("invalid"); + SerdNode* pre = serd_new_curie("eg.2"); + SerdEnv* env = serd_env_new(NULL); + serd_env_set_prefix(env, pre, eg); assert(!serd_env_get_base_uri(env)); assert(serd_env_set_base_uri(env, NULL)); assert(!serd_env_get_base_uri(env)); assert(serd_env_set_base_uri(env, hello)); assert(!serd_env_get_base_uri(env)); - serd_node_free(hello); - SerdStringView prefix; - SerdStringView suffix; - assert(serd_env_expand(env, b, &prefix, &suffix)); + SerdNode* xnode = serd_env_expand(env, hello); + assert(!xnode); - assert(!serd_env_expand_node(env, b)); + serd_node_free(hello); - SerdNode* xu = serd_env_expand_node(env, u); + SerdNode* xu = serd_env_expand(env, foo_c); assert(!strcmp(serd_node_get_string(xu), "http://example.org/foo")); serd_node_free(xu); SerdNode* badpre = serd_new_curie("hm:what"); - SerdNode* xbadpre = serd_env_expand_node(env, badpre); + SerdNode* xbadpre = serd_env_expand(env, badpre); assert(!xbadpre); + serd_node_free(badpre); - SerdNode* xc = serd_env_expand_node(env, c); - assert(!strcmp(serd_node_get_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); assert(serd_env_set_prefix(env, NULL, NULL)); @@ -446,18 +447,22 @@ main(void) assert(serd_env_set_prefix(env, b, lit)); int n_prefixes = 0; - serd_env_set_prefix_from_strings(env, "eg.2", "http://example.org/"); + serd_env_set_prefix(env, pre, eg); serd_env_foreach(env, count_prefixes, &n_prefixes); assert(n_prefixes == 1); SerdNode* shorter_uri = serd_new_uri("urn:foo"); - const SerdNode* prefix_name; - assert(!serd_env_qualify(env, shorter_uri, &prefix_name, &suffix)); + assert(!serd_env_qualify(env, shorter_uri)); serd_node_free(shorter_uri); - serd_node_free(badpre); - serd_node_free(c); + + SerdNode* qualified = serd_env_qualify(env, foo_u); + assert(serd_node_equals(qualified, foo_c)); + serd_node_free(qualified); + serd_node_free(foo_c); + serd_node_free(foo_u); serd_node_free(b); - serd_node_free(u); + serd_node_free(pre); + serd_node_free(eg); // Test SerdReader and SerdWriter |