aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-08-13 19:31:26 -0400
committerDavid Robillard <d@drobilla.net>2023-12-02 18:49:08 -0500
commit828c1018f38bab9a930cecce64646366d051d39b (patch)
tree38a60777520efb17017ed62fe3b299ba94aaccf2 /include
parenta083c64f506175029280ff76defa0ad7d7ae2ea0 (diff)
downloadserd-828c1018f38bab9a930cecce64646366d051d39b.tar.gz
serd-828c1018f38bab9a930cecce64646366d051d39b.tar.bz2
serd-828c1018f38bab9a930cecce64646366d051d39b.zip
Simplify output stream API
Diffstat (limited to 'include')
-rw-r--r--include/serd/buffer.h4
-rw-r--r--include/serd/output_stream.h94
-rw-r--r--include/serd/serd.h1
-rw-r--r--include/serd/stream.h20
-rw-r--r--include/serd/writer.h20
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