aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--serd/serd.h21
-rw-r--r--src/env.c67
2 files changed, 75 insertions, 13 deletions
diff --git a/serd/serd.h b/serd/serd.h
index b88cb8f8..9eb4dda2 100644
--- a/serd/serd.h
+++ b/serd/serd.h
@@ -718,6 +718,16 @@ serd_env_set_prefix_from_strings(SerdEnv* env,
const uint8_t* uri);
/**
+ Set a term.
+*/
+SERD_API
+SerdStatus
+serd_env_set_term(SerdEnv* env,
+ const SerdNode* name,
+ const SerdNode* uri,
+ const SerdNode* datatype);
+
+/**
Qualify `uri` into a CURIE if possible.
*/
SERD_API
@@ -751,6 +761,17 @@ serd_env_expand_node(const SerdEnv* env,
const SerdNode* node);
/**
+ Expand `node`.
+*/
+SERD_API
+SerdStatus
+serd_env_expand_term(const SerdEnv* env,
+ const SerdNode* term,
+ SerdChunk* uri_prefix,
+ SerdChunk* uri_suffix,
+ const SerdNode** datatype);
+
+/**
Call `func` for each prefix defined in `env`.
*/
SERD_API
diff --git a/src/env.c b/src/env.c
index b26c6b20..f6684393 100644
--- a/src/env.c
+++ b/src/env.c
@@ -1,5 +1,5 @@
/*
- Copyright 2011-2016 David Robillard <http://drobilla.net>
+ Copyright 2011-2017 David Robillard <http://drobilla.net>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -22,6 +22,7 @@
typedef struct {
SerdNode name;
SerdNode uri;
+ SerdNode datatype;
} SerdPrefix;
struct SerdEnvImpl {
@@ -102,10 +103,12 @@ serd_env_find(const SerdEnv* env,
return NULL;
}
-static void
-serd_env_add(SerdEnv* env,
- const SerdNode* name,
- const SerdNode* uri)
+SERD_API
+SerdStatus
+serd_env_set_term(SerdEnv* env,
+ const SerdNode* name,
+ const SerdNode* uri,
+ const SerdNode* datatype)
{
SerdPrefix* const prefix = serd_env_find(env, name->buf, name->n_bytes);
if (prefix) {
@@ -115,21 +118,22 @@ serd_env_add(SerdEnv* env,
} else {
env->prefixes = (SerdPrefix*)realloc(
env->prefixes, (++env->n_prefixes) * sizeof(SerdPrefix));
- env->prefixes[env->n_prefixes - 1].name = serd_node_copy(name);
- env->prefixes[env->n_prefixes - 1].uri = serd_node_copy(uri);
+ env->prefixes[env->n_prefixes - 1].name = serd_node_copy(name);
+ env->prefixes[env->n_prefixes - 1].uri = serd_node_copy(uri);
+ env->prefixes[env->n_prefixes - 1].datatype = serd_node_copy(datatype);
}
+
+ return SERD_SUCCESS;
}
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)
{
if (!name->buf || uri->type != SERD_URI) {
return SERD_ERR_BAD_ARG;
} else if (serd_uri_string_has_scheme(uri->buf)) {
// Set prefix to absolute URI
- serd_env_add(env, name, uri);
+ serd_env_set_term(env, name, uri, NULL);
} else {
// Resolve relative URI and create a new node and URI for it
SerdURI abs_uri;
@@ -137,7 +141,7 @@ serd_env_set_prefix(SerdEnv* env,
uri, &env->base_uri, &abs_uri);
// Set prefix to resolved (absolute) URI
- serd_env_add(env, name, &abs_uri_node);
+ serd_env_set_term(env, name, &abs_uri_node, NULL);
serd_node_free(&abs_uri_node);
}
return SERD_SUCCESS;
@@ -166,7 +170,7 @@ serd_env_qualify(const SerdEnv* env,
if (!strncmp((const char*)uri->buf,
(const char*)prefix_uri->buf,
prefix_uri->n_bytes)) {
- *prefix = env->prefixes[i].name;
+ *prefix = env->prefixes[i].name;
suffix->buf = uri->buf + prefix_uri->n_bytes;
suffix->len = uri->n_bytes - prefix_uri->n_bytes;
return true;
@@ -227,6 +231,43 @@ serd_env_expand_node(const SerdEnv* env,
}
}
+SerdStatus
+serd_env_expand_term(const SerdEnv* env,
+ const SerdNode* term,
+ SerdChunk* uri_prefix,
+ SerdChunk* uri_suffix,
+ const SerdNode** datatype)
+{
+ const uint8_t* const colon =
+ (const uint8_t*)memchr(term->buf, ':', term->n_bytes + 1);
+
+ SerdPrefix* prefix = NULL;
+ if (colon) {
+ const size_t prefix_len = colon - term->buf;
+ if ((prefix = serd_env_find(env, term->buf, prefix_len))) {
+ uri_prefix->buf = prefix->uri.buf;
+ uri_prefix->len = prefix->uri.n_bytes;
+ uri_suffix->buf = colon + 1;
+ uri_suffix->len = term->n_bytes - prefix_len - 1;
+ } else {
+ return SERD_ERR_NOT_FOUND;
+ }
+ } else {
+ if ((prefix = serd_env_find(env, term->buf, term->n_bytes))) {
+ uri_prefix->buf = prefix->uri.buf;
+ uri_prefix->len = prefix->uri.n_bytes;
+ uri_suffix->buf = NULL;
+ uri_suffix->len = 0;
+ }
+ }
+
+ if (prefix->datatype.type) {
+ *datatype = &prefix->datatype;
+ }
+
+ return SERD_FAILURE;
+}
+
void
serd_env_foreach(const SerdEnv* env,
SerdPrefixSink func,