From 0e739f34801ff6810064a8fac570f6be2b61ae70 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 13 Aug 2021 20:31:57 -0400 Subject: Simplify output stream API This makes the paging mechanism an internal detail once again. While it's conceptually elegant to simply have a single write interface and have the block dumper just be another implementation of that, unfortunately it is not practical. The inlining of serd_block_dumper_write() is a significant performance boost, because it avoids a non-inlinable function call of overhead per character. Compared to the SerdByteSink approach, this removes the burden and overhead of needing to dynamically allocate the structure itself. --- src/writer.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'src/writer.c') diff --git a/src/writer.c b/src/writer.c index 305c72e1..a9141f78 100644 --- a/src/writer.c +++ b/src/writer.c @@ -16,7 +16,7 @@ #include "writer.h" -#include "byte_sink.h" +#include "block_dumper.h" #include "env.h" #include "node.h" #include "sink.h" @@ -128,7 +128,7 @@ struct SerdWriterImpl { SerdURIView root_uri; WriteContext* anon_stack; size_t anon_stack_size; - SerdByteSink* byte_sink; + SerdBlockDumper output; WriteContext context; Sep last_sep; int indent; @@ -251,7 +251,8 @@ ctx(SerdWriter* writer, const SerdField field) SERD_WARN_UNUSED_RESULT static size_t sink(const void* buf, size_t len, SerdWriter* writer) { - const size_t written = serd_byte_sink_write(buf, len, writer->byte_sink); + const size_t written = serd_block_dumper_write(buf, 1, len, &writer->output); + if (written != len) { if (errno) { char message[1024] = {0}; @@ -1306,6 +1307,9 @@ serd_writer_finish(SerdWriter* writer) } free_context(writer); + + serd_block_dumper_flush(&writer->output); + writer->indent = 0; writer->context = WRITE_CONTEXT_NULL; writer->empty = true; @@ -1313,15 +1317,21 @@ serd_writer_finish(SerdWriter* writer) } SerdWriter* -serd_writer_new(SerdWorld* world, - SerdSyntax syntax, - SerdWriterFlags flags, - const SerdEnv* env, - SerdByteSink* byte_sink) +serd_writer_new(SerdWorld* world, + SerdSyntax syntax, + SerdWriterFlags flags, + const SerdEnv* env, + SerdOutputStream* output, + size_t block_size) { assert(world); assert(env); - assert(byte_sink); + assert(output); + + SerdBlockDumper dumper = {NULL, NULL, 0u, 0u}; + if (serd_block_dumper_open(&dumper, output, block_size)) { + return NULL; + } const WriteContext context = WRITE_CONTEXT_NULL; SerdWriter* writer = (SerdWriter*)calloc(1, sizeof(SerdWriter)); @@ -1332,7 +1342,7 @@ serd_writer_new(SerdWorld* world, writer->env = env; writer->root_node = NULL; writer->root_uri = SERD_URI_NULL; - writer->byte_sink = byte_sink; + writer->output = dumper; writer->context = context; writer->empty = true; @@ -1425,6 +1435,7 @@ serd_writer_free(SerdWriter* writer) } serd_writer_finish(writer); + serd_block_dumper_close(&writer->output); free(writer->anon_stack); serd_node_free(writer->root_node); free(writer); -- cgit v1.2.1