diff options
author | David Robillard <d@drobilla.net> | 2021-08-14 01:51:55 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2022-01-28 21:57:07 -0500 |
commit | b3892cb6e4963e1bbeb346a8124101b7c3cf379b (patch) | |
tree | 4800918b6f4db5ce0d0f4802988c1935996d6ba3 /include | |
parent | 0e739f34801ff6810064a8fac570f6be2b61ae70 (diff) | |
download | serd-b3892cb6e4963e1bbeb346a8124101b7c3cf379b.tar.gz serd-b3892cb6e4963e1bbeb346a8124101b7c3cf379b.tar.bz2 serd-b3892cb6e4963e1bbeb346a8124101b7c3cf379b.zip |
Simplify input stream API
More or less the same rationale as the previous commit, but for reading. This
makes for nice symmetry with writing, at the cost of a slightly more annoying
reader interface since the source doesn't know its block size or name.
Diffstat (limited to 'include')
-rw-r--r-- | include/serd/serd.h | 117 |
1 files changed, 70 insertions, 47 deletions
diff --git a/include/serd/serd.h b/include/serd/serd.h index db7520d9..6324c06e 100644 --- a/include/serd/serd.h +++ b/include/serd/serd.h @@ -2183,67 +2183,77 @@ serd_node_to_syntax(const SerdNode* SERD_NONNULL node, /** @} - @defgroup serd_byte_source Byte Source + @defgroup serd_input_stream Input Streams + + 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. + @{ */ -/// A source for bytes that provides text input -typedef struct SerdByteSourceImpl SerdByteSource; +/// An input stream that produces bytes +typedef struct { + void* SERD_NULLABLE stream; ///< Opaque parameter for functions + SerdReadFunc SERD_NULLABLE read; ///< Read bytes to input + SerdStreamErrorFunc SERD_NONNULL error; ///< Stream error accessor + SerdStreamCloseFunc SERD_NULLABLE close; ///< Close input +} SerdInputStream; /** - Create a new byte source that reads from a string. + 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. - @param string Null-terminated UTF-8 string to read from. - @param name Optional name of stream for error messages (string or URI). + @return An opened input stream, or all zeros on error. */ -SERD_API -SerdByteSource* SERD_ALLOCATED -serd_byte_source_new_string(const char* SERD_NONNULL string, - const SerdNode* SERD_NULLABLE name); +SERD_CONST_API +SerdInputStream +serd_open_input_stream(SerdReadFunc SERD_NONNULL read_func, + SerdStreamErrorFunc SERD_NONNULL error_func, + SerdStreamCloseFunc SERD_NULLABLE close_func, + void* SERD_NULLABLE stream); /** - Create a new byte source that reads from a file. + Open a stream that reads from a string. - An arbitrary `FILE*` can be used via serd_byte_source_new_function() as - well, this is just a convenience function that opens the file properly, sets - flags for optimized I/O if possible, and automatically sets the name of the - source to the file path. + 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 path Path of file to open and read from. - @param page_size Number of bytes to read per call. + @param position Pointer to a valid string pointer for use as stream state. + @return An opened input stream, or all zeros on error. */ -SERD_API -SerdByteSource* SERD_ALLOCATED -serd_byte_source_new_filename(const char* SERD_NONNULL path, size_t page_size); +SERD_CONST_API +SerdInputStream +serd_open_input_string(const char* SERD_NONNULL* SERD_NONNULL position); /** - Create a new byte source that reads from a user-specified function + Open a stream that reads from a file. - The `stream` will be passed to the `read_func`, which is compatible with the - standard C `fread` if `stream` is a `FILE*`. Note that the reader only ever - reads individual bytes at a time, that is, the `size` parameter will always - be 1 (but `nmemb` may be higher). + 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 read_func Stream read function, like `fread`. - @param error_func Stream error function, like `ferror`. - @param close_func Stream close function, like `fclose`. - @param stream Context parameter passed to `read_func` and `error_func`. - @param name Optional name of stream for error messages (string or URI). - @param page_size Number of bytes to read per call. + @param path Path of file to open and read from. */ SERD_API -SerdByteSource* SERD_ALLOCATED -serd_byte_source_new_function(SerdReadFunc SERD_NONNULL read_func, - SerdStreamErrorFunc SERD_NONNULL error_func, - SerdStreamCloseFunc SERD_NULLABLE close_func, - void* SERD_NULLABLE stream, - const SerdNode* SERD_NULLABLE name, - size_t page_size); +SerdInputStream +serd_open_input_file(const char* SERD_NONNULL path); + +/** + Close an input stream. -/// Free `source` + 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 -void -serd_byte_source_free(SerdByteSource* SERD_NULLABLE source); +SerdStatus +serd_close_input(SerdInputStream* SERD_NULLABLE input); /** @} @@ -2332,11 +2342,24 @@ serd_reader_new(SerdWorld* SERD_NONNULL world, const SerdSink* SERD_NONNULL sink, size_t stack_size); -/// Prepare to read from a byte source +/** + Prepare to read some input. + + 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(SerdReader* SERD_NONNULL reader, - SerdByteSource* SERD_NONNULL byte_source); +serd_reader_start(SerdReader* SERD_NONNULL reader, + SerdInputStream* SERD_NONNULL input, + const SerdNode* SERD_NULLABLE input_name, + size_t block_size); /** Read a single "chunk" of data during an incremental read. @@ -2473,11 +2496,11 @@ SerdOutputStream serd_open_output_buffer(SerdBuffer* SERD_NONNULL buffer); /** - Create a new byte sink that writes to a file. + 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 readingn with serd, - and sets flags for optimized I/O if possible. + 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. */ |