aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/byte_sink.c57
-rw-r--r--src/byte_sink.h18
-rw-r--r--src/node_syntax.c8
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);