diff options
author | David Robillard <d@drobilla.net> | 2020-06-28 23:26:48 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2022-01-13 23:05:24 -0500 |
commit | 55e28966226268a57edb07419ac419ef53ac437d (patch) | |
tree | 317a3e50480f97a415dae5a7d096726a0c730c0a /include | |
parent | b98bd7a32cf4302e0a210dd8558edd3ab2088525 (diff) | |
download | serd-55e28966226268a57edb07419ac419ef53ac437d.tar.gz serd-55e28966226268a57edb07419ac419ef53ac437d.tar.bz2 serd-55e28966226268a57edb07419ac419ef53ac437d.zip |
Make Reader always read from a ByteSource
Diffstat (limited to 'include')
-rw-r--r-- | include/serd/serd.h | 121 |
1 files changed, 86 insertions, 35 deletions
diff --git a/include/serd/serd.h b/include/serd/serd.h index 362de28d..82292389 100644 --- a/include/serd/serd.h +++ b/include/serd/serd.h @@ -206,6 +206,7 @@ typedef enum { SERD_ERR_BAD_TEXT, ///< Invalid text encoding SERD_ERR_BAD_WRITE, ///< Error writing to file/stream SERD_ERR_NO_DATA, ///< Unexpected end of input + SERD_ERR_BAD_CALL, ///< Invalid call } SerdStatus; /** @@ -275,15 +276,6 @@ serd_canonical_path(const char* SERD_NONNULL path); */ /** - Function to detect I/O stream errors. - - Identical semantics to `ferror`. - - @return Non-zero if `stream` has encountered an error. -*/ -typedef int (*SerdStreamErrorFunc)(void* SERD_NONNULL stream); - -/** Source function for raw string input. Identical semantics to `fread`, but may set errno for more informative error @@ -318,6 +310,24 @@ typedef size_t (*SerdWriteFunc)(const void* SERD_NONNULL buf, void* SERD_NONNULL stream); /** + Function to detect I/O stream errors. + + Identical semantics to `ferror`. + + @return Non-zero if `stream` has encountered an error. +*/ +typedef int (*SerdStreamErrorFunc)(void* SERD_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* SERD_NONNULL stream); + +/** @} @defgroup serd_syntax Syntax Utilities @{ @@ -1473,6 +1483,70 @@ serd_env_write_prefixes(const SerdEnv* SERD_NONNULL env, /** @} + @defgroup serd_byte_source Byte Source + @{ +*/ + +/// A source for bytes that provides text input +typedef struct SerdByteSourceImpl SerdByteSource; + +/** + Create a new byte source that reads from a string. + + @param string Null-terminated UTF-8 string to read from. + @param name Optional name of stream for error messages (string or URI). +*/ +SERD_API +SerdByteSource* SERD_ALLOCATED +serd_byte_source_new_string(const char* SERD_NONNULL string, + const SerdNode* SERD_NULLABLE name); + +/** + Create a new byte source that reads from a file. + + 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. + + @param path Path of file to open and read from. + @param page_size Number of bytes to read per call. +*/ +SERD_API +SerdByteSource* SERD_ALLOCATED +serd_byte_source_new_filename(const char* SERD_NONNULL path, size_t page_size); + +/** + Create a new byte source that reads from a user-specified function + + 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). + + @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. +*/ +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); + +/// Free `source` +SERD_API +void +serd_byte_source_free(SerdByteSource* SERD_NULLABLE source); + +/** + @} @defgroup serd_reader Reader @{ */ @@ -1511,34 +1585,11 @@ void serd_reader_add_blank_prefix(SerdReader* SERD_NONNULL reader, const char* SERD_NULLABLE prefix); -/// Prepare to read from the file at a local file `uri` -SERD_API -SerdStatus -serd_reader_start_file(SerdReader* SERD_NONNULL reader, - const char* SERD_NONNULL uri, - bool bulk); - -/** - Prepare to read from a stream. - - The `read_func` is guaranteed to only be called for `page_size` elements - with size 1 (i.e. `page_size` bytes). -*/ -SERD_API -SerdStatus -serd_reader_start_stream(SerdReader* SERD_NONNULL reader, - SerdReadFunc SERD_NONNULL read_func, - SerdStreamErrorFunc SERD_NONNULL error_func, - void* SERD_NONNULL stream, - const SerdNode* SERD_NULLABLE name, - size_t page_size); - -/// Prepare to read from a string +/// Prepare to read from a byte source SERD_API SerdStatus -serd_reader_start_string(SerdReader* SERD_NONNULL reader, - const char* SERD_NONNULL utf8, - const SerdNode* SERD_NULLABLE name); +serd_reader_start(SerdReader* SERD_NONNULL reader, + SerdByteSource* SERD_NONNULL byte_source); /** Read a single "chunk" of data during an incremental read. |