From 50733eb0168565dd75f01cbdb9d9eb7a6c7f06ac Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 18 Mar 2012 16:33:11 +0000 Subject: Add SordInserter for writing to a model via Serd sink functions. git-svn-id: http://svn.drobilla.net/sord/trunk@209 3d64ff67-21c5-427c-a301-fe4f08042e5a --- ChangeLog | 1 + sord/sord.h | 67 +++++++++++++++++++++++++++++++++ src/syntax.c | 121 +++++++++++++++++++++++++++++++---------------------------- wscript | 6 +-- 4 files changed, 134 insertions(+), 61 deletions(-) diff --git a/ChangeLog b/ChangeLog index ddc3241..45efc44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,7 @@ sord (UNRELEASED) unstable; urgency=low * Add sord_iter_get_node() * Refuse to intern relative URIs in sord_new_uri*() * Add sord_new_relative_uri() + * Add SordInserter for writing to a model via Serd sink functions. -- David Robillard (UNRELEASED) diff --git a/sord/sord.h b/sord/sord.h index 0d71d99..9bd3f02 100644 --- a/sord/sord.h +++ b/sord/sord.h @@ -74,6 +74,15 @@ typedef struct SordWorldImpl SordWorld; */ typedef struct SordModelImpl SordModel; +/** + Model Inserter. + + An inserter is used for writing statements to a model using the Serd sink + interface. This makes it simple to write to a model directly using a + SerdReader, or any other code that writes statements to a SerdStatementSink. +*/ +typedef struct SordInserterImpl SordInserter; + /** Model Iterator. */ @@ -388,6 +397,64 @@ SORD_API void sord_remove(SordModel* model, const SordQuad quad); +/** + @} + @name Inserter + @{ +*/ + +/** + Create an inserter for writing statements to a model. +*/ +SORD_API +SordInserter* +sord_inserter_new(SordModel* model, + SerdEnv* env); + +/** + Free an inserter. +*/ +SORD_API +void +sord_inserter_free(SordInserter* inserter); + +/** + Set the current base URI for writing to the model. + + Note this function can be safely casted to SerdBaseSink. +*/ +SORD_API +SerdStatus +sord_inserter_set_base_uri(SordInserter* inserter, + const SerdNode* uri); + +/** + Set a namespace prefix for writing to the model. + + Note this function can be safely casted to SerdPrefixSink. +*/ +SORD_API +SerdStatus +sord_inserter_set_prefix(SordInserter* inserter, + const SerdNode* name, + const SerdNode* uri); + +/** + Write a statement to the model. + + Note this function can be safely casted to SerdStatementSink. +*/ +SORD_API +SerdStatus +sord_inserter_write_statement(SordInserter* inserter, + SerdStatementFlags flags, + const SerdNode* graph, + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* object, + const SerdNode* object_datatype, + const SerdNode* object_lang); + /** @} @name Iteration diff --git a/src/syntax.c b/src/syntax.c index 962d6e4..6eed6ad 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -23,68 +23,68 @@ #include "sord_config.h" #include "sord_internal.h" -typedef struct { +struct SordInserterImpl { + SordModel* model; SerdEnv* env; - SordNode* graph_uri_node; - SordWorld* world; - SordModel* sord; -} ReadState; - -static SerdStatus -event_base(void* handle, - const SerdNode* uri_node) +}; + +SordInserter* +sord_inserter_new(SordModel* model, + SerdEnv* env) { - ReadState* const state = (ReadState*)handle; + SordInserter* inserter = (SordInserter*)malloc(sizeof(SordInserter)); + inserter->model = model; + inserter->env = env; + return inserter; +} - return serd_env_set_base_uri(state->env, uri_node); +void +sord_inserter_free(SordInserter* inserter) +{ + free(inserter); } -static SerdStatus -event_prefix(void* handle, - const SerdNode* name, - const SerdNode* uri_node) +SerdStatus +sord_inserter_set_base_uri(SordInserter* inserter, + const SerdNode* uri_node) { - ReadState* const state = (ReadState*)handle; + return serd_env_set_base_uri(inserter->env, uri_node); +} - return serd_env_set_prefix(state->env, name, uri_node); +SerdStatus +sord_inserter_set_prefix(SordInserter* inserter, + const SerdNode* name, + const SerdNode* uri_node) +{ + return serd_env_set_prefix(inserter->env, name, uri_node); } -static SerdStatus -event_statement(void* handle, - SerdStatementFlags flags, - const SerdNode* graph, - const SerdNode* subject, - const SerdNode* predicate, - const SerdNode* object, - const SerdNode* object_datatype, - const SerdNode* object_lang) +SerdStatus +sord_inserter_write_statement(SordInserter* inserter, + SerdStatementFlags flags, + const SerdNode* graph, + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* object, + const SerdNode* object_datatype, + const SerdNode* object_lang) { - ReadState* const state = (ReadState*)handle; - - SordNode* s = sord_node_from_serd_node(state->world, state->env, - subject, NULL, NULL); - SordNode* p = sord_node_from_serd_node(state->world, state->env, - predicate, NULL, NULL); - SordNode* o = sord_node_from_serd_node( - state->world, state->env, object, object_datatype, object_lang); - - SordNode* g = NULL; - if (state->graph_uri_node) { - g = sord_node_copy(state->graph_uri_node); - } else { - g = (graph && graph->buf) - ? sord_node_from_serd_node(state->world, state->env, - graph, NULL, NULL) - : NULL; - } + SordWorld* world = sord_get_world(inserter->model); + SerdEnv* env = inserter->env; + + SordNode* g = sord_node_from_serd_node(world, env, graph, NULL, NULL); + SordNode* s = sord_node_from_serd_node(world, env, subject, NULL, NULL); + SordNode* p = sord_node_from_serd_node(world, env, predicate, NULL, NULL); + SordNode* o = sord_node_from_serd_node(world, env, object, + object_datatype, object_lang); const SordQuad tup = { s, p, o, g }; - sord_add(state->sord, tup); + sord_add(inserter->model, tup); - sord_node_free(state->world, s); - sord_node_free(state->world, p); - sord_node_free(state->world, o); - sord_node_free(state->world, g); + sord_node_free(world, o); + sord_node_free(world, p); + sord_node_free(world, s); + sord_node_free(world, g); return SERD_SUCCESS; } @@ -96,21 +96,26 @@ sord_new_reader(SordModel* model, SerdSyntax syntax, SordNode* graph) { - ReadState* state = (ReadState*)malloc(sizeof(ReadState)); - state->env = env; - state->graph_uri_node = graph; - state->world = sord_get_world(model); - state->sord = model; - + SordInserter* inserter = sord_inserter_new(model, env); + SerdReader* reader = serd_reader_new( - syntax, state, free, - event_base, event_prefix, event_statement, NULL); + syntax, inserter, (void (*)(void*))sord_inserter_free, + (SerdBaseSink)sord_inserter_set_base_uri, + (SerdPrefixSink)sord_inserter_set_prefix, + (SerdStatementSink)sord_inserter_write_statement, + NULL); + + if (graph) { + serd_reader_set_default_graph(reader, sord_node_to_serd_node(graph)); + } return reader; } static void -write_statement(SordModel* sord, SerdWriter* writer, SordQuad tup, +write_statement(SordModel* sord, + SerdWriter* writer, + SordQuad tup, SerdStatementFlags flags) { const SordNode* s = tup[SORD_SUBJECT]; diff --git a/wscript b/wscript index 0b68c52..c6e3289 100644 --- a/wscript +++ b/wscript @@ -8,7 +8,7 @@ from waflib.extras import autowaf as autowaf import waflib.Logs as Logs, waflib.Options as Options # Version of this package (even if built as a child) -SORD_VERSION = '0.6.1' +SORD_VERSION = '0.7.0' SORD_MAJOR_VERSION = '0' # Library version (UNIX style major, minor, micro) @@ -50,7 +50,7 @@ def configure(conf): conf.env.append_unique('CFLAGS', '-std=c99') autowaf.check_pkg(conf, 'serd-0', uselib_store='SERD', - atleast_version='0.8.0', mandatory=True) + atleast_version='0.14.0', mandatory=True) conf.env['BUILD_TESTS'] = Options.options.build_tests conf.env['BUILD_UTILS'] = True @@ -278,7 +278,7 @@ def test(ctx): 'sordi_static %s/tests/UTF-8.ttl > %s' % (srcdir, nul), 'sordi_static -v > %s' % nul, 'sordi_static -h > %s' % nul, - 'sordi_static -s " a <#Thingie> ." > %s' % nul, + 'sordi_static -s " a <#Thingie> ." file:///test > %s' % nul, 'sordi_static %s > %s' % (nul, nul)], 0, name='sordi-cmd-good') -- cgit v1.2.1