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 /src/byte_source.c | |
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 'src/byte_source.c')
-rw-r--r-- | src/byte_source.c | 155 |
1 files changed, 29 insertions, 126 deletions
diff --git a/src/byte_source.c b/src/byte_source.c index 567beee8..47753d83 100644 --- a/src/byte_source.c +++ b/src/byte_source.c @@ -17,21 +17,13 @@ #include "byte_source.h" #include "caret.h" -#include "serd_config.h" #include "system.h" #include "serd/serd.h" -#include <sys/stat.h> - -#if USE_POSIX_FADVISE && USE_FILENO -# include <fcntl.h> -#endif - #include <assert.h> #include <stdbool.h> #include <stdint.h> -#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -39,21 +31,21 @@ SerdStatus serd_byte_source_page(SerdByteSource* const source) { uint8_t* const buf = - (source->page_size > 1 ? source->file_buf : &source->read_byte); + (source->block_size > 1 ? source->block : &source->read_byte); const size_t n_read = - source->read_func(buf, 1, source->page_size, source->stream); + source->in->read(buf, 1, source->block_size, source->in->stream); source->buf_size = n_read; source->read_head = 0; source->eof = false; - if (n_read < source->page_size) { + if (n_read < source->block_size) { buf[n_read] = '\0'; if (n_read == 0) { source->eof = true; - return (source->error_func(source->stream) ? SERD_ERR_UNKNOWN - : SERD_FAILURE); + return (source->in->error(source->in->stream) ? SERD_ERR_UNKNOWN + : SERD_FAILURE); } } @@ -63,43 +55,34 @@ serd_byte_source_page(SerdByteSource* const source) static void serd_byte_source_init_buffer(SerdByteSource* const source) { - if (source->page_size > 1) { - source->file_buf = (uint8_t*)serd_allocate_buffer(source->page_size); - source->read_buf = source->file_buf; - memset(source->file_buf, '\0', source->page_size); + if (source->block_size > 1) { + source->block = (uint8_t*)serd_allocate_buffer(source->block_size); + source->read_buf = source->block; + memset(source->block, '\0', source->block_size); } else { source->read_buf = &source->read_byte; } } SerdByteSource* -serd_byte_source_new_function(const SerdReadFunc read_func, - const SerdStreamErrorFunc error_func, - const SerdStreamCloseFunc close_func, - void* const stream, - const SerdNode* const name, - const size_t page_size) +serd_byte_source_new_input(SerdInputStream* const input, + const SerdNode* const name, + const size_t block_size) { - assert(read_func); - assert(error_func); + assert(input); - if (!page_size) { + if (!block_size || !input->stream) { return NULL; } SerdByteSource* source = (SerdByteSource*)calloc(1, sizeof(SerdByteSource)); - source->read_func = read_func; - source->error_func = error_func; - source->close_func = close_func; - source->stream = stream; - source->page_size = page_size; - source->buf_size = page_size; - source->type = FROM_FUNCTION; - source->name = - name ? serd_node_copy(name) : serd_new_string(SERD_STRING("func")); + name ? serd_node_copy(name) : serd_new_string(SERD_STRING("input")); + source->in = input; + source->block_size = block_size; + source->buf_size = block_size; source->caret.file = source->name; source->caret.line = 1u; source->caret.col = 1u; @@ -109,107 +92,27 @@ serd_byte_source_new_function(const SerdReadFunc read_func, return source; } -static bool -is_directory(const char* const path) -{ -#ifdef _MSC_VER - struct stat st; - return !stat(path, &st) && (st.st_mode & _S_IFDIR); -#else - struct stat st; - return !stat(path, &st) && S_ISDIR(st.st_mode); -#endif -} - -SerdByteSource* -serd_byte_source_new_filename(const char* const path, const size_t page_size) +void +serd_byte_source_free(SerdByteSource* const source) { - assert(path); - - if (page_size == 0 || is_directory(path)) { - return NULL; - } + if (source) { + if (source->block_size > 1) { + serd_free_aligned(source->block); + } - FILE* const fd = fopen(path, "rb"); - if (!fd) { - return NULL; + serd_node_free(source->name); + free(source); } - - SerdByteSource* source = (SerdByteSource*)calloc(1, sizeof(SerdByteSource)); - - source->read_func = (SerdReadFunc)fread; - source->error_func = (SerdStreamErrorFunc)ferror; - source->close_func = (SerdStreamCloseFunc)fclose; - source->stream = fd; - source->page_size = page_size; - source->buf_size = page_size; - - source->name = serd_new_file_uri(SERD_STRING(path), SERD_EMPTY_STRING()); - source->type = FROM_FILENAME; - - source->caret.file = source->name; - source->caret.line = 1u; - source->caret.col = 1u; - - serd_byte_source_init_buffer(source); - -#if USE_POSIX_FADVISE && USE_FILENO - posix_fadvise(fileno(fd), 0, 0, POSIX_FADV_SEQUENTIAL); -#endif - - return source; -} - -SerdByteSource* -serd_byte_source_new_string(const char* const string, - const SerdNode* const name) -{ - assert(string); - - SerdByteSource* source = (SerdByteSource*)calloc(1, sizeof(SerdByteSource)); - - source->page_size = 1; - source->read_buf = (const uint8_t*)string; - source->type = FROM_STRING; - - source->name = - name ? serd_node_copy(name) : serd_new_string(SERD_STRING("string")); - - source->caret.file = source->name; - source->caret.line = 1u; - source->caret.col = 1u; - - return source; } SerdStatus serd_byte_source_prepare(SerdByteSource* const source) { source->prepared = true; - if (source->type != FROM_STRING) { - if (source->page_size > 1) { - return serd_byte_source_page(source); - } - return serd_byte_source_advance(source); + if (source->block_size > 1) { + return serd_byte_source_page(source); } - return SERD_SUCCESS; -} - -void -serd_byte_source_free(SerdByteSource* const source) -{ - if (source) { - if (source->close_func) { - source->close_func(source->stream); - } - - if (source->page_size > 1) { - serd_free_aligned(source->file_buf); - } - - serd_node_free(source->name); - free(source); - } + return serd_byte_source_advance(source); } |