From aa524702008b30123be3044b45a526de84312cff Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 30 Jan 2011 03:59:36 +0000 Subject: Non-SPARQL versions of slv2_port_get_value_by_qname, slv2_port_get_value_by_qname_i18n, and svn_port_get_value. Gracefully handle invalid predicates in slv2_plugin_get_value_by_qname. 2 queries left... git-svn-id: http://svn.drobilla.net/lad/trunk/slv2@2866 a436a847-0d15-0410-975c-d299462d15a1 --- src/plugin.c | 81 +++++++------------------------------------ src/port.c | 99 +++++++++++++++++++++++++++++++---------------------- src/query.c | 42 +++++++++++++++++++++++ src/slv2_internal.h | 5 ++- src/util.c | 36 ++++++++++++++++++- 5 files changed, 152 insertions(+), 111 deletions(-) (limited to 'src') diff --git a/src/plugin.c b/src/plugin.c index 798b5b0..1caf792 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -485,45 +485,14 @@ slv2_plugin_get_value(SLV2Plugin p, } -static char* -slv2_qname_expand(SLV2Plugin p, const char* qname) -{ - char* colon = strchr(qname, ':'); - if (!colon || colon == qname) { - SLV2_ERRORF("Invalid QName `%s'\n", qname); - return NULL; - } - - const size_t prefix_len = colon - qname; - char* prefix = malloc(prefix_len + 1); - memcpy(prefix, qname, prefix_len); - prefix[prefix_len] = '\0'; - - char* namespace = librdf_hash_get(p->world->namespaces, prefix); - free(prefix); - if (!namespace) { - SLV2_ERRORF("QName `%s' has Undefined prefix\n", qname); - return NULL; - } - - const size_t qname_len = strlen(qname); - const size_t suffix_len = qname_len - prefix_len - 1; - const size_t namespace_len = strlen(namespace); - char* uri = malloc(namespace_len + suffix_len + 1); - memcpy(uri, namespace, namespace_len); - memcpy(uri + namespace_len, colon + 1, qname_len - prefix_len - 1); - uri[namespace_len + suffix_len] = '\0'; - - free(namespace); - return uri; -} - - SLV2Values slv2_plugin_get_value_by_qname(SLV2Plugin p, const char* predicate) { - char* pred_uri = slv2_qname_expand(p, predicate); + char* pred_uri = slv2_qname_expand(p, predicate); + if (!pred_uri) { + return NULL; + } SLV2Value pred_value = slv2_value_new_uri(p->world, pred_uri); SLV2Values ret = slv2_plugin_get_value(p, pred_value); slv2_value_free(pred_value); @@ -536,47 +505,23 @@ SLV2Values slv2_plugin_get_value_by_qname_i18n(SLV2Plugin p, const char* predicate) { - char* pred_uri = slv2_qname_expand(p, predicate); - librdf_node* pred_node = librdf_new_node_from_uri_string(p->world->world, - (const uint8_t*)pred_uri); - SLV2Values result = slv2_values_new(); - librdf_node* nolang = NULL; + char* pred_uri = slv2_qname_expand(p, predicate); + if (!pred_uri) { + return NULL; + } + + librdf_node* pred_node = librdf_new_node_from_uri_string( + p->world->world, (const uint8_t*)pred_uri); + librdf_stream* results = slv2_plugin_find_statements( p, librdf_new_node_from_uri(p->world->world, p->plugin_uri->val.uri_val), pred_node, NULL); - for (; !librdf_stream_end(results); librdf_stream_next(results)) { - librdf_statement* s = librdf_stream_get_object(results); - librdf_node* value = librdf_statement_get_object(s); - - const char* lang = librdf_node_get_literal_value_language(value); - if (lang) { - if (!strcmp(lang, slv2_get_lang())) { - raptor_sequence_push( - result, slv2_value_new_string( - p->world, (const char*)librdf_node_get_literal_value(value))); - } - } else { - nolang = value; - } - break; - } - librdf_free_stream(results); free(pred_uri); - if (slv2_values_size(result) == 0) { - if (nolang) { - raptor_sequence_push( - result, slv2_value_new_string( - p->world, (const char*)librdf_node_get_literal_value(nolang))); - } else { - slv2_values_free(result); - result = NULL; - } - } - return result; + return slv2_values_from_stream_i18n(p, results); } diff --git a/src/port.c b/src/port.c index 435cd99..8ca2be0 100644 --- a/src/port.c +++ b/src/port.c @@ -134,25 +134,46 @@ slv2_port_supports_event(SLV2Plugin p, } +static SLV2Values +slv2_values_from_stream_objects(SLV2Plugin p, librdf_stream* stream) +{ + if (librdf_stream_end(stream)) { + return NULL; + } + + SLV2Values values = slv2_values_new(); + for (; !librdf_stream_end(stream); librdf_stream_next(stream)) { + raptor_sequence_push( + values, + slv2_value_new_librdf_node( + p->world, + librdf_statement_get_object( + librdf_stream_get_object(stream)))); + } + librdf_free_stream(stream); + return values; +} + + SLV2Values slv2_port_get_value_by_qname(SLV2Plugin p, SLV2Port port, - const char* property) + const char* predicate) { - assert(property); - SLV2Values results = NULL; - - char* query = slv2_strjoin( - "SELECT DISTINCT ?value WHERE {\n" - "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n" - "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n\t", - property, " ?value .\n" - "FILTER(lang(?value) = \"\") }", NULL); + assert(predicate); + char* pred_uri = slv2_qname_expand(p, predicate); + if (!pred_uri) { + return NULL; + } - results = slv2_plugin_query_variable(p, query, 0); + librdf_node* port_node = slv2_port_get_node(p, port); + librdf_stream* results = slv2_plugin_find_statements( + p, + port_node, + librdf_new_node_from_uri_string(p->world->world, (const uint8_t*)pred_uri), + NULL); - free(query); - return results; + return slv2_values_from_stream_objects(p, results); } @@ -161,45 +182,41 @@ slv2_port_get_value(SLV2Plugin p, SLV2Port port, SLV2Value predicate) { - char* query = NULL; - - /* Hack around broken RASQAL, full URI predicates don't work :/ */ - query = slv2_strjoin( - "PREFIX slv2predicate: <", slv2_value_as_string(predicate), ">", - "SELECT DISTINCT ?value WHERE { \n" - "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n" - "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n\t", - " slv2predicate: ?value .\n" - "}\n", NULL); - - SLV2Values result = slv2_plugin_query_variable(p, query, 0); + if ( ! slv2_value_is_uri(predicate)) { + SLV2_ERROR("Predicate is not a URI\n"); + return NULL; + } - free(query); + librdf_node* port_node = slv2_port_get_node(p, port); + librdf_stream* results = slv2_plugin_find_statements( + p, + port_node, + librdf_new_node_from_uri(p->world->world, slv2_value_as_librdf_uri(predicate)), + NULL); - return result; + return slv2_values_from_stream_objects(p, results); } SLV2Values slv2_port_get_value_by_qname_i18n(SLV2Plugin p, SLV2Port port, - const char* property) + const char* predicate) { - assert(property); - SLV2Values results = NULL; - - char* query = slv2_strjoin( - "SELECT DISTINCT ?value WHERE {\n" - "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n" - "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n\t", - property, " ?value .\n" - "FILTER(lang(?value) = \"", slv2_get_lang(), - "\") }", NULL); + assert(predicate); + char* pred_uri = slv2_qname_expand(p, predicate); + if (!pred_uri) { + return NULL; + } - results = slv2_plugin_query_variable(p, query, 0); + librdf_node* port_node = slv2_port_get_node(p, port); + librdf_stream* results = slv2_plugin_find_statements( + p, + port_node, + librdf_new_node_from_uri_string(p->world->world, (const uint8_t*)pred_uri), + NULL); - free(query); - return results; + return slv2_values_from_stream_i18n(p, results); } diff --git a/src/query.c b/src/query.c index aebc87b..3fb0ce9 100644 --- a/src/query.c +++ b/src/query.c @@ -205,6 +205,7 @@ slv2_plugin_query_count(SLV2Plugin plugin, return ret; } + librdf_stream* slv2_plugin_find_statements(SLV2Plugin plugin, librdf_node* subject, @@ -218,3 +219,44 @@ slv2_plugin_find_statements(SLV2Plugin plugin, librdf_free_statement(q); return results; } + + +SLV2Values +slv2_values_from_stream_i18n(SLV2Plugin p, + librdf_stream* stream) +{ + SLV2Values values = slv2_values_new(); + librdf_node* nolang = NULL; + for (; !librdf_stream_end(stream); librdf_stream_next(stream)) { + librdf_statement* s = librdf_stream_get_object(stream); + librdf_node* value = librdf_statement_get_object(s); + if (librdf_node_is_literal(value)) { + const char* lang = librdf_node_get_literal_value_language(value); + if (lang) { + if (!strcmp(lang, slv2_get_lang())) { + raptor_sequence_push( + values, slv2_value_new_string( + p->world, (const char*)librdf_node_get_literal_value(value))); + } + } else { + nolang = value; + } + } + break; + } + librdf_free_stream(stream); + + if (slv2_values_size(values) == 0) { + // No value with a matching language, use untranslated default + if (nolang) { + raptor_sequence_push( + values, slv2_value_new_string( + p->world, (const char*)librdf_node_get_literal_value(nolang))); + } else { + slv2_values_free(values); + values = NULL; + } + } + + return values; +} diff --git a/src/slv2_internal.h b/src/slv2_internal.h index a4314a4..f2984a3 100644 --- a/src/slv2_internal.h +++ b/src/slv2_internal.h @@ -268,12 +268,15 @@ struct _SLV2Results { librdf_query_results* rdf_results; }; +SLV2Values slv2_values_from_stream_i18n(SLV2Plugin p, + librdf_stream* stream); + /* ********* Utilities ********* */ char* slv2_strjoin(const char* first, ...); const char* slv2_get_lang(); - +char* slv2_qname_expand(SLV2Plugin p, const char* qname); /* ********* Dynamic Manifest ********* */ #ifdef SLV2_DYN_MANIFEST diff --git a/src/util.c b/src/util.c index 92811c8..9fee529 100644 --- a/src/util.c +++ b/src/util.c @@ -22,8 +22,9 @@ #include #include #include -#include "slv2/util.h" +#include "slv2/util.h" +#include "slv2_internal.h" char* slv2_strjoin(const char* first, ...) @@ -87,3 +88,36 @@ slv2_get_lang() return lang; } + +char* +slv2_qname_expand(SLV2Plugin p, const char* qname) +{ + char* colon = strchr(qname, ':'); + if (!colon || colon == qname) { + SLV2_ERRORF("Invalid QName `%s'\n", qname); + return NULL; + } + + const size_t prefix_len = colon - qname; + char* prefix = malloc(prefix_len + 1); + memcpy(prefix, qname, prefix_len); + prefix[prefix_len] = '\0'; + + char* namespace = librdf_hash_get(p->world->namespaces, prefix); + free(prefix); + if (!namespace) { + SLV2_ERRORF("QName `%s' has Undefined prefix\n", qname); + return NULL; + } + + const size_t qname_len = strlen(qname); + const size_t suffix_len = qname_len - prefix_len - 1; + const size_t namespace_len = strlen(namespace); + char* uri = malloc(namespace_len + suffix_len + 1); + memcpy(uri, namespace, namespace_len); + memcpy(uri + namespace_len, colon + 1, qname_len - prefix_len - 1); + uri[namespace_len + suffix_len] = '\0'; + + free(namespace); + return uri; +} -- cgit v1.2.1