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 /include | |
parent | a083c64f506175029280ff76defa0ad7d7ae2ea0 (diff) | |
download | serd-828c1018f38bab9a930cecce64646366d051d39b.tar.gz serd-828c1018f38bab9a930cecce64646366d051d39b.tar.bz2 serd-828c1018f38bab9a930cecce64646366d051d39b.zip |
Simplify output stream API
Diffstat (limited to 'include')
-rw-r--r-- | include/serd/buffer.h | 4 | ||||
-rw-r--r-- | include/serd/output_stream.h | 94 | ||||
-rw-r--r-- | include/serd/serd.h | 1 | ||||
-rw-r--r-- | include/serd/stream.h | 20 | ||||
-rw-r--r-- | include/serd/writer.h | 20 |
5 files changed, 108 insertions, 31 deletions
diff --git a/include/serd/buffer.h b/include/serd/buffer.h index 556e7e1f..20abfb29 100644 --- a/include/serd/buffer.h +++ b/include/serd/buffer.h @@ -17,8 +17,8 @@ SERD_BEGIN_DECLS The #SerdBuffer type represents a writable area of memory with a known size. - A #SerdWriteFunc function is provided which enable writing output to a - memory buffer (as `fwrite` does for files). + #SerdWriteFunc and #SerdCloseFunc functions are provided which enable + writing output to a memory buffer (as `fwrite` and `fclose` do for files). @{ */ diff --git a/include/serd/output_stream.h b/include/serd/output_stream.h new file mode 100644 index 00000000..91c04e6b --- /dev/null +++ b/include/serd/output_stream.h @@ -0,0 +1,94 @@ +// Copyright 2011-2022 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#ifndef SERD_OUTPUT_STREAM_H +#define SERD_OUTPUT_STREAM_H + +#include "serd/attributes.h" +#include "serd/buffer.h" +#include "serd/status.h" +#include "serd/stream.h" +#include "zix/attributes.h" + +SERD_BEGIN_DECLS + +/** + @defgroup serd_output_stream Output Streams + @ingroup serd_reading_writing + @{ +*/ + +/** + An output stream that receives bytes. + + An output stream is used for writing output as a raw stream of bytes. It is + compatible with standard C `FILE` streams, but allows different functions to + be provided for things like writing to a buffer or a socket. + + Output from serd is UTF-8 encoded text. +*/ +typedef struct { + void* ZIX_NULLABLE stream; ///< Opaque parameter for functions + SerdWriteFunc ZIX_NONNULL write; ///< Write bytes to output + SerdErrorFunc ZIX_NULLABLE error; ///< Stream error accessor + SerdCloseFunc ZIX_NULLABLE close; ///< Close output +} SerdOutputStream; + +/** + Open a stream that writes to a provided function. + + @param write_func Function to write bytes to the stream. + @param error_func Function to detect errors in the stream. + @param close_func Function to close the stream. + @param stream Stream parameter passed to `write_func` and `close_func`. + @return An opened output stream, or all zeros on error. +*/ +SERD_CONST_API SerdOutputStream +serd_open_output_stream(SerdWriteFunc ZIX_NONNULL write_func, + SerdErrorFunc ZIX_NULLABLE error_func, + SerdCloseFunc ZIX_NULLABLE close_func, + void* ZIX_NULLABLE stream); + +/** + Open a stream that writes to a buffer. + + The `buffer` is owned by the caller, but will be expanded using `realloc` as + necessary. Note that the string in the buffer will not be null terminated + until the stream is closed. + + @param buffer Buffer to write output to. + @return An opened output stream, or all zeros on error. +*/ +SERD_CONST_API SerdOutputStream +serd_open_output_buffer(SerdBuffer* ZIX_NONNULL buffer); + +/** + Open a stream that writes to a file. + + An arbitrary `FILE*` can be used with serd_open_output_stream() as well, + this convenience function opens the file properly for writing with serd, and + sets flags for optimized I/O if possible. + + @param path Path of file to open and write to. +*/ +SERD_API SerdOutputStream +serd_open_output_file(const char* ZIX_NONNULL path); + +/** + Close an output stream. + + This will call the close function, and reset the stream internally so that + no further writes can be made. For convenience, this is safe to call on + NULL, and safe to call several times on the same output. Failure is + returned in both of those cases. +*/ +SERD_API SerdStatus +serd_close_output(SerdOutputStream* ZIX_NULLABLE output); + +/** + @} +*/ + +SERD_END_DECLS + +#endif // SERD_OUTPUT_STREAM_H diff --git a/include/serd/serd.h b/include/serd/serd.h index 58c8e7ec..2b09eff2 100644 --- a/include/serd/serd.h +++ b/include/serd/serd.h @@ -79,6 +79,7 @@ */ #include "serd/input_stream.h" +#include "serd/output_stream.h" #include "serd/reader.h" #include "serd/stream.h" #include "serd/writer.h" diff --git a/include/serd/stream.h b/include/serd/stream.h index f59e2c9d..a6fabb69 100644 --- a/include/serd/stream.h +++ b/include/serd/stream.h @@ -24,24 +24,6 @@ SERD_BEGIN_DECLS */ /** - Function to detect I/O stream errors. - - Identical semantics to `ferror`. - - @return Non-zero if `stream` has encountered an error. -*/ -typedef int (*SerdStreamErrorFunc)(void* ZIX_NONNULL stream); - -/** - Function to close an I/O stream. - - Identical semantics to `fclose`. - - @return Non-zero if `stream` has encountered an error. -*/ -typedef int (*SerdStreamCloseFunc)(void* ZIX_NONNULL stream); - -/** Function for reading input bytes from a stream. This has identical semantics to `fread`, but may set `errno` for more @@ -62,7 +44,7 @@ typedef size_t (*SerdReadFunc)(void* ZIX_NONNULL buf, Function for writing output bytes to a stream. This has identical semantics to `fwrite`, but may set `errno` for more - informative error reporting than supported by #SerdStreamErrorFunc. + informative error reporting than supported by #SerdErrorFunc. @param buf Input buffer. @param size Size of a single element of data in bytes (always 1). diff --git a/include/serd/writer.h b/include/serd/writer.h index 3cd7e2f4..41ffb8cd 100644 --- a/include/serd/writer.h +++ b/include/serd/writer.h @@ -6,14 +6,15 @@ #include "serd/attributes.h" #include "serd/env.h" +#include "serd/output_stream.h" #include "serd/sink.h" #include "serd/status.h" -#include "serd/stream.h" #include "serd/string_view.h" #include "serd/syntax.h" #include "serd/world.h" #include "zix/attributes.h" +#include <stddef.h> #include <stdint.h> SERD_BEGIN_DECLS @@ -38,9 +39,8 @@ typedef enum { SERD_WRITE_ASCII = 1U << 0U, ///< Escape all non-ASCII characters SERD_WRITE_UNQUALIFIED = 1U << 1U, ///< Do not shorten URIs into CURIEs SERD_WRITE_UNRESOLVED = 1U << 2U, ///< Do not make URIs relative - SERD_WRITE_BULK = 1U << 3U, ///< Write output in pages - SERD_WRITE_LAX = 1U << 4U, ///< Tolerate lossy output - SERD_WRITE_TERSE = 1U << 5U, ///< Write terser output without newlines + SERD_WRITE_LAX = 1U << 3U, ///< Tolerate lossy output + SERD_WRITE_TERSE = 1U << 4U, ///< Write terser output without newlines } SerdWriterFlag; /// Bitwise OR of #SerdWriterFlag values @@ -48,12 +48,12 @@ typedef uint32_t SerdWriterFlags; /// Create a new RDF writer SERD_API SerdWriter* ZIX_ALLOCATED -serd_writer_new(SerdWorld* ZIX_NONNULL world, - SerdSyntax syntax, - SerdWriterFlags flags, - SerdEnv* ZIX_NONNULL env, - SerdWriteFunc ZIX_NONNULL ssink, - void* ZIX_NULLABLE stream); +serd_writer_new(SerdWorld* ZIX_NONNULL world, + SerdSyntax syntax, + SerdWriterFlags flags, + SerdEnv* ZIX_NONNULL env, + SerdOutputStream* ZIX_NONNULL output, + size_t block_size); /// Free `writer` SERD_API void |