aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-03-01 19:38:01 -0500
committerDavid Robillard <d@drobilla.net>2023-12-02 16:27:02 -0500
commitc2e59da8865a8c5719b8ddaf5f68204729a8ebab (patch)
tree4a8c2eb24c4a274eac41a226df6679a6319b6ac4 /src
parentb631e7a3d6a807aaf4919396b62ba96e1a9f0bd9 (diff)
downloadserd-c2e59da8865a8c5719b8ddaf5f68204729a8ebab.tar.gz
serd-c2e59da8865a8c5719b8ddaf5f68204729a8ebab.tar.bz2
serd-c2e59da8865a8c5719b8ddaf5f68204729a8ebab.zip
Add SerdSink interface and hide implementations
Diffstat (limited to 'src')
-rw-r--r--src/n3.c16
-rw-r--r--src/reader.c51
-rw-r--r--src/reader.h37
-rw-r--r--src/serdi.c9
-rw-r--r--src/sink.c102
-rw-r--r--src/sink.h21
-rw-r--r--src/writer.c24
7 files changed, 179 insertions, 81 deletions
diff --git a/src/n3.c b/src/n3.c
index 929b1a97..cd7e5a03 100644
--- a/src/n3.c
+++ b/src/n3.c
@@ -11,6 +11,7 @@
#include "serd/node.h"
#include "serd/reader.h"
+#include "serd/sink.h"
#include "serd/statement.h"
#include "serd/status.h"
#include "serd/syntax.h"
@@ -1099,9 +1100,7 @@ read_anon(SerdReader* const reader,
return r_err(reader, SERD_BAD_SYNTAX, "'.' inside blank\n");
}
read_ws_star(reader);
- if (reader->end_func) {
- reader->end_func(reader->handle, deref(reader, *dest));
- }
+ serd_sink_write_end(reader->sink, deref(reader, *dest));
*ctx.flags = old_flags;
}
@@ -1453,9 +1452,7 @@ read_base(SerdReader* const reader, const bool sparql, const bool token)
Ref uri = 0;
TRY(st, read_IRIREF(reader, &uri));
- if (reader->base_func) {
- TRY(st, reader->base_func(reader->handle, deref(reader, uri)));
- }
+ TRY(st, serd_sink_write_base(reader->sink, deref(reader, uri)));
pop_node(reader, uri);
read_ws_star(reader);
@@ -1491,10 +1488,8 @@ read_prefixID(SerdReader* const reader, const bool sparql, const bool token)
Ref uri = 0;
TRY(st, read_IRIREF(reader, &uri));
- if (reader->prefix_func) {
- st = reader->prefix_func(
- reader->handle, deref(reader, name), deref(reader, uri));
- }
+ st = serd_sink_write_prefix(
+ reader->sink, deref(reader, name), deref(reader, uri));
pop_node(reader, uri);
pop_node(reader, name);
@@ -1502,7 +1497,6 @@ read_prefixID(SerdReader* const reader, const bool sparql, const bool token)
read_ws_star(reader);
st = eat_byte_check(reader, '.') ? SERD_SUCCESS : SERD_BAD_SYNTAX;
}
-
return st;
}
diff --git a/src/reader.c b/src/reader.c
index c7919ca6..284de45d 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -143,14 +143,12 @@ emit_statement(SerdReader* const reader, const ReadContext ctx, const Ref o)
graph = reader->default_graph;
}
- const SerdStatus st = !reader->statement_func
- ? SERD_SUCCESS
- : reader->statement_func(reader->handle,
- *ctx.flags,
- graph,
- deref(reader, ctx.subject),
- deref(reader, ctx.predicate),
- deref(reader, o));
+ const SerdStatus st = serd_sink_write(reader->sink,
+ *ctx.flags,
+ deref(reader, ctx.subject),
+ deref(reader, ctx.predicate),
+ deref(reader, o),
+ graph);
*ctx.flags &= SERD_ANON_CONT | SERD_LIST_CONT; // Preserve only cont flags
return st;
@@ -164,26 +162,16 @@ read_doc(SerdReader* const reader)
}
SerdReader*
-serd_reader_new(const SerdSyntax syntax,
- void* const handle,
- void (*const free_handle)(void*),
- const SerdBaseFunc base_func,
- const SerdPrefixFunc prefix_func,
- const SerdStatementFunc statement_func,
- const SerdEndFunc end_func)
+serd_reader_new(const SerdSyntax syntax, const SerdSink* const sink)
{
- SerdReader* me = (SerdReader*)calloc(1, sizeof(SerdReader));
- me->handle = handle;
- me->free_handle = free_handle;
- me->base_func = base_func;
- me->prefix_func = prefix_func;
- me->statement_func = statement_func;
- me->end_func = end_func;
- me->default_graph = NULL;
- me->stack = serd_stack_new(SERD_PAGE_SIZE);
- me->syntax = syntax;
- me->next_id = 1;
- me->strict = true;
+ SerdReader* me = (SerdReader*)calloc(1, sizeof(SerdReader));
+
+ me->sink = sink;
+ me->default_graph = NULL;
+ me->stack = serd_stack_new(SERD_PAGE_SIZE);
+ me->syntax = syntax;
+ me->next_id = 1;
+ me->strict = true;
me->rdf_first = push_node(me, SERD_URI, NS_RDF "first", 48);
me->rdf_rest = push_node(me, SERD_URI, NS_RDF "rest", 47);
@@ -224,18 +212,9 @@ serd_reader_free(SerdReader* const reader)
#endif
free(reader->stack.buf);
free(reader->bprefix);
- if (reader->free_handle) {
- reader->free_handle(reader->handle);
- }
free(reader);
}
-void*
-serd_reader_handle(const SerdReader* const reader)
-{
- return reader->handle;
-}
-
void
serd_reader_add_blank_prefix(SerdReader* const reader, const char* const prefix)
{
diff --git a/src/reader.h b/src/reader.h
index 0de1df2a..db749fe8 100644
--- a/src/reader.h
+++ b/src/reader.h
@@ -45,27 +45,22 @@ typedef struct {
} ReadContext;
struct SerdReaderImpl {
- void* handle;
- void (*free_handle)(void* ptr);
- SerdBaseFunc base_func;
- SerdPrefixFunc prefix_func;
- SerdStatementFunc statement_func;
- SerdEndFunc end_func;
- SerdErrorFunc error_func;
- void* error_handle;
- Ref rdf_first;
- Ref rdf_rest;
- Ref rdf_nil;
- SerdNode* default_graph;
- SerdByteSource source;
- SerdStack stack;
- SerdSyntax syntax;
- unsigned next_id;
- uint8_t* buf;
- char* bprefix;
- size_t bprefix_len;
- bool strict; ///< True iff strict parsing
- bool seen_genid;
+ const SerdSink* sink;
+ SerdErrorFunc error_func;
+ void* error_handle;
+ Ref rdf_first;
+ Ref rdf_rest;
+ Ref rdf_nil;
+ SerdNode* default_graph;
+ SerdByteSource source;
+ SerdStack stack;
+ SerdSyntax syntax;
+ unsigned next_id;
+ uint8_t* buf;
+ char* bprefix;
+ size_t bprefix_len;
+ bool strict; ///< True iff strict parsing
+ bool seen_genid;
#ifdef SERD_STACK_CHECK
Ref* allocs; ///< Stack of push offsets
size_t n_allocs; ///< Number of stack pushes
diff --git a/src/serdi.c b/src/serdi.c
index e3b41204..0de64b81 100644
--- a/src/serdi.c
+++ b/src/serdi.c
@@ -9,7 +9,6 @@
#include "serd/error.h"
#include "serd/node.h"
#include "serd/reader.h"
-#include "serd/sink.h"
#include "serd/status.h"
#include "serd/stream.h"
#include "serd/string_view.h"
@@ -348,13 +347,7 @@ main(int argc, char** argv)
output_syntax, writer_flags, env, (SerdWriteFunc)fwrite, out_fd);
SerdReader* const reader =
- serd_reader_new(input_syntax,
- writer,
- NULL,
- (SerdBaseFunc)serd_writer_set_base_uri,
- (SerdPrefixFunc)serd_writer_set_prefix,
- (SerdStatementFunc)serd_writer_write_statement,
- (SerdEndFunc)serd_writer_end_anon);
+ serd_reader_new(input_syntax, serd_writer_sink(writer));
serd_reader_set_strict(reader, !lax);
if (quiet) {
diff --git a/src/sink.c b/src/sink.c
new file mode 100644
index 00000000..5e04ced6
--- /dev/null
+++ b/src/sink.c
@@ -0,0 +1,102 @@
+// Copyright 2011-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#include "sink.h"
+
+#include "serd/node.h"
+#include "serd/sink.h"
+#include "serd/statement.h"
+#include "serd/status.h"
+
+#include <assert.h>
+#include <stdlib.h>
+
+SerdSink*
+serd_sink_new(void* handle, SerdFreeFunc free_handle)
+{
+ SerdSink* sink = (SerdSink*)calloc(1, sizeof(SerdSink));
+
+ sink->handle = handle;
+ sink->free_handle = free_handle;
+
+ return sink;
+}
+
+void
+serd_sink_free(SerdSink* sink)
+{
+ if (sink) {
+ if (sink->free_handle) {
+ sink->free_handle(sink->handle);
+ }
+
+ free(sink);
+ }
+}
+
+SerdStatus
+serd_sink_set_base_func(SerdSink* sink, SerdBaseFunc base_func)
+{
+ 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;
+}
+
+SerdStatus
+serd_sink_write_base(const SerdSink* sink, const SerdNode* uri)
+{
+ return sink->base ? sink->base(sink->handle, uri) : SERD_SUCCESS;
+}
+
+SerdStatus
+serd_sink_write_prefix(const SerdSink* sink,
+ const SerdNode* name,
+ const SerdNode* uri)
+{
+ return sink->prefix ? sink->prefix(sink->handle, name, uri) : SERD_SUCCESS;
+}
+
+SerdStatus
+serd_sink_write(const SerdSink* sink,
+ const SerdStatementFlags flags,
+ const SerdNode* subject,
+ const SerdNode* predicate,
+ const SerdNode* object,
+ const SerdNode* graph)
+{
+ assert(sink);
+ assert(subject);
+ assert(predicate);
+ assert(object);
+
+ return sink->statement
+ ? sink->statement(
+ sink->handle, flags, graph, subject, predicate, object)
+ : SERD_SUCCESS;
+}
+
+SerdStatus
+serd_sink_write_end(const SerdSink* sink, const SerdNode* node)
+{
+ return sink->end ? sink->end(sink->handle, node) : SERD_SUCCESS;
+}
diff --git a/src/sink.h b/src/sink.h
new file mode 100644
index 00000000..98884fe2
--- /dev/null
+++ b/src/sink.h
@@ -0,0 +1,21 @@
+// Copyright 2011-2020 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#ifndef SERD_SRC_SINK_H
+#define SERD_SRC_SINK_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;
+};
+
+#endif // SERD_SRC_SINK_H
diff --git a/src/writer.c b/src/writer.c
index 01beb315..e674f2b1 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -5,6 +5,7 @@
#include "env.h"
#include "node.h"
#include "serd_internal.h"
+#include "sink.h"
#include "stack.h"
#include "string_utils.h"
#include "try.h"
@@ -15,6 +16,7 @@
#include "serd/env.h"
#include "serd/error.h"
#include "serd/node.h"
+#include "serd/sink.h"
#include "serd/statement.h"
#include "serd/status.h"
#include "serd/stream.h"
@@ -123,6 +125,7 @@ static const SepRule rules[] = {
#undef SEP_EACH
struct SerdWriterImpl {
+ SerdSink iface;
SerdSyntax syntax;
SerdWriterFlags flags;
SerdEnv* env;
@@ -143,6 +146,11 @@ 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_prefix(SerdWriter* writer,
+ const SerdNode* name,
+ const SerdNode* uri);
+
+SERD_NODISCARD static SerdStatus
write_node(SerdWriter* writer,
const SerdNode* node,
Field field,
@@ -951,7 +959,7 @@ terminate_context(SerdWriter* writer)
return st;
}
-SerdStatus
+static SerdStatus
serd_writer_write_statement(SerdWriter* const writer,
const SerdStatementFlags flags,
const SerdNode* const graph,
@@ -1090,7 +1098,7 @@ serd_writer_write_statement(SerdWriter* const writer,
return st;
}
-SerdStatus
+static SerdStatus
serd_writer_end_anon(SerdWriter* writer, const SerdNode* node)
{
SerdStatus st = SERD_SUCCESS;
@@ -1146,6 +1154,12 @@ serd_writer_new(SerdSyntax syntax,
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;
+
return writer;
}
@@ -1259,10 +1273,10 @@ serd_writer_free(SerdWriter* writer)
free(writer);
}
-SerdEnv*
-serd_writer_env(SerdWriter* writer)
+const SerdSink*
+serd_writer_sink(SerdWriter* writer)
{
- return writer->env;
+ return &writer->iface;
}
size_t