From ddd073f0a1c47e5dbba2efd04617862e49171bed Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 25 Feb 2011 07:28:10 +0000 Subject: Abstract common read state tracking code (SerdReadState) to make user code less tedious. git-svn-id: http://svn.drobilla.net/serd/trunk@110 490d8e77-9747-427b-9fa3-0b8f29cee8a0 --- src/reader.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ src/serdi.c | 89 +++++++++++++++------------------------------------ 2 files changed, 118 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/reader.c b/src/reader.c index e0790e39..b19ffcdc 100644 --- a/src/reader.c +++ b/src/reader.c @@ -41,9 +41,6 @@ #define STACK_PAGE_SIZE 4096 #define READ_BUF_LEN 4096 -#ifndef NDEBUG -#define STACK_DEBUG 1 -#endif typedef struct { const uint8_t* filename; @@ -98,12 +95,18 @@ struct SerdReaderImpl { int32_t read_head; ///< Offset into read_buf bool from_file; ///< True iff reading from @ref fd bool eof; -#ifdef STACK_DEBUG +#ifdef SUIL_STACK_CHECK Ref* alloc_stack; ///< Stack of push offsets size_t n_allocs; ///< Number of stack pushes #endif }; +struct SerdReadStateImpl { + SerdEnv env; + SerdNode base_uri_node; + SerdURI base_uri; +}; + typedef enum { SERD_SUCCESS = 0, ///< Completed successfully SERD_FAILURE = 1, ///< Non-fatal failure @@ -202,7 +205,7 @@ eat_string(SerdReader reader, const char* str, unsigned n) } } -#ifdef STACK_DEBUG +#ifdef SUIL_STACK_CHECK static inline bool stack_is_top_string(SerdReader reader, Ref ref) { @@ -229,7 +232,7 @@ push_string(SerdReader reader, const char* c_str, size_t n_bytes) str->n_bytes = n_bytes; str->n_chars = n_bytes - 1; memcpy(str->buf, c_str, n_bytes); -#ifdef STACK_DEBUG +#ifdef SUIL_STACK_CHECK reader->alloc_stack = realloc(reader->alloc_stack, sizeof(uint8_t*) * (++reader->n_allocs)); reader->alloc_stack[reader->n_allocs - 1] = (mem - reader->stack.buf); @@ -249,7 +252,7 @@ deref(SerdReader reader, const Ref ref) static inline void push_byte(SerdReader reader, Ref ref, const uint8_t c) { - #ifdef STACK_DEBUG + #ifdef SUIL_STACK_CHECK assert(stack_is_top_string(reader, ref)); #endif serd_stack_push(&reader->stack, 1); @@ -273,7 +276,7 @@ pop_string(SerdReader reader, Ref ref) || ref == reader->rdf_rest.value) { return; } - #ifdef STACK_DEBUG + #ifdef SUIL_STACK_CHECK if (!stack_is_top_string(reader, ref)) { fprintf(stderr, "attempt to pop non-top string %s\n", deref(reader, ref)->buf); @@ -1377,7 +1380,7 @@ serd_reader_new(SerdSyntax syntax, me->read_buf = 0; me->read_head = 0; me->eof = false; -#ifdef STACK_DEBUG +#ifdef SERD_STACK_CHECK me->alloc_stack = 0; me->n_allocs = 0; #endif @@ -1401,7 +1404,7 @@ serd_reader_free(SerdReader reader) pop_string(me, me->rdf_rest.value); pop_string(me, me->rdf_first.value); -#ifdef STACK_DEBUG +#ifdef SERD_STACK_CHECK free(me->alloc_stack); #endif free(me->stack.buf); @@ -1458,3 +1461,82 @@ serd_reader_read_string(SerdReader me, const uint8_t* utf8) me->read_buf = NULL; return ret; } + +SERD_API +SerdReadState +serd_read_state_new(SerdEnv env, + const uint8_t* base_uri_str) +{ + SerdReadState state = malloc(sizeof(struct SerdReadStateImpl)); + SerdURI base_base_uri = SERD_URI_NULL; + state->env = env; + state->base_uri_node = serd_node_new_uri_from_string( + base_uri_str, &base_base_uri, &state->base_uri); + return state; +} + +SERD_API +void +serd_read_state_free(SerdReadState state) +{ + serd_node_free(&state->base_uri_node); + free(state); +} + +SERD_API +SerdNode +serd_read_state_get_base_uri(SerdReadState state, + SerdURI* out) +{ + *out = state->base_uri; + return state->base_uri_node; +} + +SERD_API +bool +serd_read_state_set_base_uri(SerdReadState state, + const SerdNode* uri_node) +{ + // Resolve base URI and create a new node and URI for it + SerdURI base_uri; + SerdNode base_uri_node = serd_node_new_uri_from_node( + uri_node, &state->base_uri, &base_uri); + + if (base_uri_node.buf) { + // Replace the current base URI + serd_node_free(&state->base_uri_node); + state->base_uri_node = base_uri_node; + state->base_uri = base_uri; + return true; + } + return false; +} + +SERD_API +bool +serd_read_state_set_prefix(SerdReadState state, + const SerdNode* name, + const SerdNode* uri_node) +{ + if (serd_uri_string_has_scheme(uri_node->buf)) { + // Set prefix to absolute URI + serd_env_add(state->env, name, uri_node); + return true; + } else { + // Resolve relative URI and create a new node and URI for it + SerdURI abs_uri; + SerdNode abs_uri_node = serd_node_new_uri_from_node( + uri_node, &state->base_uri, &abs_uri); + + if (!abs_uri_node.buf) { + return false; + } + + // Set prefix to resolved (absolute) URI + serd_env_add(state->env, name, &abs_uri_node); + serd_node_free(&abs_uri_node); + return true; + } + return false; +} + diff --git a/src/serdi.c b/src/serdi.c index d97cb9f9..7eede1e6 100644 --- a/src/serdi.c +++ b/src/serdi.c @@ -31,38 +31,20 @@ #include "serd-config.h" typedef struct { - SerdWriter writer; - SerdEnv env; - SerdNode base_uri_node; - SerdURI base_uri; + SerdEnv env; + SerdReadState read_state; + SerdWriter writer; } State; -static uint8_t* -copy_string(const uint8_t* str, size_t* n_bytes) -{ - const size_t len = strlen((const char*)str); - uint8_t* const ret = malloc(len + 1); - memcpy(ret, str, len + 1); - *n_bytes = len + 1; - return ret; -} - static bool event_base(void* handle, const SerdNode* uri_node) { State* const state = (State*)handle; - // Resolve base URI and create a new node and URI for it - SerdURI base_uri; - SerdNode base_uri_node = serd_node_new_uri_from_node( - uri_node, &state->base_uri, &base_uri); - - if (base_uri_node.buf) { - // Replace the current base URI - serd_node_free(&state->base_uri_node); - state->base_uri_node = base_uri_node; - state->base_uri = base_uri; + if (serd_read_state_set_base_uri(state->read_state, uri_node)) { + SerdURI base_uri; + serd_read_state_get_base_uri(state->read_state, &base_uri); serd_writer_set_base_uri(state->writer, &base_uri); return true; } @@ -75,23 +57,8 @@ event_prefix(void* handle, const SerdNode* uri_node) { State* const state = (State*)handle; - if (serd_uri_string_has_scheme(uri_node->buf)) { - // Set prefix to absolute URI - serd_env_add(state->env, name, uri_node); - } else { - // Resolve relative URI and create a new node and URI for it - SerdURI abs_uri; - SerdNode abs_uri_node = serd_node_new_uri_from_node( - uri_node, &state->base_uri, &abs_uri); - - if (!abs_uri_node.buf) { - return false; - } - - // Set prefix to resolved (absolute) URI - serd_env_add(state->env, name, &abs_uri_node); - serd_node_free(&abs_uri_node); - } + + serd_read_state_set_prefix(state->read_state, name, uri_node); serd_writer_set_prefix(state->writer, name, uri_node); return true; } @@ -218,20 +185,19 @@ main(int argc, char** argv) } } - uint8_t* base_uri_str = NULL; - size_t base_uri_n_bytes = 0; - SerdURI base_uri; + const uint8_t* base_uri_str = NULL; + SerdURI base_uri; if (a < argc) { // Base URI given on command line const uint8_t* const in_base_uri = (const uint8_t*)argv[a++]; if (!serd_uri_parse((const uint8_t*)in_base_uri, &base_uri)) { fprintf(stderr, "invalid base URI `%s'\n", argv[2]); return 1; } - base_uri_str = copy_string(in_base_uri, &base_uri_n_bytes); + base_uri_str = in_base_uri; } else if (from_file) { // Use input file URI - base_uri_str = copy_string(input, &base_uri_n_bytes); + base_uri_str = input; } else { - base_uri_str = copy_string((const uint8_t*)"", &base_uri_n_bytes); + base_uri_str = (const uint8_t*)""; } if (!serd_uri_parse(base_uri_str, &base_uri)) { @@ -241,22 +207,21 @@ main(int argc, char** argv) FILE* out_fd = stdout; SerdEnv env = serd_env_new(); - SerdStyle output_style = (output_syntax == SERD_NTRIPLES) - ? SERD_STYLE_ASCII - : SERD_STYLE_ABBREVIATED; + SerdStyle output_style = SERD_STYLE_RESOLVED; + if (output_syntax == SERD_NTRIPLES) { + output_style |= SERD_STYLE_ASCII; + } else { + output_style |= SERD_STYLE_ABBREVIATED; + } - output_style |= SERD_STYLE_RESOLVED; + SerdReadState read_state = serd_read_state_new(env, base_uri_str); - const SerdNode base_uri_node = { SERD_URI, - base_uri_n_bytes, - base_uri_n_bytes - 1, - base_uri_str }; + serd_read_state_get_base_uri(read_state, &base_uri); - State state = { - serd_writer_new(output_syntax, output_style, - env, &base_uri, file_sink, out_fd), - env, base_uri_node, base_uri - }; + SerdWriter writer = serd_writer_new( + output_syntax, output_style, env, &base_uri, file_sink, out_fd); + + State state = { env, read_state, writer }; SerdReader reader = serd_reader_new( SERD_TURTLE, &state, @@ -274,11 +239,9 @@ main(int argc, char** argv) serd_writer_finish(state.writer); serd_writer_free(state.writer); - + serd_read_state_free(state.read_state); serd_env_free(state.env); - serd_node_free(&state.base_uri_node); - if (success) { return 0; } -- cgit v1.2.1