aboutsummaryrefslogtreecommitdiffstats
path: root/src/byte_source.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-08-14 01:51:55 -0400
committerDavid Robillard <d@drobilla.net>2022-01-28 21:57:07 -0500
commitb3892cb6e4963e1bbeb346a8124101b7c3cf379b (patch)
tree4800918b6f4db5ce0d0f4802988c1935996d6ba3 /src/byte_source.c
parent0e739f34801ff6810064a8fac570f6be2b61ae70 (diff)
downloadserd-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.c155
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);
}