aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/serd/env.h10
-rw-r--r--src/env.c47
-rw-r--r--test/test_env.c43
3 files changed, 100 insertions, 0 deletions
diff --git a/include/serd/env.h b/include/serd/env.h
index 2b2982f3..404c96b6 100644
--- a/include/serd/env.h
+++ b/include/serd/env.h
@@ -10,6 +10,8 @@
#include "serd/status.h"
#include "serd/string_view.h"
+#include <stdbool.h>
+
SERD_BEGIN_DECLS
/**
@@ -25,6 +27,14 @@ typedef struct SerdEnvImpl SerdEnv;
SERD_API SerdEnv* SERD_ALLOCATED
serd_env_new(SerdStringView base_uri);
+/// Copy an environment
+SERD_API SerdEnv* SERD_ALLOCATED
+serd_env_copy(const SerdEnv* SERD_NULLABLE env);
+
+/// Return true iff `a` is equal to `b`
+SERD_PURE_API bool
+serd_env_equals(const SerdEnv* SERD_NULLABLE a, const SerdEnv* SERD_NULLABLE b);
+
/// Free `env`
SERD_API void
serd_env_free(SerdEnv* SERD_NULLABLE env);
diff --git a/src/env.c b/src/env.c
index a2096b70..c3f48e48 100644
--- a/src/env.c
+++ b/src/env.c
@@ -37,6 +37,31 @@ serd_env_new(const SerdStringView base_uri)
return env;
}
+SerdEnv*
+serd_env_copy(const SerdEnv* const env)
+{
+ if (!env) {
+ return NULL;
+ }
+
+ SerdEnv* copy = (SerdEnv*)calloc(1, sizeof(struct SerdEnvImpl));
+ if (copy) {
+ copy->n_prefixes = env->n_prefixes;
+ copy->prefixes = (SerdPrefix*)malloc(copy->n_prefixes * sizeof(SerdPrefix));
+ for (size_t i = 0; i < copy->n_prefixes; ++i) {
+ copy->prefixes[i].name = serd_node_copy(env->prefixes[i].name);
+ copy->prefixes[i].uri = serd_node_copy(env->prefixes[i].uri);
+ }
+
+ const SerdNode* const base = serd_env_base_uri(env);
+ if (base) {
+ serd_env_set_base_uri(copy, serd_node_string_view(base));
+ }
+ }
+
+ return copy;
+}
+
void
serd_env_free(SerdEnv* const env)
{
@@ -53,6 +78,28 @@ serd_env_free(SerdEnv* const env)
free(env);
}
+bool
+serd_env_equals(const SerdEnv* const a, const SerdEnv* const b)
+{
+ if (!a || !b) {
+ return !a == !b;
+ }
+
+ if (a->n_prefixes != b->n_prefixes ||
+ !serd_node_equals(a->base_uri_node, b->base_uri_node)) {
+ return false;
+ }
+
+ for (size_t i = 0; i < a->n_prefixes; ++i) {
+ if (!serd_node_equals(a->prefixes[i].name, b->prefixes[i].name) ||
+ !serd_node_equals(a->prefixes[i].uri, b->prefixes[i].uri)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
SerdURIView
serd_env_base_uri_view(const SerdEnv* const env)
{
diff --git a/test/test_env.c b/test/test_env.c
index 4f947246..69b69061 100644
--- a/test/test_env.c
+++ b/test/test_env.c
@@ -13,6 +13,47 @@
#include <assert.h>
#include <string.h>
+static void
+test_copy(void)
+{
+ assert(!serd_env_copy(NULL));
+
+ SerdEnv* const env = serd_env_new(serd_string("http://example.org/base/"));
+
+ serd_env_set_prefix(
+ env, serd_string("eg"), serd_string("http://example.org/"));
+
+ SerdEnv* const env_copy = serd_env_copy(env);
+
+ assert(serd_env_equals(env, env_copy));
+
+ serd_env_set_prefix(
+ env_copy, serd_string("test"), serd_string("http://example.org/test"));
+
+ assert(!serd_env_equals(env, env_copy));
+
+ serd_env_set_prefix(
+ env, serd_string("test2"), serd_string("http://example.org/test2"));
+
+ assert(!serd_env_equals(env, env_copy));
+
+ serd_env_free(env_copy);
+ serd_env_free(env);
+}
+
+static void
+test_comparison(void)
+{
+ SerdEnv* const env = serd_env_new(serd_empty_string());
+
+ assert(!serd_env_equals(env, NULL));
+ assert(!serd_env_equals(NULL, env));
+ assert(serd_env_equals(NULL, NULL));
+ assert(serd_env_equals(env, env));
+
+ serd_env_free(env);
+}
+
static SerdStatus
count_prefixes(void* handle, const SerdEvent* event)
{
@@ -118,6 +159,8 @@ test_env(void)
int
main(void)
{
+ test_copy();
+ test_comparison();
test_env();
return 0;
}