diff options
-rw-r--r-- | serd/serd.h | 51 | ||||
-rw-r--r-- | src/env.c | 114 | ||||
-rw-r--r-- | src/namespaces.c | 115 | ||||
-rw-r--r-- | src/serdi.c | 20 | ||||
-rw-r--r-- | src/writer.c | 13 | ||||
-rw-r--r-- | wscript | 2 |
6 files changed, 156 insertions, 159 deletions
diff --git a/serd/serd.h b/serd/serd.h index 03ada7a8..295baee0 100644 --- a/serd/serd.h +++ b/serd/serd.h @@ -49,13 +49,13 @@ extern "C" { #endif /** @defgroup serd Serd - * @brief A lightweight RDF Serialisation Library. + * A lightweight RDF serialisation library. * @{ */ -typedef struct SerdNamespacesImpl* SerdNamespaces; ///< Set of namespaces -typedef struct SerdReaderImpl* SerdReader; ///< RDF reader -typedef struct SerdWriterImpl* SerdWriter; ///< RDF writer +typedef struct SerdEnvImpl* SerdEnv; /**< Namespace prefixes. */ +typedef struct SerdReaderImpl* SerdReader; /**< RDF reader. */ +typedef struct SerdWriterImpl* SerdWriter; /**< RDF writer. */ /** RDF syntax */ typedef enum { @@ -71,12 +71,12 @@ typedef enum { LITERAL = 4 ///< Literal string (with optional lang or datatype) } SerdNodeType; -/** @name URI - * Support for parsing and resolving URIs. +/** @name SerdURI + * A parsed URI. * @{ */ -/** A chunk of memory (non-terminated string). */ +/** A chunk of memory (unterminated string). */ typedef struct { const uint8_t* buf; ///< Start of chunk size_t len; ///< Length of chunk in bytes @@ -127,7 +127,7 @@ size_t serd_uri_serialise(const SerdURI* uri, SerdSink sink, void* stream); /** @} */ -/** @name String +/** @name SerdString * @brief A measured UTF-8 string. * @{ */ @@ -159,40 +159,41 @@ SERD_API SerdString* serd_string_new_from_uri(const SerdURI* uri, SerdURI* out); + /** @} */ -/** @name Namespaces - * @brief A dictionary of namespaces (names associated with URI strings) +/** @name SerdEnv + * @brief An environment (a prefix => URI dictionary). * @{ */ -/** Create a new namespaces dictionary. */ +/** Create a new environment. */ SERD_API -SerdNamespaces -serd_namespaces_new(); +SerdEnv +serd_env_new(); /** Free @a ns. */ SERD_API void -serd_namespaces_free(SerdNamespaces ns); +serd_env_free(SerdEnv env); /** Add namespace @a uri to @a ns using prefix @a name. */ SERD_API void -serd_namespaces_add(SerdNamespaces ns, - const SerdString* name, - const SerdString* uri); +serd_env_add(SerdEnv env, + const SerdString* name, + const SerdString* uri); /** Expand @a qname. */ SERD_API bool -serd_namespaces_expand(const SerdNamespaces ns, - const SerdString* qname, - SerdChunk* uri_prefix, - SerdChunk* uri_suffix); +serd_env_expand(const SerdEnv env, + const SerdString* qname, + SerdChunk* uri_prefix, + SerdChunk* uri_suffix); /** @} */ -/** @name Reader - * @brief Reader for RDF syntax. +/** @name SerdReader + * @brief Reader of RDF syntax. * @{ */ @@ -239,7 +240,7 @@ void serd_reader_free(SerdReader reader); /** @} */ -/** @name Writer +/** @name SerdWriter * @brief Writer of RDF syntax. * @{ */ @@ -255,7 +256,7 @@ SERD_API SerdWriter serd_writer_new(SerdSyntax syntax, SerdStyle style, - SerdNamespaces ns, + SerdEnv env, const SerdURI* base_uri, SerdSink sink, void* stream); diff --git a/src/env.c b/src/env.c new file mode 100644 index 00000000..9d8b6235 --- /dev/null +++ b/src/env.c @@ -0,0 +1,114 @@ +/* Serd, an RDF serialisation library. + * Copyright 2011 David Robillard <d@drobilla.net> + * + * Serd is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Serd is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#include "serd/serd.h" + +typedef struct { + SerdString* name; + SerdString* uri; +} SerdPrefix; + +struct SerdEnvImpl { + SerdPrefix* prefixes; + size_t n_prefixes; +}; + +SERD_API +SerdEnv +serd_env_new() +{ + SerdEnv env = malloc(sizeof(struct SerdEnvImpl)); + env->prefixes = NULL; + env->n_prefixes = 0; + return env; +} + +SERD_API +void +serd_env_free(SerdEnv env) +{ + for (size_t i = 0; i < env->n_prefixes; ++i) { + serd_string_free(env->prefixes[i].name); + serd_string_free(env->prefixes[i].uri); + } + free(env->prefixes); + free(env); +} + +static inline SerdPrefix* +serd_env_find(SerdEnv env, + const uint8_t* name, + size_t name_len) +{ + for (size_t i = 0; i < env->n_prefixes; ++i) { + const SerdString* prefix_name = env->prefixes[i].name; + if (prefix_name->n_bytes == name_len + 1) { + if (!memcmp(prefix_name->buf, name, name_len)) { + return &env->prefixes[i]; + } + } + } + return NULL; +} + +SERD_API +void +serd_env_add(SerdEnv env, + const SerdString* name, + const SerdString* uri) +{ + assert(name && uri); + SerdPrefix* const prefix = serd_env_find(env, name->buf, name->n_chars); + if (prefix) { + serd_string_free(prefix->uri); + prefix->uri = serd_string_copy(uri); + } else { + env->prefixes = realloc(env->prefixes, + (++env->n_prefixes) * sizeof(SerdPrefix)); + env->prefixes[env->n_prefixes - 1].name = serd_string_copy(name); + env->prefixes[env->n_prefixes - 1].uri = serd_string_copy(uri); + } +} + +SERD_API +bool +serd_env_expand(const SerdEnv env, + const SerdString* qname, + SerdChunk* uri_prefix, + SerdChunk* uri_suffix) +{ + const uint8_t* const colon = memchr(qname->buf, ':', qname->n_bytes); + if (!colon) { + return false; // Illegal qname + } + + const size_t name_len = colon - qname->buf; + const SerdPrefix* const prefix = serd_env_find(env, qname->buf, name_len); + if (prefix) { + uri_prefix->buf = prefix->uri->buf; + uri_prefix->len = prefix->uri->n_bytes - 1; + uri_suffix->buf = colon + 1; + uri_suffix->len = qname->n_bytes - (colon - qname->buf) - 2; + return true; + } + return false; +} diff --git a/src/namespaces.c b/src/namespaces.c deleted file mode 100644 index 409c92b9..00000000 --- a/src/namespaces.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Serd, an RDF serialisation library. - * Copyright 2011 David Robillard <d@drobilla.net> - * - * Serd is free software: you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Serd is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - * License for details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <assert.h> -#include <stdbool.h> -#include <stdlib.h> -#include <string.h> - -#include "serd/serd.h" - -typedef struct { - SerdString* name; - SerdString* uri; -} SerdNamespace; - -struct SerdNamespacesImpl { - SerdNamespace* namespaces; - size_t n_namespaces; -}; - -SERD_API -SerdNamespaces -serd_namespaces_new() -{ - SerdNamespaces ns = malloc(sizeof(struct SerdNamespacesImpl)); - ns->namespaces = NULL; - ns->n_namespaces = 0; - return ns; -} - -SERD_API -void -serd_namespaces_free(SerdNamespaces ns) -{ - for (size_t i = 0; i < ns->n_namespaces; ++i) { - serd_string_free(ns->namespaces[i].name); - serd_string_free(ns->namespaces[i].uri); - } - free(ns->namespaces); - free(ns); -} - -static inline SerdNamespace* -serd_namespaces_find(SerdNamespaces ns, - const uint8_t* name, - size_t name_len) -{ - for (size_t i = 0; i < ns->n_namespaces; ++i) { - const SerdString* ns_name = ns->namespaces[i].name; - if (ns_name->n_bytes == name_len + 1) { - if (!memcmp(ns_name->buf, name, name_len)) { - return &ns->namespaces[i]; - } - } - } - return NULL; -} - -SERD_API -void -serd_namespaces_add(SerdNamespaces ns, - const SerdString* name, - const SerdString* uri) -{ - assert(name); - assert(uri); - SerdNamespace* const record = serd_namespaces_find(ns, name->buf, name->n_chars); - if (record) { - serd_string_free(record->uri); - record->uri = serd_string_copy(uri); - } else { - ++ns->n_namespaces; - ns->namespaces = realloc(ns->namespaces, - ns->n_namespaces * sizeof(SerdNamespace)); - ns->namespaces[ns->n_namespaces - 1].name = serd_string_copy(name); - ns->namespaces[ns->n_namespaces - 1].uri = serd_string_copy(uri); - } -} - -SERD_API -bool -serd_namespaces_expand(const SerdNamespaces ns, - const SerdString* qname, - SerdChunk* uri_prefix, - SerdChunk* uri_suffix) -{ - const uint8_t* colon = memchr((const char*)qname->buf, ':', qname->n_bytes); - if (!colon) { - return false; // Illegal qname - } - - SerdNamespace* const record = serd_namespaces_find(ns, qname->buf, colon - qname->buf); - if (record) { - uri_prefix->buf = record->uri->buf; - uri_prefix->len = record->uri->n_bytes - 1; - uri_suffix->buf = colon + 1; - uri_suffix->len = qname->n_bytes - (colon - qname->buf) - 2; - return true; - } - return false; -} diff --git a/src/serdi.c b/src/serdi.c index 00e687de..73653792 100644 --- a/src/serdi.c +++ b/src/serdi.c @@ -22,10 +22,10 @@ #include "serd/serd.h" typedef struct { - SerdWriter writer; - SerdNamespaces ns; - SerdString* base_uri_str; - SerdURI base_uri; + SerdWriter writer; + SerdEnv env; + SerdString* base_uri_str; + SerdURI base_uri; } State; static bool @@ -84,10 +84,10 @@ event_prefix(void* handle, } SerdURI new_abs_uri; SerdString* abs_uri_string = serd_string_new_from_uri(&abs_uri, &new_abs_uri); - serd_namespaces_add(state->ns, name, abs_uri_string); + serd_env_add(state->env, name, abs_uri_string); serd_string_free(abs_uri_string); } else { - serd_namespaces_add(state->ns, name, uri_string); + serd_env_add(state->env, name, uri_string); } serd_writer_set_prefix(state->writer, name, uri_string); @@ -205,7 +205,7 @@ main(int argc, char** argv) return 1; } - SerdNamespaces ns = serd_namespaces_new(); + SerdEnv env = serd_env_new(); SerdStyle output_style = (output_syntax == SERD_NTRIPLES) ? SERD_STYLE_ASCII @@ -213,8 +213,8 @@ main(int argc, char** argv) State state = { serd_writer_new(output_syntax, output_style, - ns, &base_uri, file_sink, out_fd), - ns, base_uri_str, base_uri + env, &base_uri, file_sink, out_fd), + env, base_uri_str, base_uri }; SerdReader reader = serd_reader_new( @@ -227,7 +227,7 @@ main(int argc, char** argv) serd_writer_finish(state.writer); serd_writer_free(state.writer); - serd_namespaces_free(state.ns); + serd_env_free(state.env); serd_string_free(state.base_uri_str); if (success) { diff --git a/src/writer.c b/src/writer.c index 7c31106b..1e50b7b0 100644 --- a/src/writer.c +++ b/src/writer.c @@ -41,7 +41,7 @@ typedef bool (*NodeWriter)(SerdWriter writer, struct SerdWriterImpl { SerdSyntax syntax; SerdStyle style; - SerdNamespaces ns; + SerdEnv env; SerdURI base_uri; SerdSink sink; void* stream; @@ -154,9 +154,6 @@ write_node(SerdWriter writer, const SerdString* datatype, const SerdString* lang) { - const SerdURI* base_uri = &writer->base_uri; - SerdNamespaces ns = writer->ns; - SerdChunk uri_prefix; SerdChunk uri_suffix; switch (type) { @@ -167,7 +164,7 @@ write_node(SerdWriter writer, case QNAME: switch (writer->syntax) { case SERD_NTRIPLES: - if (!serd_namespaces_expand(ns, str, &uri_prefix, &uri_suffix)) { + if (!serd_env_expand(writer->env, str, &uri_prefix, &uri_suffix)) { fprintf(stderr, "error: undefined namespace prefix `%s'\n", str->buf); return false; } @@ -185,7 +182,7 @@ write_node(SerdWriter writer, SerdURI uri; if (serd_uri_parse(str->buf, &uri)) { SerdURI abs_uri; - if (serd_uri_resolve(&uri, base_uri, &abs_uri)) { + if (serd_uri_resolve(&uri, &writer->base_uri, &abs_uri)) { writer->sink("<", 1, writer->stream); serd_uri_serialise(&abs_uri, writer->sink, writer->stream); writer->sink(">", 1, writer->stream); @@ -336,7 +333,7 @@ SERD_API SerdWriter serd_writer_new(SerdSyntax syntax, SerdStyle style, - SerdNamespaces ns, + SerdEnv env, const SerdURI* base_uri, SerdSink sink, void* stream) @@ -344,7 +341,7 @@ serd_writer_new(SerdSyntax syntax, SerdWriter writer = malloc(sizeof(struct SerdWriterImpl)); writer->syntax = syntax; writer->style = style; - writer->ns = ns; + writer->env = env; writer->base_uri = *base_uri; writer->sink = sink; writer->stream = stream; @@ -55,7 +55,7 @@ def build(bld): autowaf.build_pc(bld, 'SERD', SERD_VERSION, ['REDLAND']) lib_source = ''' - src/namespaces.c + src/env.c src/reader.c src/string.c src/uri.c |