From 7a0d649727b4b5a15a88a1270aa444d4ed8ce779 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 20 Feb 2021 19:18:28 -0500 Subject: Replace multiple stream callbacks with SerdEvent This makes plumbing easier since everything goes through the same "stream" and only one callback is required to handling everything. It's also more easily extensible in case more event types need to be added in the future. --- test/test_env.c | 16 ++++++++++------ test/test_overflow.c | 2 +- test/test_read_chunk.c | 24 ++++++++++++++++++----- test/test_reader_writer.c | 36 ++++++++++++++-------------------- test/test_sink.c | 49 ++++++++++++++++++++++++++++++++++++++++------- test/test_writer.c | 26 +++++++++++++++++++++++++ 6 files changed, 112 insertions(+), 41 deletions(-) (limited to 'test') diff --git a/test/test_env.c b/test/test_env.c index 1748b4cf..e5be688e 100644 --- a/test/test_env.c +++ b/test/test_env.c @@ -22,12 +22,12 @@ #include static SerdStatus -count_prefixes(void* handle, const SerdNode* name, const SerdNode* uri) +count_prefixes(void* handle, const SerdEvent* event) { - (void)name; - (void)uri; + if (event->type == SERD_PREFIX) { + ++*(int*)handle; + } - ++*(int*)handle; return SERD_SUCCESS; } @@ -87,10 +87,13 @@ test_env(void) const SerdNode* blank = serd_nodes_blank(nodes, SERD_STRING("b1")); assert(!serd_env_expand_node(env, blank)); - int n_prefixes = 0; + size_t n_prefixes = 0; + SerdSink* const count_prefixes_sink = + serd_sink_new(&n_prefixes, count_prefixes, NULL); + serd_env_set_prefix( env, SERD_STRING("eg.2"), SERD_STRING("http://example.org/")); - serd_env_foreach(env, count_prefixes, &n_prefixes); + serd_env_write_prefixes(env, count_prefixes_sink); assert(n_prefixes == 1); const SerdNode* shorter_uri = serd_nodes_uri(nodes, SERD_STRING("urn:foo")); @@ -107,6 +110,7 @@ test_env(void) assert(!serd_env_set_base_uri(env, SERD_EMPTY_STRING())); assert(!serd_env_base_uri(env)); + serd_sink_free(count_prefixes_sink); serd_nodes_free(nodes); serd_env_free(env); } diff --git a/test/test_overflow.c b/test/test_overflow.c index 2d7c2542..f29c8652 100644 --- a/test/test_overflow.c +++ b/test/test_overflow.c @@ -30,7 +30,7 @@ test_size(SerdWorld* const world, const SerdSyntax syntax, const size_t stack_size) { - SerdSink* sink = serd_sink_new(NULL, NULL); + SerdSink* sink = serd_sink_new(NULL, NULL, NULL); SerdReader* const reader = serd_reader_new(world, syntax, sink, stack_size); assert(reader); diff --git a/test/test_read_chunk.c b/test/test_read_chunk.c index f5ba8d93..0055ef3a 100644 --- a/test/test_read_chunk.c +++ b/test/test_read_chunk.c @@ -70,15 +70,29 @@ on_end(void* handle, const SerdNode* node) return SERD_SUCCESS; } +static SerdStatus +on_event(void* handle, const SerdEvent* event) +{ + switch (event->type) { + case SERD_BASE: + return on_base(handle, event->base.uri); + case SERD_PREFIX: + return on_prefix(handle, event->prefix.name, event->prefix.uri); + case SERD_STATEMENT: + return on_statement( + handle, event->statement.flags, event->statement.statement); + case SERD_END: + break; + } + + return on_end(handle, event->end.node); +} + int main(void) { SerdWorld* world = serd_world_new(); - 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); - serd_sink_set_end_func(sink, on_end); + SerdSink* sink = serd_sink_new(NULL, on_event, NULL); SerdReader* reader = serd_reader_new(world, SERD_TURTLE, sink, 4096); assert(reader); diff --git a/test/test_reader_writer.c b/test/test_reader_writer.c index 11939e2c..706f5962 100644 --- a/test/test_reader_writer.c +++ b/test/test_reader_writer.c @@ -25,14 +25,11 @@ #include static SerdStatus -test_sink(void* handle, - SerdStatementFlags flags, - const SerdStatement* statement) +count_statements(void* handle, const SerdEvent* event) { - (void)flags; - (void)statement; - - ++*(size_t*)handle; + if (event->type == SERD_STATEMENT) { + ++*(size_t*)handle; + } return SERD_SUCCESS; } @@ -88,13 +85,12 @@ 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, NULL); - SerdReader* reader = serd_reader_new(world, SERD_TURTLE, sink, 4096); - assert(reader); + SerdSink* const sink = serd_sink_new(&n_statements, count_statements, NULL); assert(sink); - assert(f); - serd_sink_set_statement_func(sink, test_sink); + + SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, sink, 4096); + assert(reader); SerdStatus st = serd_reader_start_stream( reader, (SerdReadFunc)fread, (SerdStreamErrorFunc)ferror, f, NULL, 1); @@ -147,17 +143,14 @@ test_read_chunks(void) static void test_read_string(void) { - SerdWorld* world = serd_world_new(); - size_t n_statements = 0; - SerdSink* sink = serd_sink_new(&n_statements, NULL); - SerdReader* reader = serd_reader_new(world, SERD_TURTLE, sink, 4096); + SerdWorld* world = serd_world_new(); + size_t n_statements = 0; - assert(reader); + SerdSink* sink = serd_sink_new(&n_statements, count_statements, NULL); assert(sink); - serd_sink_set_statement_func(sink, test_sink); - - serd_sink_set_statement_func(sink, test_sink); + SerdReader* reader = serd_reader_new(world, SERD_TURTLE, sink, 4096); + assert(reader); // Test reading a string that ends exactly at the end of input (no newline) assert( @@ -274,9 +267,8 @@ test_reader(const char* path) { SerdWorld* world = serd_world_new(); size_t n_statements = 0; - SerdSink* const sink = serd_sink_new(&n_statements, NULL); + SerdSink* const sink = serd_sink_new(&n_statements, count_statements, NULL); assert(sink); - serd_sink_set_statement_func(sink, test_sink); // Test that too little stack space fails gracefully assert(!serd_reader_new(world, SERD_TURTLE, sink, 32)); diff --git a/test/test_sink.c b/test/test_sink.c index 8b69d1df..29bb793f 100644 --- a/test/test_sink.c +++ b/test/test_sink.c @@ -76,6 +76,24 @@ on_end(void* handle, const SerdNode* node) return state->return_status; } +static SerdStatus +on_event(void* const handle, const SerdEvent* const event) +{ + switch (event->type) { + case SERD_BASE: + return on_base(handle, event->base.uri); + case SERD_PREFIX: + return on_prefix(handle, event->prefix.name, event->prefix.uri); + case SERD_STATEMENT: + return on_statement( + handle, event->statement.flags, event->statement.statement); + case SERD_END: + return on_end(handle, event->end.node); + } + + return SERD_ERR_BAD_ARG; +} + static void test_callbacks(void) { @@ -93,23 +111,37 @@ test_callbacks(void) State state = {0, 0, 0, 0, 0, SERD_SUCCESS}; + const SerdBaseEvent base_event = {SERD_BASE, uri}; + const SerdPrefixEvent prefix_event = {SERD_PREFIX, name, uri}; + const SerdStatementEvent statement_event = {SERD_STATEMENT, 0u, statement}; + const SerdEndEvent end_event = {SERD_END, blank}; + // Call functions on a sink with no functions set - SerdSink* null_sink = serd_sink_new(&state, NULL); + SerdSink* null_sink = serd_sink_new(&state, NULL, NULL); + assert(!serd_sink_write_base(null_sink, base)); assert(!serd_sink_write_prefix(null_sink, name, uri)); assert(!serd_sink_write_statement(null_sink, 0, statement)); assert(!serd_sink_write(null_sink, 0, base, uri, blank, NULL)); assert(!serd_sink_write_end(null_sink, blank)); + + SerdEvent event = {SERD_BASE}; + + event.base = base_event; + assert(!serd_sink_write_event(null_sink, &event)); + event.prefix = prefix_event; + assert(!serd_sink_write_event(null_sink, &event)); + event.statement = statement_event; + assert(!serd_sink_write_event(null_sink, &event)); + event.end = end_event; + assert(!serd_sink_write_event(null_sink, &event)); + serd_sink_free(null_sink); // Try again with a sink that has the event handler set - SerdSink* sink = serd_sink_new(&state, 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); - serd_sink_set_end_func(sink, on_end); + SerdSink* sink = serd_sink_new(&state, on_event, NULL); assert(!serd_sink_write_base(sink, base)); assert(serd_node_equals(state.last_base, base)); @@ -124,6 +156,9 @@ test_callbacks(void) assert(!serd_sink_write_end(sink, blank)); assert(serd_node_equals(state.last_end, blank)); + const SerdEvent junk = {(SerdEventType)42}; + assert(serd_sink_write_event(sink, &junk) == SERD_ERR_BAD_ARG); + serd_sink_free(sink); serd_statement_free(statement); @@ -139,7 +174,7 @@ test_free(void) // Set up a sink with dynamically allocated data and a free function uintptr_t* data = (uintptr_t*)calloc(1, sizeof(uintptr_t)); - SerdSink* sink = serd_sink_new(data, free); + SerdSink* sink = serd_sink_new(data, NULL, free); // Free the sink, which should free the data (rely on valgrind or sanitizers) serd_sink_free(sink); diff --git a/test/test_writer.c b/test/test_writer.c index 6f336ca4..d7c4eac8 100644 --- a/test/test_writer.c +++ b/test/test_writer.c @@ -22,6 +22,31 @@ #include #include +static void +test_write_bad_event(void) +{ + SerdWorld* world = serd_world_new(); + SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdBuffer buffer = {NULL, 0}; + SerdWriter* writer = + serd_writer_new(world, SERD_TURTLE, 0u, env, serd_buffer_sink, &buffer); + + assert(writer); + + const SerdEvent event = {(SerdEventType)42}; + assert(serd_sink_write_event(serd_writer_sink(writer), &event) == + SERD_ERR_BAD_ARG); + + char* const out = serd_buffer_sink_finish(&buffer); + + assert(!strcmp(out, "")); + serd_free(out); + + serd_writer_free(writer); + serd_env_free(env); + serd_world_free(world); +} + static void test_write_bad_prefix(void) { @@ -148,6 +173,7 @@ test_writer_stack_overflow(void) int main(void) { + test_write_bad_event(); test_write_bad_prefix(); test_write_long_literal(); test_writer_stack_overflow(); -- cgit v1.2.1