From b7948f8c9ad54c30e2579fd5da4626c6f3de325a Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 28 Jun 2020 23:26:48 +0200 Subject: WIP: Make Reader always read from a ByteSource --- include/serd/serd.h | 104 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 32 deletions(-) (limited to 'include/serd/serd.h') diff --git a/include/serd/serd.h b/include/serd/serd.h index 61ae6099..e36dd24b 100644 --- a/include/serd/serd.h +++ b/include/serd/serd.h @@ -105,9 +105,6 @@ typedef struct SerdWriterImpl SerdWriter; /// An interface that receives a stream of RDF data typedef struct SerdSinkImpl SerdSink; -/// A sink for bytes that receives string output -typedef struct SerdByteSinkImpl SerdByteSink; - /// Return status code typedef enum { SERD_SUCCESS, ///< No error @@ -123,6 +120,7 @@ typedef enum { SERD_ERR_NO_DATA, ///< Unexpected end of input SERD_ERR_BAD_TEXT, ///< Invalid text encoding SERD_ERR_BAD_WRITE, ///< Error writing to file/stream + SERD_ERR_BAD_CALL, ///< Invalid call } SerdStatus; /// RDF syntax type @@ -371,10 +369,13 @@ serd_base64_decode(const char* SERD_NONNULL str, /** @} - @defgroup serd_streams Byte Streams + @defgroup serd_byte_source Byte Source @{ */ +/// A source for bytes that provides text input +typedef struct SerdByteSourceImpl SerdByteSource; + /** Function to detect I/O stream errors. @@ -402,7 +403,69 @@ typedef size_t (*SerdReadFunc)(void* SERD_NONNULL buf, void* SERD_NONNULL stream); /** - Sink function for raw string output. + 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 block_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 block_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 serd 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 Function called with bytes to consume. + @param error_func Stream error function with `ferror` semantics. + @param stream Context parameter passed to `read_func` and `error_func`. + @param name Optional name of stream for error messages (string or URI). + @param block_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, + void* SERD_NULLABLE stream, + const SerdNode* SERD_NULLABLE name, + size_t block_size); + +/// Free `source` +SERD_API +void +serd_byte_source_free(SerdByteSource* SERD_NULLABLE source); + +/** + @} + @defgroup serd_byte_sink Byte Sink + @{ +*/ + +/// A sink for bytes that receives text output +typedef struct SerdByteSinkImpl SerdByteSink; + +/** + Sink function for raw string output Identical semantics to `fwrite`, but may set errno for more informative error reporting than supported by SerdStreamErrorFunc. @@ -1241,37 +1304,14 @@ 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 + Read a single "chunk" of data during an incremental read. This function will read a single top level description, and return. This may be a directive, statement, or several statements; essentially it reads -- cgit v1.2.1