aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-06-28 23:26:48 +0200
committerDavid Robillard <d@drobilla.net>2023-12-02 18:49:08 -0500
commita083c64f506175029280ff76defa0ad7d7ae2ea0 (patch)
tree5e666749e352659d225d9c45c60bee06bd2bfe5c /include
parent20eb7727954f9d8b7164146895904bbe595f5932 (diff)
downloadserd-a083c64f506175029280ff76defa0ad7d7ae2ea0.tar.gz
serd-a083c64f506175029280ff76defa0ad7d7ae2ea0.tar.bz2
serd-a083c64f506175029280ff76defa0ad7d7ae2ea0.zip
Simplify input stream API
Diffstat (limited to 'include')
-rw-r--r--include/serd/input_stream.h90
-rw-r--r--include/serd/reader.h37
-rw-r--r--include/serd/serd.h1
-rw-r--r--include/serd/stream.h32
4 files changed, 136 insertions, 24 deletions
diff --git a/include/serd/input_stream.h b/include/serd/input_stream.h
new file mode 100644
index 00000000..cc63e694
--- /dev/null
+++ b/include/serd/input_stream.h
@@ -0,0 +1,90 @@
+// Copyright 2011-2022 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#ifndef SERD_INPUT_STREAM_H
+#define SERD_INPUT_STREAM_H
+
+#include "serd/attributes.h"
+#include "serd/status.h"
+#include "serd/stream.h"
+#include "zix/attributes.h"
+
+SERD_BEGIN_DECLS
+
+/**
+ @defgroup serd_input_stream Input Streams
+ @ingroup serd_reading_writing
+
+ An input stream is used for reading input as a raw stream of bytes. It is
+ compatible with standard C `FILE` streams, but allows different functions to
+ be provided for things like reading from a buffer or a socket.
+
+ @{
+*/
+
+/// An input stream that produces bytes
+typedef struct {
+ void* ZIX_NULLABLE stream; ///< Opaque parameter for functions
+ SerdReadFunc ZIX_NONNULL read; ///< Read bytes from input
+ SerdErrorFunc ZIX_NULLABLE error; ///< Stream error accessor
+ SerdCloseFunc ZIX_NULLABLE close; ///< Close input
+} SerdInputStream;
+
+/**
+ Open a stream that reads from a provided function.
+
+ @param read_func Function to read input.
+ @param error_func Function used to detect errors.
+ @param close_func Function to close the stream after reading is done.
+ @param stream Opaque stream parameter for functions.
+
+ @return An opened input stream, or all zeros on error.
+*/
+SERD_CONST_API SerdInputStream
+serd_open_input_stream(SerdReadFunc ZIX_NONNULL read_func,
+ SerdErrorFunc ZIX_NONNULL error_func,
+ SerdCloseFunc ZIX_NULLABLE close_func,
+ void* ZIX_NULLABLE stream);
+
+/**
+ Open a stream that reads from a string.
+
+ The string pointer that position points to must remain valid until the
+ stream is closed. This pointer serves as the internal stream state and will
+ be mutated as the stream is used.
+
+ @param position Pointer to a valid string pointer for use as stream state.
+ @return An opened input stream, or all zeros on error.
+*/
+SERD_CONST_API SerdInputStream
+serd_open_input_string(const char* ZIX_NONNULL* ZIX_NONNULL position);
+
+/**
+ Open a stream that reads from a file.
+
+ An arbitrary `FILE*` can be used with serd_open_input_stream() as well, this
+ convenience function opens the file properly for reading with serd, and sets
+ flags for optimized I/O if possible.
+
+ @param path Path of file to open and read from.
+*/
+SERD_API SerdInputStream
+serd_open_input_file(const char* ZIX_NONNULL path);
+
+/**
+ Close an input stream.
+
+ This will call the close function, and reset the stream internally so that
+ no further reads can be made. For convenience, this is safe to call on
+ NULL, and safe to call several times on the same input.
+*/
+SERD_API SerdStatus
+serd_close_input(SerdInputStream* ZIX_NULLABLE input);
+
+/**
+ @}
+*/
+
+SERD_END_DECLS
+
+#endif // SERD_INPUT_STREAM_H
diff --git a/include/serd/reader.h b/include/serd/reader.h
index c79d6a44..4c669342 100644
--- a/include/serd/reader.h
+++ b/include/serd/reader.h
@@ -5,15 +5,14 @@
#define SERD_READER_H
#include "serd/attributes.h"
+#include "serd/input_stream.h"
#include "serd/node.h"
#include "serd/sink.h"
#include "serd/status.h"
-#include "serd/stream.h"
#include "serd/syntax.h"
#include "serd/world.h"
#include "zix/attributes.h"
-#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
@@ -56,31 +55,23 @@ SERD_API void
serd_reader_add_blank_prefix(SerdReader* ZIX_NONNULL reader,
const char* ZIX_NULLABLE prefix);
-/// Prepare to read from the file at a local file `uri`
-SERD_API SerdStatus
-serd_reader_start_file(SerdReader* ZIX_NONNULL reader,
- const char* ZIX_NONNULL uri,
- bool bulk);
-
/**
- Prepare to read from a stream.
+ Prepare to read some input.
- The `read_func` is guaranteed to only be called for `page_size` elements
- with size 1 (i.e. `page_size` bytes).
+ This sets up the reader to read from the given input, but will not read any
+ bytes from it. This should be followed by serd_reader_read_chunk() or
+ serd_reader_read_document() to actually read the input.
+
+ @param reader The reader.
+ @param input An opened input stream to read from.
+ @param input_name The name of the input stream for error messages.
+ @param block_size The number of bytes to read from the stream at once.
*/
SERD_API SerdStatus
-serd_reader_start_stream(SerdReader* ZIX_NONNULL reader,
- SerdReadFunc ZIX_NONNULL read_func,
- SerdStreamErrorFunc ZIX_NONNULL error_func,
- void* ZIX_NONNULL stream,
- const SerdNode* ZIX_NULLABLE name,
- size_t page_size);
-
-/// Prepare to read from a string
-SERD_API SerdStatus
-serd_reader_start_string(SerdReader* ZIX_NONNULL reader,
- const char* ZIX_NONNULL utf8,
- const SerdNode* ZIX_NULLABLE name);
+serd_reader_start(SerdReader* ZIX_NONNULL reader,
+ SerdInputStream* ZIX_NONNULL input,
+ const SerdNode* ZIX_NULLABLE input_name,
+ size_t block_size);
/**
Read a single "chunk" of data during an incremental read.
diff --git a/include/serd/serd.h b/include/serd/serd.h
index 5b13f676..58c8e7ec 100644
--- a/include/serd/serd.h
+++ b/include/serd/serd.h
@@ -78,6 +78,7 @@
@{
*/
+#include "serd/input_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 4b3582f5..f59e2c9d 100644
--- a/include/serd/stream.h
+++ b/include/serd/stream.h
@@ -33,10 +33,19 @@ SERD_BEGIN_DECLS
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
- informative error reporting than supported by #SerdStreamErrorFunc.
+ informative error reporting than supported by #SerdErrorFunc.
@param buf Output buffer.
@param size Size of a single element of data in bytes (always 1).
@@ -67,6 +76,27 @@ typedef size_t (*SerdWriteFunc)(const void* ZIX_NONNULL buf,
void* ZIX_NONNULL stream);
/**
+ Function for detecting I/O stream errors.
+
+ This has identical semantics to `ferror`.
+
+ @return Non-zero if `stream` has encountered an error.
+*/
+typedef int (*SerdErrorFunc)(void* ZIX_NONNULL stream);
+
+/**
+ Function for closing an I/O stream.
+
+ This has identical semantics to `fclose`. Note that when writing, this may
+ flush the stream which can cause errors, including errors caused by previous
+ writes that appeared successful at the time. Therefore it is necessary to
+ check the return value of this function to properly detect write errors.
+
+ @return Non-zero if `stream` has encountered an error.
+*/
+typedef int (*SerdCloseFunc)(void* ZIX_NONNULL stream);
+
+/**
@}
*/