aboutsummaryrefslogtreecommitdiffstats
path: root/src/output_stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/output_stream.c')
-rw-r--r--src/output_stream.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/output_stream.c b/src/output_stream.c
new file mode 100644
index 00000000..1254aa4f
--- /dev/null
+++ b/src/output_stream.c
@@ -0,0 +1,89 @@
+/*
+ Copyright 2011-2021 David Robillard <d@drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include "serd_config.h"
+
+#include "serd/serd.h"
+
+// IWYU pragma: no_include <features.h>
+
+#include <assert.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,
+ SerdStreamCloseFunc const close_func,
+ void* const stream)
+{
+ assert(write_func);
+
+ SerdOutputStream output = {stream, write_func, close_func};
+ return output;
+}
+
+SerdOutputStream
+serd_open_output_buffer(SerdBuffer* const buffer)
+{
+ assert(buffer);
+
+ return serd_open_output_stream(serd_buffer_write, 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};
+ return failure;
+ }
+
+#if USE_POSIX_FADVISE && USE_FILENO
+ posix_fadvise(fileno(file), 0, 0, POSIX_FADV_SEQUENTIAL);
+#endif
+
+ return serd_open_output_stream(
+ (SerdWriteFunc)fwrite, (SerdStreamCloseFunc)fclose, file);
+}
+
+SerdStatus
+serd_close_output(SerdOutputStream* const output)
+{
+ int ret = 0;
+
+ if (output) {
+ if (output->close && output->stream) {
+ ret = output->close(output->stream);
+ output->stream = NULL;
+ }
+
+ output->stream = NULL;
+ }
+
+ return ret ? SERD_ERR_UNKNOWN : SERD_SUCCESS;
+}