diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/byte_sink.c | 57 | ||||
-rw-r--r-- | src/byte_sink.h | 18 | ||||
-rw-r--r-- | src/node_syntax.c | 8 |
3 files changed, 38 insertions, 45 deletions
diff --git a/src/byte_sink.c b/src/byte_sink.c index 42d12f7b..febd11cd 100644 --- a/src/byte_sink.c +++ b/src/byte_sink.c @@ -30,33 +30,39 @@ # include <fcntl.h> #endif +static int +close_buffer(void* const stream) +{ + serd_buffer_sink("", 1, 1, stream); // Write null terminator + + return 0; +} + SerdByteSink* serd_byte_sink_new_buffer(SerdBuffer* const buffer) { assert(buffer); - SerdByteSink* sink = (SerdByteSink*)calloc(1, sizeof(SerdByteSink)); - - sink->write_func = serd_buffer_sink; - sink->stream = buffer; - sink->block_size = 1; - sink->type = TO_BUFFER; - - return sink; + return serd_byte_sink_new_function( + serd_buffer_sink, close_buffer, buffer, 1u); } -static SerdByteSink* -serd_byte_sink_new_internal(const SerdWriteFunc write_func, - void* const stream, - const size_t block_size, - const SerdByteSinkType type) +SerdByteSink* +serd_byte_sink_new_function(const SerdWriteFunc write_func, + const SerdStreamCloseFunc close_func, + void* const stream, + const size_t block_size) { + if (!block_size) { + return NULL; + } + SerdByteSink* sink = (SerdByteSink*)calloc(1, sizeof(SerdByteSink)); sink->write_func = write_func; + sink->close_func = close_func; sink->stream = stream; sink->block_size = block_size; - sink->type = type; if (block_size > 1) { sink->buf = (char*)serd_allocate_buffer(block_size); @@ -83,20 +89,8 @@ serd_byte_sink_new_filename(const char* const path, const size_t block_size) posix_fadvise(fileno(file), 0, 0, POSIX_FADV_SEQUENTIAL); #endif - return serd_byte_sink_new_internal( - (SerdWriteFunc)fwrite, file, block_size, TO_FILENAME); -} - -SerdByteSink* -serd_byte_sink_new_function(const SerdWriteFunc write_func, - void* const stream, - const size_t block_size) -{ - assert(write_func); - - return block_size ? serd_byte_sink_new_internal( - write_func, stream, block_size, TO_FUNCTION) - : NULL; + return serd_byte_sink_new_function( + (SerdWriteFunc)fwrite, (SerdStreamCloseFunc)fclose, file, block_size); } void @@ -104,7 +98,7 @@ serd_byte_sink_flush(SerdByteSink* sink) { assert(sink); - if (sink->block_size > 1 && sink->size > 0) { + if (sink->stream && sink->block_size > 1 && sink->size > 0) { sink->write_func(sink->buf, 1, sink->size, sink->stream); sink->size = 0; } @@ -117,12 +111,13 @@ serd_byte_sink_close(SerdByteSink* sink) serd_byte_sink_flush(sink); - if (sink->type == TO_FILENAME && sink->stream) { - const int st = fclose((FILE*)sink->stream); + if (sink->stream && sink->close_func) { + const int st = sink->close_func(sink->stream); sink->stream = NULL; return st ? SERD_ERR_UNKNOWN : SERD_SUCCESS; } + sink->stream = NULL; return SERD_SUCCESS; } diff --git a/src/byte_sink.h b/src/byte_sink.h index f023f180..d117a589 100644 --- a/src/byte_sink.h +++ b/src/byte_sink.h @@ -22,19 +22,13 @@ #include <stddef.h> #include <string.h> -typedef enum { - TO_BUFFER, ///< Writing to a user-provided buffer - TO_FILENAME, ///< Writing to a file we opened - TO_FUNCTION, ///< Writing to a user-provided function -} SerdByteSinkType; - struct SerdByteSinkImpl { - SerdWriteFunc write_func; ///< User sink for TO_FUNCTION - void* stream; ///< User data for write_func - char* buf; ///< Local buffer iff block_size > 1 - size_t size; ///< Bytes written so far in this chunk - size_t block_size; ///< Size of chunks to write - SerdByteSinkType type; ///< Type of output + SerdWriteFunc write_func; ///< User sink for TO_FUNCTION + SerdStreamCloseFunc close_func; ///< Optional function to close stream + void* stream; ///< User data for write_func + char* buf; ///< Local buffer iff block_size > 1 + size_t size; ///< Bytes written so far in this chunk + size_t block_size; ///< Size of chunks to write }; static inline size_t diff --git a/src/node_syntax.c b/src/node_syntax.c index b1d10a5d..0c45e33a 100644 --- a/src/node_syntax.c +++ b/src/node_syntax.c @@ -99,8 +99,12 @@ serd_node_to_syntax_in(const SerdNode* const node, SerdWriter* const writer = serd_writer_new(world, syntax, 0, env, out); char* result = NULL; - if (!serd_writer_write_node(writer, node) && !serd_writer_finish(writer)) { - result = serd_buffer_sink_finish(&buffer); + if (!serd_writer_write_node(writer, node) && !serd_writer_finish(writer) && + !serd_byte_sink_close(out)) { + result = (char*)buffer.buf; + } else { + serd_byte_sink_close(out); + free(buffer.buf); } serd_writer_free(writer); |