aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-08-12 12:24:57 +0200
committerDavid Robillard <d@drobilla.net>2020-10-27 13:13:59 +0100
commit8c5e9d12ae4d3ef0c3a879f5a485e0040c333e75 (patch)
tree609f9c73f296837db80f9faec8aca501f1a4f249
parent207d78fafb99d26363e6e239c653482694d32510 (diff)
downloadserd-8c5e9d12ae4d3ef0c3a879f5a485e0040c333e75.tar.gz
serd-8c5e9d12ae4d3ef0c3a879f5a485e0040c333e75.tar.bz2
serd-8c5e9d12ae4d3ef0c3a879f5a485e0040c333e75.zip
WIP: expander
-rw-r--r--src/expander.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/expander.c b/src/expander.c
new file mode 100644
index 00000000..4a49f77c
--- /dev/null
+++ b/src/expander.c
@@ -0,0 +1,91 @@
+/*
+ Copyright 2019-2020 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
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include "sink.h"
+#include "statement.h"
+
+#include "serd/serd.h"
+
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <stdio.h>
+
+typedef struct
+{
+ const SerdSink* target;
+} SerdExpanderData;
+
+static SerdStatus
+serd_expander_on_event(void* handle, const SerdEvent* event)
+{
+ const SerdExpanderData* const data = (SerdExpanderData*)handle;
+
+ if (event->type != SERD_STATEMENT) {
+ return serd_sink_write_event(data->target, event);
+ }
+
+ const SerdEnv* const env = serd_sink_get_env(data->target);
+ const SerdStatement* const statement = event->statement.statement;
+
+ SerdNode* xs = serd_env_expand(env, serd_statement_get_subject(statement));
+ SerdNode* xp = serd_env_expand(env, serd_statement_get_predicate(statement));
+ SerdNode* xo = serd_env_expand(env, serd_statement_get_object(statement));
+ SerdNode* xg = serd_env_expand(env, serd_statement_get_graph(statement));
+
+ const SerdNode* const s = xs ? xs : serd_statement_get_subject(statement);
+ const SerdNode* const p = xp ? xp : serd_statement_get_predicate(statement);
+ const SerdNode* const o = xo ? xo : serd_statement_get_object(statement);
+ const SerdNode* const g = xg ? xg : serd_statement_get_graph(statement);
+ /* if (!xs || !p || !o || !g) { */
+ /* fprintf(stderr, "invalid\n"); */
+ /* return SERD_ERR_INVALID; */
+ /* } */
+
+ const SerdStatement expanded = {{s, p, o, g}, statement->cursor};
+ SerdEvent expanded_event = {SERD_STATEMENT};
+
+ expanded_event.statement.flags = event->statement.flags;
+ expanded_event.statement.statement = &expanded;
+
+ SerdStatus st = serd_sink_write_event(data->target, &expanded_event);
+
+ serd_node_free(xg);
+ serd_node_free(xo);
+ serd_node_free(xp);
+ serd_node_free(xs);
+
+ return st;
+}
+
+SerdSink*
+serd_expander_new(const SerdSink* const target)
+{
+ if (!serd_sink_get_env(target)) {
+ return NULL;
+ }
+
+ SerdExpanderData* data =
+ (SerdExpanderData*)calloc(1, sizeof(SerdExpanderData));
+
+ data->target = target;
+
+ SerdSink* const sink = serd_sink_new(data, free);
+
+ serd_sink_set_event_func(sink, serd_expander_on_event);
+
+ return sink;
+}