aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-02-20 19:18:28 -0500
committerDavid Robillard <d@drobilla.net>2023-12-02 18:49:07 -0500
commitd62c7dc45af3256c6cd70d12a11e91b5b872c7db (patch)
tree63f9f1cc8f8900ad59b5bd8f07b70e6008522d21 /src
parentab1aa43256fac3e017212abe6f9d845bf74c024c (diff)
downloadserd-d62c7dc45af3256c6cd70d12a11e91b5b872c7db.tar.gz
serd-d62c7dc45af3256c6cd70d12a11e91b5b872c7db.tar.bz2
serd-d62c7dc45af3256c6cd70d12a11e91b5b872c7db.zip
Replace multiple stream callbacks with SerdEvent
This makes plumbing easier since everything goes through the same "stream" and only one callback is required to handling everything. It's also more easily extensible in case more event types need to be added in the future.
Diffstat (limited to 'src')
-rw-r--r--src/env.c16
-rw-r--r--src/sink.c53
-rw-r--r--src/sink.h10
-rw-r--r--src/string.c2
-rw-r--r--src/writer.c40
5 files changed, 69 insertions, 52 deletions
diff --git a/src/env.c b/src/env.c
index 8b3970b3..4ce0add4 100644
--- a/src/env.c
+++ b/src/env.c
@@ -238,12 +238,16 @@ serd_env_expand_node(const SerdEnv* const env, const SerdNode* const node)
return NULL;
}
-void
-serd_env_foreach(const SerdEnv* const env,
- const SerdPrefixFunc func,
- void* const handle)
+SerdStatus
+serd_env_write_prefixes(const SerdEnv* const env, const SerdSink* const sink)
{
- for (size_t i = 0; i < env->n_prefixes; ++i) {
- func(handle, env->prefixes[i].name, env->prefixes[i].uri);
+ SerdStatus st = SERD_SUCCESS;
+
+ for (size_t i = 0; !st && i < env->n_prefixes; ++i) {
+ const SerdPrefix* const prefix = &env->prefixes[i];
+
+ st = serd_sink_write_prefix(sink, prefix->name, prefix->uri);
}
+
+ return st;
}
diff --git a/src/sink.c b/src/sink.c
index 51b23ea5..8343a62a 100644
--- a/src/sink.c
+++ b/src/sink.c
@@ -14,11 +14,14 @@
#include <stdlib.h>
SerdSink*
-serd_sink_new(void* handle, SerdFreeFunc free_handle)
+serd_sink_new(void* const handle,
+ SerdEventFunc event_func,
+ SerdFreeFunc free_handle)
{
SerdSink* sink = (SerdSink*)calloc(1, sizeof(SerdSink));
sink->handle = handle;
+ sink->on_event = event_func;
sink->free_handle = free_handle;
return sink;
@@ -37,37 +40,18 @@ serd_sink_free(SerdSink* sink)
}
SerdStatus
-serd_sink_set_base_func(SerdSink* sink, SerdBaseFunc base_func)
+serd_sink_write_event(const SerdSink* sink, const SerdEvent* event)
{
- sink->base = base_func;
- return SERD_SUCCESS;
-}
-
-SerdStatus
-serd_sink_set_prefix_func(SerdSink* sink, SerdPrefixFunc prefix_func)
-{
- sink->prefix = prefix_func;
- return SERD_SUCCESS;
-}
-
-SerdStatus
-serd_sink_set_statement_func(SerdSink* sink, SerdStatementFunc statement_func)
-{
- sink->statement = statement_func;
- return SERD_SUCCESS;
-}
-
-SerdStatus
-serd_sink_set_end_func(SerdSink* sink, SerdEndFunc end_func)
-{
- sink->end = end_func;
- return SERD_SUCCESS;
+ return sink->on_event ? sink->on_event(sink->handle, event) : SERD_SUCCESS;
}
SerdStatus
serd_sink_write_base(const SerdSink* sink, const SerdNode* uri)
{
- return sink->base ? sink->base(sink->handle, uri) : SERD_SUCCESS;
+ const SerdBaseEvent ev = {SERD_BASE, uri};
+
+ return sink->on_event ? sink->on_event(sink->handle, (const SerdEvent*)&ev)
+ : SERD_SUCCESS;
}
SerdStatus
@@ -75,7 +59,10 @@ serd_sink_write_prefix(const SerdSink* sink,
const SerdNode* name,
const SerdNode* uri)
{
- return sink->prefix ? sink->prefix(sink->handle, name, uri) : SERD_SUCCESS;
+ const SerdPrefixEvent ev = {SERD_PREFIX, name, uri};
+
+ return sink->on_event ? sink->on_event(sink->handle, (const SerdEvent*)&ev)
+ : SERD_SUCCESS;
}
SerdStatus
@@ -83,8 +70,11 @@ serd_sink_write_statement(const SerdSink* sink,
const SerdStatementFlags flags,
const SerdStatement* statement)
{
- return sink->statement ? sink->statement(sink->handle, flags, statement)
- : SERD_SUCCESS;
+ const SerdStatementEvent statement_ev = {SERD_STATEMENT, flags, statement};
+ SerdEvent ev = {SERD_STATEMENT};
+ ev.statement = statement_ev;
+
+ return sink->on_event ? sink->on_event(sink->handle, &ev) : SERD_SUCCESS;
}
SerdStatus
@@ -107,5 +97,8 @@ serd_sink_write(const SerdSink* sink,
SerdStatus
serd_sink_write_end(const SerdSink* sink, const SerdNode* node)
{
- return sink->end ? sink->end(sink->handle, node) : SERD_SUCCESS;
+ const SerdEndEvent ev = {SERD_END, node};
+
+ return sink->on_event ? sink->on_event(sink->handle, (const SerdEvent*)&ev)
+ : SERD_SUCCESS;
}
diff --git a/src/sink.h b/src/sink.h
index 98884fe2..097e0d6d 100644
--- a/src/sink.h
+++ b/src/sink.h
@@ -4,18 +4,16 @@
#ifndef SERD_SRC_SINK_H
#define SERD_SRC_SINK_H
+#include "serd/event.h"
#include "serd/sink.h"
/**
An interface that receives a stream of RDF data.
*/
struct SerdSinkImpl {
- void* handle;
- SerdFreeFunc free_handle;
- SerdBaseFunc base;
- SerdPrefixFunc prefix;
- SerdStatementFunc statement;
- SerdEndFunc end;
+ void* handle;
+ SerdFreeFunc free_handle;
+ SerdEventFunc on_event;
};
#endif // SERD_SRC_SINK_H
diff --git a/src/string.c b/src/string.c
index e13c0c01..8cc839bd 100644
--- a/src/string.c
+++ b/src/string.c
@@ -56,6 +56,8 @@ serd_strerror(const SerdStatus status)
return "Invalid text encoding";
case SERD_BAD_CALL:
return "Invalid call";
+ case SERD_BAD_EVENT:
+ return "Invalid event in stream";
case SERD_BAD_URI:
return "Invalid or unresolved URI";
case SERD_BAD_DATA:
diff --git a/src/writer.c b/src/writer.c
index 37263010..ca17bbd9 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -16,6 +16,7 @@
#include "serd/attributes.h"
#include "serd/buffer.h"
#include "serd/env.h"
+#include "serd/event.h"
#include "serd/node.h"
#include "serd/sink.h"
#include "serd/statement.h"
@@ -139,6 +140,9 @@ typedef enum { WRITE_STRING, WRITE_LONG_STRING } TextContext;
typedef enum { RESET_GRAPH = 1U << 0U, RESET_INDENT = 1U << 1U } ResetFlag;
SERD_NODISCARD static SerdStatus
+serd_writer_set_base_uri(SerdWriter* writer, const SerdNode* uri);
+
+SERD_NODISCARD static SerdStatus
serd_writer_set_prefix(SerdWriter* writer,
const SerdNode* name,
const SerdNode* uri);
@@ -945,7 +949,7 @@ write_list_next(SerdWriter* const writer,
return st;
}
-static SerdStatus
+SERD_NODISCARD static SerdStatus
terminate_context(SerdWriter* writer)
{
SerdStatus st = SERD_SUCCESS;
@@ -961,7 +965,7 @@ terminate_context(SerdWriter* writer)
return st;
}
-static SerdStatus
+SERD_NODISCARD static SerdStatus
serd_writer_write_statement(SerdWriter* const writer,
const SerdStatementFlags flags,
const SerdStatement* const statement)
@@ -1103,7 +1107,7 @@ serd_writer_write_statement(SerdWriter* const writer,
return st;
}
-static SerdStatus
+SERD_NODISCARD static SerdStatus
serd_writer_end_anon(SerdWriter* writer, const SerdNode* node)
{
SerdStatus st = SERD_SUCCESS;
@@ -1113,7 +1117,7 @@ serd_writer_end_anon(SerdWriter* writer, const SerdNode* node)
}
if (serd_stack_is_empty(&writer->anon_stack)) {
- return w_err(writer, SERD_BAD_CALL, "unexpected end of anonymous node\n");
+ return w_err(writer, SERD_BAD_EVENT, "unexpected end of anonymous node\n");
}
// Write the end separator ']' and pop the context
@@ -1129,6 +1133,25 @@ serd_writer_end_anon(SerdWriter* writer, const SerdNode* node)
return st;
}
+SERD_NODISCARD static SerdStatus
+serd_writer_on_event(SerdWriter* writer, const SerdEvent* event)
+{
+ switch (event->type) {
+ case SERD_BASE:
+ return serd_writer_set_base_uri(writer, event->base.uri);
+ case SERD_PREFIX:
+ return serd_writer_set_prefix(
+ writer, event->prefix.name, event->prefix.uri);
+ case SERD_STATEMENT:
+ return serd_writer_write_statement(
+ writer, event->statement.flags, event->statement.statement);
+ case SERD_END:
+ return serd_writer_end_anon(writer, event->end.node);
+ }
+
+ return SERD_BAD_ARG;
+}
+
SerdStatus
serd_writer_finish(SerdWriter* writer)
{
@@ -1161,11 +1184,8 @@ serd_writer_new(SerdWorld* world,
writer->byte_sink = serd_byte_sink_new(
ssink, stream, (flags & SERD_WRITE_BULK) ? SERD_PAGE_SIZE : 1);
- writer->iface.handle = writer;
- writer->iface.base = (SerdBaseFunc)serd_writer_set_base_uri;
- writer->iface.prefix = (SerdPrefixFunc)serd_writer_set_prefix;
- writer->iface.statement = (SerdStatementFunc)serd_writer_write_statement;
- writer->iface.end = (SerdEndFunc)serd_writer_end_anon;
+ writer->iface.handle = writer;
+ writer->iface.on_event = (SerdEventFunc)serd_writer_on_event;
return writer;
}
@@ -1185,7 +1205,7 @@ serd_writer_chop_blank_prefix(SerdWriter* writer, const char* prefix)
}
}
-SerdStatus
+SERD_NODISCARD static SerdStatus
serd_writer_set_base_uri(SerdWriter* writer, const SerdNode* uri)
{
if (uri && serd_node_type(uri) != SERD_URI) {