aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-12-29 17:36:15 -0500
committerDavid Robillard <d@drobilla.net>2019-04-13 19:15:32 +0200
commit2b775031fc4d239cbece7f0911f4be9e50e690d7 (patch)
tree0a58b292c1bae93b40e4e912450aa883d7bd2190
parentd6060f62d7dd3c9906fb4c58a75874f57d846162 (diff)
downloadserd-2b775031fc4d239cbece7f0911f4be9e50e690d7.tar.gz
serd-2b775031fc4d239cbece7f0911f4be9e50e690d7.tar.bz2
serd-2b775031fc4d239cbece7f0911f4be9e50e690d7.zip
Add Env to Sink
This isn't technically necessary for any sink, but is a pattern common to every sink implementation in serd, so having it here reduces boilerplate and parameters in user code.
-rw-r--r--serd/serd.h10
-rw-r--r--src/n3.c20
-rw-r--r--src/reader.c9
-rw-r--r--src/sink.c20
-rw-r--r--src/sink.h1
-rw-r--r--src/writer.c61
-rw-r--r--tests/overflow_test.c2
-rw-r--r--tests/read_chunk_test.c2
-rw-r--r--tests/serd_test.c5
9 files changed, 71 insertions, 59 deletions
diff --git a/serd/serd.h b/serd/serd.h
index 6cb853ce..6f9360cc 100644
--- a/serd/serd.h
+++ b/serd/serd.h
@@ -1066,10 +1066,11 @@ serd_env_write_prefixes(const SerdEnv* env, const SerdSink* sink);
serd_sink_set_*_func functions to set handlers for various events.
@param handle Opaque handle that will be passed to sink functions.
+ @param env Environment for sink, updated as base uri or prefixes change.
*/
SERD_API
SerdSink*
-serd_sink_new(void* handle);
+serd_sink_new(void* handle, SerdEnv* env);
/**
Free `sink`.
@@ -1079,6 +1080,13 @@ void
serd_sink_free(SerdSink* sink);
/**
+ Return the env used by `writer`.
+*/
+SERD_API
+const SerdEnv*
+serd_sink_get_env(const SerdSink* sink);
+
+/**
Set a function to be called when the base URI changes.
*/
SERD_API
diff --git a/src/n3.c b/src/n3.c
index e108084d..857e4d1c 100644
--- a/src/n3.c
+++ b/src/n3.c
@@ -18,7 +18,6 @@
#include "node.h"
#include "reader.h"
#include "serd_internal.h"
-#include "sink.h"
#include "stack.h"
#include "string_utils.h"
#include "uri_utils.h"
@@ -958,8 +957,8 @@ read_anon(SerdReader* reader, ReadContext ctx, bool subject, SerdNode** dest)
*ctx.flags = old_flags;
}
- if (reader->sink->end && (!subject || !empty)) {
- reader->sink->end(reader->sink->handle, *dest);
+ if (!subject || !empty) {
+ serd_sink_write_end(reader->sink, *dest);
}
return (eat_byte_check(reader, ']') == ']') ? SERD_SUCCESS
@@ -1262,10 +1261,8 @@ read_base(SerdReader* reader, bool sparql, bool token)
read_ws_star(reader);
SerdNode* uri = NULL;
TRY(st, read_IRIREF(reader, &uri));
- if (reader->sink->base) {
- serd_node_zero_pad(uri);
- reader->sink->base(reader->sink->handle, uri);
- }
+ serd_node_zero_pad(uri);
+ serd_sink_write_base(reader->sink, uri);
read_ws_star(reader);
if (!sparql) {
@@ -1301,11 +1298,10 @@ read_prefixID(SerdReader* reader, bool sparql, bool token)
SerdNode* uri = NULL;
TRY(st, read_IRIREF(reader, &uri));
- if (reader->sink->prefix) {
- serd_node_zero_pad(name);
- serd_node_zero_pad(uri);
- st = reader->sink->prefix(reader->sink->handle, name, uri);
- }
+ serd_node_zero_pad(name);
+ serd_node_zero_pad(uri);
+ st = serd_sink_write_prefix(reader->sink, name, uri);
+
if (!sparql) {
read_ws_star(reader);
st = eat_byte_check(reader, '.') ? SERD_SUCCESS : SERD_ERR_BAD_SYNTAX;
diff --git a/src/reader.c b/src/reader.c
index ab6b3611..4235168a 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -20,7 +20,6 @@
#include "node.h"
#include "serd/serd.h"
#include "serd_internal.h"
-#include "sink.h"
#include "stack.h"
#include "statement.h"
#include "system.h"
@@ -121,9 +120,6 @@ SerdStatus
emit_statement(SerdReader* reader, ReadContext ctx, SerdNode* o)
{
SerdNode* graph = ctx.graph;
- if (!reader->sink->statement) {
- return SERD_SUCCESS;
- }
/* Zero the pad of the object node on the top of the stack. Lower nodes
(subject and predicate) were already zeroed by subsequent pushes. */
@@ -134,8 +130,9 @@ emit_statement(SerdReader* reader, ReadContext ctx, SerdNode* o)
&reader->source.cur
};
- const SerdStatus st = reader->sink->statement(
- reader->sink->handle, *ctx.flags, &statement);
+ const SerdStatus st = serd_sink_write_statement(
+ reader->sink, *ctx.flags, &statement);
+
*ctx.flags = 0;
return st;
}
diff --git a/src/sink.c b/src/sink.c
index d14ad8f1..1b693e88 100644
--- a/src/sink.c
+++ b/src/sink.c
@@ -23,11 +23,13 @@
#include <stdlib.h>
SerdSink*
-serd_sink_new(void* handle)
+serd_sink_new(void* handle, SerdEnv* env)
{
SerdSink* sink = (SerdSink*)calloc(1, sizeof(SerdSink));
sink->handle = handle;
+ sink->env = env;
+
return sink;
}
@@ -37,6 +39,12 @@ serd_sink_free(SerdSink* sink)
free(sink);
}
+const SerdEnv*
+serd_sink_get_env(const SerdSink* sink)
+{
+ return sink->env;
+}
+
SerdStatus
serd_sink_set_base_func(SerdSink* sink, SerdBaseSink base_func)
{
@@ -68,7 +76,10 @@ serd_sink_set_end_func(SerdSink* sink, SerdEndSink end_func)
SerdStatus
serd_sink_write_base(const SerdSink* sink, const SerdNode* uri)
{
- return sink->base ? sink->base(sink->handle, uri) : SERD_SUCCESS;
+ const SerdStatus st = (sink->env ? serd_env_set_base_uri(sink->env, uri)
+ : SERD_SUCCESS);
+
+ return (!st && sink->base) ? sink->base(sink->handle, uri) : st;
}
SerdStatus
@@ -76,7 +87,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 SerdStatus st = (sink->env ? serd_env_set_prefix(sink->env, name, uri)
+ : SERD_SUCCESS);
+
+ return (!st && sink->prefix) ? sink->prefix(sink->handle, name, uri) : st;
}
SerdStatus
diff --git a/src/sink.h b/src/sink.h
index 03523370..bab46ef6 100644
--- a/src/sink.h
+++ b/src/sink.h
@@ -24,6 +24,7 @@
*/
struct SerdSinkImpl {
void* handle;
+ SerdEnv* env;
SerdBaseSink base;
SerdPrefixSink prefix;
SerdStatementSink statement;
diff --git a/src/writer.c b/src/writer.c
index 72ecc4ed..953de1fb 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -105,7 +105,6 @@ struct SerdWriterImpl {
SerdSink iface;
SerdSyntax syntax;
SerdWriterFlags flags;
- SerdEnv* env;
SerdNode* root_node;
SerdURI root_uri;
SerdStack anon_stack;
@@ -520,6 +519,8 @@ write_uri_node(SerdWriter* const writer,
const SerdField field,
const SerdStatementFlags flags)
{
+ SerdEnv* const env = writer->iface.env;
+
writer->last_sep = SEP_NONE;
if (is_inline_start(writer, field, flags)) {
write_sep(writer, SEP_ANON_BEGIN);
@@ -537,7 +538,7 @@ write_uri_node(SerdWriter* const writer,
serd_node_equals(node, writer->world->rdf_nil)) {
return sink("()", 2, writer) == 2;
} else if (has_scheme && supports_abbrev(writer) &&
- serd_env_qualify_in_place(writer->env, node, &prefix, &suffix) &&
+ serd_env_qualify_in_place(env, node, &prefix, &suffix) &&
is_name(serd_node_get_string(prefix), serd_node_get_length(prefix)) &&
is_name(suffix.buf, suffix.len)) {
write_uri_from_node(writer, prefix);
@@ -547,8 +548,8 @@ write_uri_node(SerdWriter* const writer,
}
sink("<", 1, writer);
- if (serd_env_get_base_uri(writer->env)) {
- const SerdURI* base_uri = serd_env_get_parsed_base_uri(writer->env);
+ if (serd_env_get_base_uri(env)) {
+ const SerdURI* base_uri = serd_env_get_parsed_base_uri(env);
SerdURI uri, abs_uri;
serd_uri_parse(node_str, &uri);
serd_uri_resolve(&uri, base_uri, &abs_uri);
@@ -587,7 +588,7 @@ write_curie(SerdWriter* const writer,
case SERD_NTRIPLES:
case SERD_NQUADS:
if ((st = serd_env_expand_in_place(
- writer->env, node, &prefix, &suffix))) {
+ writer->iface.env, node, &prefix, &suffix))) {
serd_world_errorf(writer->world,
st,
"undefined namespace prefix `%s'\n",
@@ -910,7 +911,6 @@ serd_writer_new(SerdWorld* world,
writer->world = world;
writer->syntax = syntax;
writer->flags = flags;
- writer->env = env;
writer->root_node = NULL;
writer->root_uri = SERD_URI_NULL;
writer->anon_stack = serd_stack_new(SERD_PAGE_SIZE);
@@ -920,6 +920,7 @@ serd_writer_new(SerdWorld* world,
writer->empty = true;
writer->iface.handle = writer;
+ writer->iface.env = env;
writer->iface.base = (SerdBaseSink)serd_writer_set_base_uri;
writer->iface.prefix = (SerdPrefixSink)serd_writer_set_prefix;
writer->iface.statement = (SerdStatementSink)serd_writer_write_statement;
@@ -946,20 +947,17 @@ SerdStatus
serd_writer_set_base_uri(SerdWriter* writer,
const SerdNode* uri)
{
- if (!serd_env_set_base_uri(writer->env, uri)) {
- if (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG) {
- if (ctx(writer, SERD_GRAPH) || ctx(writer, SERD_SUBJECT)) {
- sink(" .\n\n", 4, writer);
- reset_context(writer, true);
- }
- sink("@base <", 7, writer);
- sink(serd_node_get_string(uri), uri->n_bytes, writer);
- sink("> .\n", 4, writer);
+ if (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG) {
+ if (ctx(writer, SERD_GRAPH) || ctx(writer, SERD_SUBJECT)) {
+ sink(" .\n\n", 4, writer);
+ reset_context(writer, true);
}
- writer->indent = 0;
- return reset_context(writer, true);
+ sink("@base <", 7, writer);
+ sink(serd_node_get_string(uri), uri->n_bytes, writer);
+ sink("> .\n", 4, writer);
}
- return SERD_ERR_UNKNOWN;
+ writer->indent = 0;
+ return reset_context(writer, true);
}
SerdStatus
@@ -983,22 +981,19 @@ serd_writer_set_prefix(SerdWriter* writer,
const SerdNode* name,
const SerdNode* uri)
{
- if (!serd_env_set_prefix(writer->env, name, uri)) {
- if (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG) {
- if (ctx(writer, SERD_GRAPH) || ctx(writer, SERD_SUBJECT)) {
- sink(" .\n\n", 4, writer);
- reset_context(writer, true);
- }
- sink("@prefix ", 8, writer);
- sink(serd_node_get_string(name), name->n_bytes, writer);
- sink(": <", 3, writer);
- write_uri_from_node(writer, uri);
- sink("> .\n", 4, writer);
+ if (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG) {
+ if (ctx(writer, SERD_GRAPH) || ctx(writer, SERD_SUBJECT)) {
+ sink(" .\n\n", 4, writer);
+ reset_context(writer, true);
}
- writer->indent = 0;
- return reset_context(writer, true);
+ sink("@prefix ", 8, writer);
+ sink(serd_node_get_string(name), name->n_bytes, writer);
+ sink(": <", 3, writer);
+ write_uri_from_node(writer, uri);
+ sink("> .\n", 4, writer);
}
- return SERD_ERR_UNKNOWN;
+ writer->indent = 0;
+ return reset_context(writer, true);
}
void
@@ -1020,7 +1015,7 @@ serd_writer_get_sink(SerdWriter* writer)
SerdEnv*
serd_writer_get_env(SerdWriter* writer)
{
- return writer->env;
+ return writer->iface.env;
}
size_t
diff --git a/tests/overflow_test.c b/tests/overflow_test.c
index 1614a2db..43be9932 100644
--- a/tests/overflow_test.c
+++ b/tests/overflow_test.c
@@ -56,7 +56,7 @@ main(void)
{NULL, 0}};
SerdWorld* world = serd_world_new();
- SerdSink* sink = serd_sink_new(NULL);
+ SerdSink* sink = serd_sink_new(NULL, NULL);
for (const Test* t = tests; t->str; ++t) {
const SerdStatus st = test(world, sink, t->str, t->stack_size);
diff --git a/tests/read_chunk_test.c b/tests/read_chunk_test.c
index 75750b8b..54513f06 100644
--- a/tests/read_chunk_test.c
+++ b/tests/read_chunk_test.c
@@ -74,7 +74,7 @@ int
main(void)
{
SerdWorld* world = serd_world_new();
- SerdSink* sink = serd_sink_new(NULL);
+ SerdSink* sink = serd_sink_new(NULL, NULL);
serd_sink_set_base_func(sink, on_base);
serd_sink_set_prefix_func(sink, on_prefix);
serd_sink_set_statement_func(sink, on_statement);
diff --git a/tests/serd_test.c b/tests/serd_test.c
index a461e22a..f923a9c0 100644
--- a/tests/serd_test.c
+++ b/tests/serd_test.c
@@ -452,10 +452,11 @@ main(void)
assert(serd_env_set_prefix(env, b, lit));
size_t n_prefixes = 0;
- SerdSink* count_prefixes_sink = serd_sink_new(&n_prefixes);
+ SerdSink* count_prefixes_sink = serd_sink_new(&n_prefixes, NULL);
serd_sink_set_prefix_func(count_prefixes_sink, count_prefixes);
serd_env_set_prefix(env, pre, eg);
serd_env_write_prefixes(env, count_prefixes_sink);
+ serd_sink_free(count_prefixes_sink);
assert(n_prefixes == 1);
SerdNode* shorter_uri = serd_new_uri("urn:foo");
@@ -601,7 +602,7 @@ main(void)
fseek(fd, 0, SEEK_SET);
size_t n_statements = 0;
- SerdSink* sink = serd_sink_new(&n_statements);
+ SerdSink* sink = serd_sink_new(&n_statements, NULL);
serd_sink_set_statement_func(sink, count_statements);
SerdReader* reader = serd_reader_new(world, SERD_TURTLE, sink, 4096);