diff options
author | David Robillard <d@drobilla.net> | 2021-08-13 19:31:26 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2023-12-02 18:49:08 -0500 |
commit | 828c1018f38bab9a930cecce64646366d051d39b (patch) | |
tree | 38a60777520efb17017ed62fe3b299ba94aaccf2 /src/output_stream.c | |
parent | a083c64f506175029280ff76defa0ad7d7ae2ea0 (diff) | |
download | serd-828c1018f38bab9a930cecce64646366d051d39b.tar.gz serd-828c1018f38bab9a930cecce64646366d051d39b.tar.bz2 serd-828c1018f38bab9a930cecce64646366d051d39b.zip |
Simplify output stream API
Diffstat (limited to 'src/output_stream.c')
-rw-r--r-- | src/output_stream.c | 80 |
1 files changed, 80 insertions, 0 deletions
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 <d@drobilla.net> +// 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 <features.h> + +#include <assert.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdio.h> + +#if USE_POSIX_FADVISE && USE_FILENO +# include <fcntl.h> +#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; +} |