aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-06-03 19:24:59 +0200
committerDavid Robillard <d@drobilla.net>2021-03-08 23:23:05 -0500
commit846553f8894264d64cdd1dfb08df56fe08189dac (patch)
tree6ca8d42da04999851491edcf6811d05d4962bcac
parent7c6c3159d1804f4855d9a4e0cd52486f61fcbab6 (diff)
downloadserd-846553f8894264d64cdd1dfb08df56fe08189dac.tar.gz
serd-846553f8894264d64cdd1dfb08df56fe08189dac.tar.bz2
serd-846553f8894264d64cdd1dfb08df56fe08189dac.zip
Add SerdStatement
-rw-r--r--include/serd/serd.h57
-rw-r--r--meson.build1
-rw-r--r--src/reader.c9
-rw-r--r--src/sink.c17
-rw-r--r--src/statement.c53
-rw-r--r--src/statement.h34
-rw-r--r--src/writer.c14
-rw-r--r--test/test_read_chunk.c14
-rw-r--r--test/test_reader_writer.c16
9 files changed, 177 insertions, 38 deletions
diff --git a/include/serd/serd.h b/include/serd/serd.h
index b5c7c4f0..e32e66cc 100644
--- a/include/serd/serd.h
+++ b/include/serd/serd.h
@@ -84,6 +84,9 @@ extern "C" {
/// Global library state
typedef struct SerdWorldImpl SerdWorld;
+/// A subject, predicate, and object, with optional graph context
+typedef struct SerdStatementImpl SerdStatement;
+
/// The origin of a statement in a document
typedef struct SerdCursorImpl SerdCursor;
@@ -841,12 +844,10 @@ typedef SerdStatus (*SerdPrefixFunc)(void* SERD_NULLABLE handle,
Called for every RDF statement in the serialisation.
*/
-typedef SerdStatus (*SerdStatementFunc)(void* SERD_NULLABLE handle,
- SerdStatementFlags flags,
- const SerdNode* SERD_NULLABLE graph,
- const SerdNode* SERD_NONNULL subject,
- const SerdNode* SERD_NONNULL predicate,
- const SerdNode* SERD_NONNULL object);
+typedef SerdStatus (*SerdStatementFunc)(void* SERD_NULLABLE handle,
+ SerdStatementFlags flags,
+ const SerdStatement* SERD_NONNULL
+ statement);
/**
Sink function for anonymous node end markers
@@ -1037,6 +1038,13 @@ serd_sink_write_prefix(const SerdSink* SERD_NONNULL sink,
const SerdNode* SERD_NONNULL name,
const SerdNode* SERD_NONNULL uri);
+/// Write a statement
+SERD_API
+SerdStatus
+serd_sink_write_statement(const SerdSink* SERD_NONNULL sink,
+ SerdStatementFlags flags,
+ const SerdStatement* SERD_NONNULL statement);
+
/// Write a statement from individual nodes
SERD_API
SerdStatus
@@ -1266,6 +1274,43 @@ serd_writer_finish(SerdWriter* SERD_NONNULL writer);
/**
@}
+ @defgroup serd_statement Statement
+ @{
+*/
+
+/// Return the given node in `statement`
+SERD_PURE_API
+const SerdNode* SERD_NULLABLE
+serd_statement_node(const SerdStatement* SERD_NONNULL statement,
+ SerdField field);
+
+/// Return the subject in `statement`
+SERD_PURE_API
+const SerdNode* SERD_NONNULL
+serd_statement_subject(const SerdStatement* SERD_NONNULL statement);
+
+/// Return the predicate in `statement`
+SERD_PURE_API
+const SerdNode* SERD_NONNULL
+serd_statement_predicate(const SerdStatement* SERD_NONNULL statement);
+
+/// Return the object in `statement`
+SERD_PURE_API
+const SerdNode* SERD_NONNULL
+serd_statement_object(const SerdStatement* SERD_NONNULL statement);
+
+/// Return the graph in `statement`
+SERD_PURE_API
+const SerdNode* SERD_NULLABLE
+serd_statement_graph(const SerdStatement* SERD_NONNULL statement);
+
+/// Return the source location where `statement` originated, or NULL
+SERD_PURE_API
+const SerdCursor* SERD_NULLABLE
+serd_statement_cursor(const SerdStatement* SERD_NONNULL statement);
+
+/**
+ @}
@defgroup serd_cursor Cursor
@{
*/
diff --git a/meson.build b/meson.build
index 5bfafbd5..05120981 100644
--- a/meson.build
+++ b/meson.build
@@ -99,6 +99,7 @@ sources = [
'src/node.c',
'src/reader.c',
'src/sink.c',
+ 'src/statement.c',
'src/string.c',
'src/syntax.c',
'src/system.c',
diff --git a/src/reader.c b/src/reader.c
index f6c5e056..351428fc 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -18,6 +18,8 @@
#include "byte_source.h"
#include "serd_internal.h"
+#include "stack.h"
+#include "statement.h"
#include "system.h"
#include "world.h"
@@ -121,8 +123,11 @@ emit_statement(SerdReader* reader, ReadContext ctx, SerdNode* o)
(subject and predicate) were already zeroed by subsequent pushes. */
serd_node_zero_pad(o);
- const SerdStatus st = serd_sink_write(
- reader->sink, *ctx.flags, ctx.subject, ctx.predicate, o, ctx.graph);
+ const SerdStatement statement = {{ctx.subject, ctx.predicate, o, ctx.graph},
+ &reader->source.cur};
+
+ const SerdStatus st =
+ serd_sink_write_statement(reader->sink, *ctx.flags, &statement);
*ctx.flags &= SERD_ANON_CONT | SERD_LIST_CONT; // Preserve only cont flags
return st;
diff --git a/src/sink.c b/src/sink.c
index b62af23a..6f8cc734 100644
--- a/src/sink.c
+++ b/src/sink.c
@@ -16,6 +16,8 @@
#include "sink.h"
+#include "statement.h"
+
#include "serd/serd.h"
#include <stdlib.h>
@@ -86,6 +88,15 @@ serd_sink_write_prefix(const SerdSink* sink,
}
SerdStatus
+serd_sink_write_statement(const SerdSink* sink,
+ const SerdStatementFlags flags,
+ const SerdStatement* statement)
+{
+ return sink->statement ? sink->statement(sink->handle, flags, statement)
+ : SERD_SUCCESS;
+}
+
+SerdStatus
serd_sink_write(const SerdSink* sink,
const SerdStatementFlags flags,
const SerdNode* subject,
@@ -93,10 +104,8 @@ serd_sink_write(const SerdSink* sink,
const SerdNode* object,
const SerdNode* graph)
{
- return sink->statement
- ? sink->statement(
- sink->handle, flags, graph, subject, predicate, object)
- : SERD_SUCCESS;
+ const SerdStatement statement = {{subject, predicate, object, graph}, NULL};
+ return serd_sink_write_statement(sink, flags, &statement);
}
SerdStatus
diff --git a/src/statement.c b/src/statement.c
new file mode 100644
index 00000000..c9bac440
--- /dev/null
+++ b/src/statement.c
@@ -0,0 +1,53 @@
+/*
+ Copyright 2011-2020 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include "statement.h"
+
+const SerdNode*
+serd_statement_node(const SerdStatement* statement, SerdField field)
+{
+ return statement->nodes[field];
+}
+
+const SerdNode*
+serd_statement_subject(const SerdStatement* statement)
+{
+ return statement->nodes[SERD_SUBJECT];
+}
+
+const SerdNode*
+serd_statement_predicate(const SerdStatement* statement)
+{
+ return statement->nodes[SERD_PREDICATE];
+}
+
+const SerdNode*
+serd_statement_object(const SerdStatement* statement)
+{
+ return statement->nodes[SERD_OBJECT];
+}
+
+const SerdNode*
+serd_statement_graph(const SerdStatement* statement)
+{
+ return statement->nodes[SERD_GRAPH];
+}
+
+const SerdCursor*
+serd_statement_cursor(const SerdStatement* statement)
+{
+ return statement->cursor;
+}
diff --git a/src/statement.h b/src/statement.h
new file mode 100644
index 00000000..a5baaa6a
--- /dev/null
+++ b/src/statement.h
@@ -0,0 +1,34 @@
+/*
+ Copyright 2011-2020 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#ifndef SERD_STATEMENT_H
+#define SERD_STATEMENT_H
+
+#include "serd/serd.h"
+
+/**
+ Quad of nodes (a statement), or a quad pattern.
+
+ Nodes are ordered (S P O G). The ID of the default graph is 0.
+*/
+typedef const SerdNode* SerdQuad[4];
+
+struct SerdStatementImpl {
+ SerdQuad nodes;
+ SerdCursor* cursor;
+};
+
+#endif // SERD_STATEMENT_H
diff --git a/src/writer.c b/src/writer.c
index 8800282d..4160c09d 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -773,13 +773,15 @@ write_list_obj(SerdWriter* writer,
}
static SerdStatus
-serd_writer_write_statement(SerdWriter* writer,
- SerdStatementFlags flags,
- const SerdNode* graph,
- const SerdNode* subject,
- const SerdNode* predicate,
- const SerdNode* object)
+serd_writer_write_statement(SerdWriter* writer,
+ SerdStatementFlags flags,
+ const SerdStatement* statement)
{
+ const SerdNode* const subject = serd_statement_subject(statement);
+ const SerdNode* const predicate = serd_statement_predicate(statement);
+ const SerdNode* const object = serd_statement_object(statement);
+ const SerdNode* const graph = serd_statement_graph(statement);
+
if (!is_resource(subject) || !is_resource(predicate) || !object) {
return SERD_ERR_BAD_ARG;
}
diff --git a/test/test_read_chunk.c b/test/test_read_chunk.c
index 8be4ad63..d77c3398 100644
--- a/test/test_read_chunk.c
+++ b/test/test_read_chunk.c
@@ -48,19 +48,13 @@ on_prefix(void* handle, const SerdNode* name, const SerdNode* uri)
}
static SerdStatus
-on_statement(void* handle,
- SerdStatementFlags flags,
- const SerdNode* graph,
- const SerdNode* subject,
- const SerdNode* predicate,
- const SerdNode* object)
+on_statement(void* handle,
+ SerdStatementFlags flags,
+ const SerdStatement* statement)
{
(void)handle;
(void)flags;
- (void)graph;
- (void)subject;
- (void)predicate;
- (void)object;
+ (void)statement;
++n_statement;
return SERD_SUCCESS;
diff --git a/test/test_reader_writer.c b/test/test_reader_writer.c
index 788b2d63..9ccfa967 100644
--- a/test/test_reader_writer.c
+++ b/test/test_reader_writer.c
@@ -26,18 +26,12 @@
#include <string.h>
static SerdStatus
-test_sink(void* handle,
- SerdStatementFlags flags,
- const SerdNode* graph,
- const SerdNode* subject,
- const SerdNode* predicate,
- const SerdNode* object)
+test_sink(void* handle,
+ SerdStatementFlags flags,
+ const SerdStatement* statement)
{
(void)flags;
- (void)subject;
- (void)predicate;
- (void)object;
- (void)graph;
+ (void)statement;
++*(size_t*)handle;
@@ -164,6 +158,8 @@ test_read_string(void)
serd_sink_set_statement_func(sink, test_sink);
+ serd_sink_set_statement_func(sink, test_sink);
+
// Test reading a string that ends exactly at the end of input (no newline)
assert(
!serd_reader_start_string(reader,