aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-12-29 17:36:15 -0500
committerDavid Robillard <d@drobilla.net>2019-12-19 20:57:55 -0500
commitb1e79af3188b1caf2051fca20fba6464e4ce62d4 (patch)
tree9c8d230bd6392440c7779aebdb8e133b0a6f4faa
parenta20bfec928afe3be17765f7b044ecd7244502689 (diff)
downloadserd-b1e79af3188b1caf2051fca20fba6464e4ce62d4.tar.gz
serd-b1e79af3188b1caf2051fca20fba6464e4ce62d4.tar.bz2
serd-b1e79af3188b1caf2051fca20fba6464e4ce62d4.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.h17
-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.c65
-rw-r--r--tests/overflow_test.c2
-rw-r--r--tests/read_chunk_test.c2
-rw-r--r--tests/serd_test.c9
9 files changed, 72 insertions, 73 deletions
diff --git a/serd/serd.h b/serd/serd.h
index 2613ed6f..f18968e7 100644
--- a/serd/serd.h
+++ b/serd/serd.h
@@ -1095,10 +1095,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`.
@@ -1108,6 +1109,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
@@ -1336,13 +1344,6 @@ const SerdSink*
serd_writer_get_sink(SerdWriter* writer);
/**
- Return the env used by `writer`.
-*/
-SERD_API
-SerdEnv*
-serd_writer_get_env(SerdWriter* writer);
-
-/**
A convenience sink function for writing to a string.
This function can be used as a SerdSink to write to a SerdBuffer which is
diff --git a/src/n3.c b/src/n3.c
index 427281a1..a3075cac 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"
@@ -975,8 +974,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
@@ -1279,10 +1278,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) {
@@ -1318,11 +1315,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 778616d2..44117a20 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 29dd67c3..86a5c966 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;
@@ -516,6 +515,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);
@@ -533,7 +534,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);
@@ -543,8 +544,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);
@@ -583,7 +584,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",
@@ -907,7 +908,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);
@@ -917,6 +917,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;
@@ -943,20 +944,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
@@ -980,22 +978,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
@@ -1014,12 +1009,6 @@ serd_writer_get_sink(SerdWriter* writer)
return &writer->iface;
}
-SerdEnv*
-serd_writer_get_env(SerdWriter* writer)
-{
- return writer->env;
-}
-
size_t
serd_buffer_sink(const void* buf, size_t size, size_t nmemb, void* stream)
{
diff --git a/tests/overflow_test.c b/tests/overflow_test.c
index 4a942f58..7e545793 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 65079c5d..80e5b926 100644
--- a/tests/serd_test.c
+++ b/tests/serd_test.c
@@ -102,7 +102,7 @@ test_read_chunks(void)
size_t n_statements = 0;
FILE* const f = tmpfile();
static const char null = 0;
- SerdSink* sink = serd_sink_new(&n_statements);
+ SerdSink* sink = serd_sink_new(&n_statements, NULL);
assert(sink);
serd_sink_set_statement_func(sink, count_statements);
@@ -592,10 +592,11 @@ test_env(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");
@@ -659,7 +660,7 @@ test_writer(const char* const path)
assert(serd_sink_write_base(iface, lit));
assert(serd_sink_write_prefix(iface, lit, lit));
assert(serd_sink_write_end(iface, NULL));
- assert(serd_writer_get_env(writer) == env);
+ assert(serd_sink_get_env(iface) == env);
uint8_t buf[] = { 0xEF, 0xBF, 0xBD, 0 };
SerdNode* s = serd_new_uri("");
@@ -757,7 +758,7 @@ test_reader(const char* path)
SerdWorld* world = serd_world_new();
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);