From 0e7dfee8bae6655b316f1d0cabbad7df4dba6105 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 16 Feb 2011 17:03:27 +0000 Subject: Add SERD_STYLE_RESOLVED option for resolving (expanding) relative URIs in output. Add serd_env_qualify and serd_env_foreach. git-svn-id: http://svn.drobilla.net/serd/trunk@101 490d8e77-9747-427b-9fa3-0b8f29cee8a0 --- serd/serd.h | 67 ++++++++++++++++++++++++++++++++++++++++--------------------- src/env.c | 36 +++++++++++++++++++++++++++++++++ src/serdi.c | 2 ++ 3 files changed, 82 insertions(+), 23 deletions(-) diff --git a/serd/serd.h b/serd/serd.h index 98064bac..9655cdd2 100644 --- a/serd/serd.h +++ b/serd/serd.h @@ -222,6 +222,29 @@ SERD_API void serd_node_free(SerdNode* node); +/** @} */ +/** @name SerdHandlers + * @brief Event handlers (user-provided worker functions). + * @{ + */ + +/** Sink for base URI changes. */ +typedef bool (*SerdBaseSink)(void* handle, + const SerdNode* uri); + +/** Sink for namespace definitions. */ +typedef bool (*SerdPrefixSink)(void* handle, + const SerdNode* name, + const SerdNode* uri); + +/** Sink for statements. */ +typedef bool (*SerdStatementSink)(void* handle, + const SerdNode* graph, + const SerdNode* subject, + const SerdNode* predicate, + const SerdNode* object, + const SerdNode* object_datatype, + const SerdNode* object_lang); /** @} */ /** @name SerdEnv @@ -246,38 +269,35 @@ serd_env_add(SerdEnv env, const SerdNode* name, const SerdNode* uri); -/** Expand @a qname. */ +/** Qualify @a into a CURIE if possible. */ +SERD_API +bool +serd_env_qualify(const SerdEnv env, + const SerdNode* uri, + SerdNode* prefix, + SerdChunk* suffix); + +/** Expand @a curie. */ SERD_API bool serd_env_expand(const SerdEnv env, - const SerdNode* qname, + const SerdNode* curie, SerdChunk* uri_prefix, SerdChunk* uri_suffix); +/** Call @a func for each prefix defined in @a env. */ +SERD_API +void +serd_env_foreach(const SerdEnv env, + SerdPrefixSink func, + void* handle); + /** @} */ /** @name SerdReader * @brief Reader of RDF syntax. * @{ */ -/** Sink for base URI changes. */ -typedef bool (*SerdBaseSink)(void* handle, - const SerdNode* uri); - -/** Sink for namespace definitions. */ -typedef bool (*SerdPrefixSink)(void* handle, - const SerdNode* name, - const SerdNode* uri); - -/** Sink for statements. */ -typedef bool (*SerdStatementSink)(void* handle, - const SerdNode* graph, - const SerdNode* subject, - const SerdNode* predicate, - const SerdNode* object, - const SerdNode* object_datatype, - const SerdNode* object_lang); - /** Sink for anonymous node end markers. * This is called to indicate that the anonymous node with the given * @a value will no longer be referred to by any future statements @@ -333,7 +353,8 @@ serd_reader_free(SerdReader reader); typedef enum { SERD_STYLE_ABBREVIATED = 1, /**< Abbreviate triples when possible. */ - SERD_STYLE_ASCII = 1 << 1 /**< Escape all non-ASCII characters. */ + SERD_STYLE_ASCII = 1 << 1, /**< Escape all non-ASCII characters. */ + SERD_STYLE_RESOLVED = 1 << 2 /**< Resolve relative URIs against base. */ } SerdStyle; /** Create a new RDF writer. */ @@ -351,13 +372,13 @@ SERD_API void serd_writer_free(SerdWriter writer); -/** Set the current output base URI. */ +/** Set the current output base URI (and emit directive if applicable). */ SERD_API void serd_writer_set_base_uri(SerdWriter writer, const SerdURI* uri); -/** Set the current output base URI. */ +/** Set a namespace prefix (and emit directive if applicable). */ SERD_API void serd_writer_set_prefix(SerdWriter writer, diff --git a/src/env.c b/src/env.c index 3d64d2b1..9d3b3ca4 100644 --- a/src/env.c +++ b/src/env.c @@ -91,6 +91,29 @@ serd_env_add(SerdEnv env, } } +SERD_API +bool +serd_env_qualify(const SerdEnv env, + const SerdNode* uri, + SerdNode* prefix_name, + SerdChunk* suffix) +{ + for (size_t i = 0; i < env->n_prefixes; ++i) { + const SerdNode* const prefix_uri = &env->prefixes[i].uri; + if (uri->n_bytes >= prefix_uri->n_bytes) { + if (!strncmp((const char*)uri->buf, + (const char*)prefix_uri->buf, + prefix_uri->n_bytes)) { + *prefix_name = env->prefixes[i].name; + suffix->buf = uri->buf + prefix_uri->n_bytes; + suffix->len = uri->n_bytes - prefix_uri->n_bytes; + return true; + } + } + } + return false; +} + SERD_API bool serd_env_expand(const SerdEnv env, @@ -114,3 +137,16 @@ serd_env_expand(const SerdEnv env, } return false; } + +SERD_API +void +serd_env_foreach(const SerdEnv env, + SerdPrefixSink func, + void* handle) +{ + for (size_t i = 0; i < env->n_prefixes; ++i) { + func(handle, + &env->prefixes[i].name, + &env->prefixes[i].uri); + } +} diff --git a/src/serdi.c b/src/serdi.c index 5d7244b2..7736f773 100644 --- a/src/serdi.c +++ b/src/serdi.c @@ -237,6 +237,8 @@ main(int argc, char** argv) ? SERD_STYLE_ASCII : SERD_STYLE_ABBREVIATED; + output_style |= SERD_STYLE_RESOLVED; + const SerdNode base_uri_node = { SERD_URI, base_uri_n_bytes, base_uri_n_bytes - 1, -- cgit v1.2.1