From 828c1018f38bab9a930cecce64646366d051d39b Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 13 Aug 2021 19:31:26 -0400 Subject: Simplify output stream API --- src/output_stream.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/output_stream.c (limited to 'src/output_stream.c') diff --git a/src/output_stream.c b/src/output_stream.c new file mode 100644 index 00000000..9014a372 --- /dev/null +++ b/src/output_stream.c @@ -0,0 +1,80 @@ +// Copyright 2011-2021 David Robillard +// SPDX-License-Identifier: ISC + +#include "serd_config.h" + +#include "serd/buffer.h" +#include "serd/output_stream.h" +#include "serd/status.h" +#include "serd/stream.h" + +// IWYU pragma: no_include + +#include +#include +#include +#include + +#if USE_POSIX_FADVISE && USE_FILENO +# include +#endif + +SerdOutputStream +serd_open_output_stream(SerdWriteFunc const write_func, + SerdErrorFunc const error_func, + SerdCloseFunc const close_func, + void* const stream) +{ + assert(write_func); + + SerdOutputStream output = {stream, write_func, error_func, close_func}; + return output; +} + +SerdOutputStream +serd_open_output_buffer(SerdBuffer* const buffer) +{ + assert(buffer); + + return serd_open_output_stream( + serd_buffer_write, NULL, serd_buffer_close, buffer); +} + +SerdOutputStream +serd_open_output_file(const char* const path) +{ + assert(path); + +#ifdef __GLIBC__ + FILE* const file = fopen(path, "wbe"); +#else + FILE* const file = fopen(path, "wb"); +#endif + + if (!file) { + const SerdOutputStream failure = {NULL, NULL, NULL, NULL}; + return failure; + } + +#if USE_POSIX_FADVISE && USE_FILENO + (void)posix_fadvise(fileno(file), 0, 0, POSIX_FADV_SEQUENTIAL); +#endif + + return serd_open_output_stream( + (SerdWriteFunc)fwrite, (SerdErrorFunc)ferror, (SerdCloseFunc)fclose, file); +} + +SerdStatus +serd_close_output(SerdOutputStream* const output) +{ + if (!output || !output->stream) { + return SERD_FAILURE; + } + + const bool had_error = output->error ? output->error(output->stream) : false; + int close_st = output->close ? output->close(output->stream) : 0; + + output->stream = NULL; + + return (had_error || close_st) ? SERD_BAD_STREAM : SERD_SUCCESS; +} -- cgit v1.2.1