summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugin.c81
-rw-r--r--src/port.c99
-rw-r--r--src/query.c42
-rw-r--r--src/slv2_internal.h5
-rw-r--r--src/util.c36
5 files changed, 152 insertions, 111 deletions
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 <string.h>
#include <assert.h>
#include <stdarg.h>
-#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;
+}