diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/serd/input_stream.h | 90 | ||||
-rw-r--r-- | include/serd/reader.h | 37 | ||||
-rw-r--r-- | include/serd/serd.h | 1 | ||||
-rw-r--r-- | include/serd/stream.h | 32 |
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); + +/** @} */ |