diff options
Diffstat (limited to 'src/byte_source.c')
-rw-r--r-- | src/byte_source.c | 173 |
1 files changed, 103 insertions, 70 deletions
diff --git a/src/byte_source.c b/src/byte_source.c index 90af28ee..efe4cb04 100644 --- a/src/byte_source.c +++ b/src/byte_source.c @@ -21,117 +21,150 @@ #include "serd/serd.h" #include <stdbool.h> -#include <stdint.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> -SerdStatus -serd_byte_source_page(SerdByteSource* source) +SerdByteSource* +serd_byte_source_new_string(const char* string, const SerdNode* name) { - uint8_t* const buf = (source->page_size > 1 - ? source->file_buf - : &source->read_byte); + SerdByteSource* source = (SerdByteSource*)calloc(1, sizeof(SerdByteSource)); - const size_t n_read = source->read_func( - buf, 1, source->page_size, source->stream); + source->page_size = 1; + source->name = name ? serd_node_copy(name) : serd_new_string("string"); + source->read_buf = (const uint8_t*)string; + source->type = FROM_STRING; - source->buf_size = n_read; - source->read_head = 0; - source->eof = false; + const SerdCursor cur = {source->name, 1, 1}; + source->cur = cur; - if (n_read < source->page_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; +} + +SerdByteSource* +serd_byte_source_new_filename(const char* path, size_t block_size) +{ + if (!path || !block_size) { + return NULL; } - return SERD_SUCCESS; + FILE* fd = fopen(path, "rb"); + if (!fd) { + return NULL; + } + + 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 = block_size; + source->buf_size = block_size; + source->name = serd_new_file_uri(path, NULL); + source->type = FROM_FILENAME; + + const SerdCursor cur = { source->name, 1, 1 }; + source->cur = cur; + + if (block_size > 1) { + source->file_buf = (uint8_t*)serd_allocate_buffer(block_size); + source->read_buf = source->file_buf; + memset(source->file_buf, '\0', block_size); + } else { + source->read_buf = &source->read_byte; + } + + return source; } -SerdStatus -serd_byte_source_open_source(SerdByteSource* source, - SerdReadFunc read_func, - SerdStreamErrorFunc error_func, - SerdStreamCloseFunc close_func, - void* stream, - const SerdNode* name, - size_t page_size) +SerdByteSource* +serd_byte_source_new_function(SerdReadFunc read_func, + SerdStreamErrorFunc error_func, + void* stream, + const SerdNode* name, + size_t block_size) { - assert(page_size > 0); - memset(source, '\0', sizeof(*source)); + if (!read_func || !block_size) { + 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->close_func = close_func; FIXME source->stream = stream; - source->page_size = page_size; - source->buf_size = page_size; - source->name = serd_node_copy(name); - source->from_stream = true; + source->page_size = block_size; + source->buf_size = block_size; + source->name = name ? serd_node_copy(name) : serd_new_string("func"); + source->type = FROM_FUNCTION; const SerdCursor cur = { source->name, 1, 1 }; source->cur = cur; - if (page_size > 1) { - source->file_buf = (uint8_t*)serd_allocate_buffer(page_size); + if (block_size > 1) { + source->file_buf = (uint8_t*)serd_allocate_buffer(block_size); source->read_buf = source->file_buf; - memset(source->file_buf, '\0', page_size); + memset(source->file_buf, '\0', block_size); } else { source->read_buf = &source->read_byte; } - return SERD_SUCCESS; + return source; } -SerdStatus -serd_byte_source_prepare(SerdByteSource* source) +void +serd_byte_source_free(SerdByteSource* source) { - if (source->page_size == 0) { - return SERD_FAILURE; - } - - source->prepared = true; - if (source->from_stream) { + if (source) { + if (source->close_func) { + source->close_func(source->stream); + } if (source->page_size > 1) { - return serd_byte_source_page(source); - } else if (source->from_stream) { - return serd_byte_source_advance(source); + free(source->file_buf); } + serd_node_free(source->name); + free(source); } - return SERD_SUCCESS; } SerdStatus -serd_byte_source_open_string(SerdByteSource* source, - const char* utf8, - const SerdNode* name) +serd_byte_source_page(SerdByteSource* source) { - memset(source, '\0', sizeof(*source)); + uint8_t* const buf = (source->page_size > 1 + ? source->file_buf + : &source->read_byte); - source->page_size = 1; - source->name = name ? serd_node_copy(name) : serd_new_string("string"); - source->read_buf = (const uint8_t*)utf8; + const size_t n_read = source->read_func( + buf, 1, source->page_size, source->stream); - const SerdCursor cur = {source->name, 1, 1}; - source->cur = cur; + source->buf_size = n_read; + source->read_head = 0; + source->eof = false; + + if (n_read < source->page_size) { + buf[n_read] = '\0'; + if (n_read == 0) { + source->eof = true; + return (source->error_func(source->stream) + ? SERD_ERR_UNKNOWN : SERD_FAILURE); + } + } return SERD_SUCCESS; } SerdStatus -serd_byte_source_close(SerdByteSource* source) +serd_byte_source_prepare(SerdByteSource* source) { - SerdStatus st = SERD_SUCCESS; - if (source->close_func) { - st = source->close_func(source->stream) ? SERD_ERR_UNKNOWN - : SERD_SUCCESS; - } - if (source->page_size > 1) { - free(source->file_buf); + source->prepared = true; + if (source->type != FROM_STRING) { + if (source->page_size > 1) { + return serd_byte_source_page(source); + } else { + return serd_byte_source_advance(source); + } } - serd_node_free(source->name); - memset(source, '\0', sizeof(*source)); - return st; + return SERD_SUCCESS; } |