summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-01-29 04:55:18 +0000
committerDavid Robillard <d@drobilla.net>2011-01-29 04:55:18 +0000
commite9db5bc44e81f2c581e2443f3742c7fd0a0f1268 (patch)
tree499a954da2892c2224c5f37425fcb689c58a4325 /src
parenta4addf6fd568474db8071d3982e3f325ce52f8e4 (diff)
downloadlilv-e9db5bc44e81f2c581e2443f3742c7fd0a0f1268.tar.gz
lilv-e9db5bc44e81f2c581e2443f3742c7fd0a0f1268.tar.bz2
lilv-e9db5bc44e81f2c581e2443f3742c7fd0a0f1268.zip
Non-SPARQL version of slv2_plugin_load_ports_if_necessary.
This version has much better error-checking than the previous, but unfortunately the API returns void so it can't be communicated to the caller... git-svn-id: http://svn.drobilla.net/lad/trunk/slv2@2845 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/plugin.c186
-rw-r--r--src/slv2_internal.h3
-rw-r--r--src/world.c36
3 files changed, 139 insertions, 86 deletions
diff --git a/src/plugin.c b/src/plugin.c
index 2a835ec..100589b 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -86,7 +86,7 @@ slv2_plugin_free(SLV2Plugin p)
}
if (p->rdf) {
- librdf_free_model(p->rdf);
+ //librdf_free_model(p->rdf); // FIXME: memory leak
p->rdf = NULL;
}
@@ -111,6 +111,50 @@ slv2_plugin_load_if_necessary(SLV2Plugin p)
}
+static SLV2Values
+slv2_plugin_query_node(SLV2Plugin p, librdf_node* subject, librdf_node* predicate)
+{
+ // <subject> <predicate> ?value
+ librdf_stream* results = slv2_plugin_find_statements(
+ p, subject, predicate, NULL);
+
+ if (librdf_stream_end(results)) {
+ librdf_free_stream(results);
+ return NULL;
+ }
+
+ SLV2Values result = slv2_values_new();
+ while (!librdf_stream_end(results)) {
+ librdf_statement* s = librdf_stream_get_object(results);
+ librdf_node* value_node = librdf_statement_get_object(s);
+
+ SLV2Value value = slv2_value_new_librdf_node(p->world, value_node);
+ if (value)
+ raptor_sequence_push(result, value);
+
+ librdf_stream_next(results);
+ }
+
+ librdf_free_stream(results);
+ return result;
+}
+
+
+static SLV2Value
+slv2_plugin_get_unique(SLV2Plugin p, librdf_node* subject, librdf_node* predicate)
+{
+ SLV2Values values = slv2_plugin_query_node(p, subject, predicate);
+ if (!values || slv2_values_size(values) != 1) {
+ SLV2_ERRORF("Port does not have exactly one `%s' property\n",
+ librdf_uri_as_string(librdf_node_get_uri(predicate)));
+ return NULL;
+ }
+ SLV2Value ret = slv2_value_duplicate(slv2_values_get_at(values, 0));
+ slv2_values_free(values);
+ return ret;
+}
+
+
/* private */
void
slv2_plugin_load_ports_if_necessary(SLV2Plugin p)
@@ -122,61 +166,86 @@ slv2_plugin_load_ports_if_necessary(SLV2Plugin p)
p->ports = malloc(sizeof(SLV2Port*));
p->ports[0] = NULL;
- const unsigned char* query = (const unsigned char*)
- "PREFIX : <http://lv2plug.in/ns/lv2core#>\n"
- "SELECT DISTINCT ?type ?symbol ?index WHERE {\n"
- "<> :port ?port .\n"
- "?port a ?type ;\n"
- " :symbol ?symbol ;\n"
- " :index ?index .\n"
- "}";
+ librdf_stream* ports = slv2_plugin_find_statements(
+ p,
+ librdf_new_node_from_uri(p->world->world, p->plugin_uri->val.uri_val),
+ librdf_new_node_from_node(p->world->lv2_port_node),
+ NULL);
- librdf_query* q = librdf_new_query(p->world->world, "sparql",
- NULL, query, slv2_value_as_librdf_uri(p->plugin_uri));
+ while (!librdf_stream_end(ports)) {
+ librdf_statement* s = librdf_stream_get_object(ports);
+ librdf_node* port = librdf_new_node_from_node(
+ librdf_statement_get_object(s));
- librdf_query_results* results = librdf_query_execute(q, p->rdf);
+ SLV2Value symbol = slv2_plugin_get_unique(
+ p, port, p->world->lv2_symbol_node);
- while (!librdf_query_results_finished(results)) {
- librdf_node* type_node = librdf_query_results_get_binding_value(results, 0);
- librdf_node* symbol_node = librdf_query_results_get_binding_value(results, 1);
- librdf_node* index_node = librdf_query_results_get_binding_value(results, 2);
+ if (!slv2_value_is_string(symbol)) {
+ SLV2_ERROR("port has a non-string symbol\n");
+ p->num_ports = 0;
+ goto error;
+ }
- if (librdf_node_is_literal(symbol_node) && librdf_node_is_literal(index_node)) {
- const char* symbol = (const char*)librdf_node_get_literal_value(symbol_node);
- const char* index = (const char*)librdf_node_get_literal_value(index_node);
+ SLV2Value index = slv2_plugin_get_unique(
+ p, port, p->world->lv2_index_node);
- const int this_index = atoi(index);
- SLV2Port this_port = NULL;
+ if (!slv2_value_is_int(index)) {
+ SLV2_ERROR("port has a non-integer index\n");
+ p->num_ports = 0;
+ goto error;
+ }
- assert(this_index >= 0);
+ uint32_t this_index = slv2_value_as_int(index);
+ SLV2Port this_port = NULL;
+ if (p->num_ports > this_index) {
+ this_port = p->ports[this_index];
+ } else {
+ p->ports = realloc(p->ports, (this_index + 1) * sizeof(SLV2Port*));
+ memset(p->ports + p->num_ports, '\0',
+ (this_index - p->num_ports) * sizeof(SLV2Port));
+ p->num_ports = this_index + 1;
+ }
- if (p->num_ports > (unsigned)this_index) {
- this_port = p->ports[this_index];
+ // Havn't seen this port yet, add it to array
+ if (!this_port) {
+ this_port = slv2_port_new(p->world,
+ this_index,
+ slv2_value_as_string(symbol));
+ p->ports[this_index] = this_port;
+ }
+
+ librdf_stream* types = slv2_plugin_find_statements(
+ p, port, p->world->rdf_a_node, NULL);
+ while (!librdf_stream_end(types)) {
+ librdf_node* type = librdf_statement_get_object(
+ librdf_stream_get_object(types));
+ if (librdf_node_is_resource(type)) {
+ raptor_sequence_push(
+ this_port->classes,
+ slv2_value_new_librdf_uri(p->world, librdf_node_get_uri(type)));
} else {
- p->ports = realloc(p->ports, (this_index + 1) * sizeof(SLV2Port*));
- memset(p->ports + p->num_ports, '\0',
- (this_index - p->num_ports) * sizeof(SLV2Port));
- p->num_ports = this_index + 1;
+ SLV2_WARN("port has non-URI rdf:type\n");
}
-
- // Havn't seen this port yet, add it to array
- if (!this_port) {
- this_port = slv2_port_new(p->world, this_index, symbol);
- p->ports[this_index] = this_port;
+ librdf_stream_next(types);
+ }
+ librdf_free_stream(types);
+
+ error:
+ slv2_value_free(symbol);
+ slv2_value_free(index);
+ if (p->num_ports == 0) {
+ if (p->ports) {
+ for (uint32_t i = 0; i < p->num_ports; ++i)
+ slv2_port_free(p->ports[i]);
+ free(p->ports);
+ p->ports = NULL;
}
-
- raptor_sequence_push(this_port->classes,
- slv2_value_new_librdf_uri(p->world, librdf_node_get_uri(type_node)));
+ break; // Invalid plugin
+ } else {
+ librdf_stream_next(ports);
}
-
- librdf_free_node(type_node);
- librdf_free_node(symbol_node);
- librdf_free_node(index_node);
- librdf_query_results_next(results);
}
-
- librdf_free_query_results(results);
- librdf_free_query(q);
+ librdf_free_stream(ports);
}
}
@@ -367,6 +436,7 @@ slv2_plugin_verify(SLV2Plugin plugin)
return false;
}
+ slv2_values_free(results);
return true;
}
@@ -451,36 +521,14 @@ slv2_plugin_get_value_for_subject(SLV2Plugin p,
return NULL;
}
if ( ! slv2_value_is_uri(predicate)) {
- SLV2_ERROR("Subject is not a URI\n");
+ SLV2_ERROR("Predicate is not a URI\n");
return NULL;
}
- // <subject> <predicate> ?value
- librdf_stream* results = slv2_plugin_find_statements(
+ return slv2_plugin_query_node(
p,
librdf_new_node_from_uri(p->world->world, subject->val.uri_val),
- librdf_new_node_from_uri(p->world->world, predicate->val.uri_val),
- NULL);
-
- if (librdf_stream_end(results)) {
- librdf_free_stream(results);
- return NULL;
- }
-
- SLV2Values result = slv2_values_new();
- while (!librdf_stream_end(results)) {
- librdf_statement* s = librdf_stream_get_object(results);
- librdf_node* value_node = librdf_statement_get_object(s);
-
- SLV2Value value = slv2_value_new_librdf_node(p->world, value_node);
- if (value)
- raptor_sequence_push(result, value);
-
- librdf_stream_next(results);
- }
-
- librdf_free_stream(results);
- return result;
+ librdf_new_node_from_uri(p->world->world, predicate->val.uri_val));
}
diff --git a/src/slv2_internal.h b/src/slv2_internal.h
index 1075703..7d7e727 100644
--- a/src/slv2_internal.h
+++ b/src/slv2_internal.h
@@ -152,6 +152,9 @@ struct _SLV2World {
librdf_node* lv2_specification_node;
librdf_node* lv2_plugin_node;
librdf_node* lv2_binary_node;
+ librdf_node* lv2_port_node;
+ librdf_node* lv2_index_node;
+ librdf_node* lv2_symbol_node;
librdf_node* rdf_a_node;
librdf_node* xsd_integer_node;
librdf_node* xsd_decimal_node;
diff --git a/src/world.c b/src/world.c
index b54ce65..e66534c 100644
--- a/src/world.c
+++ b/src/world.c
@@ -55,23 +55,22 @@ slv2_world_new_internal(SLV2World world)
world->plugins = slv2_plugins_new();
- world->lv2_specification_node = librdf_new_node_from_uri_string(world->world,
- (const unsigned char*)"http://lv2plug.in/ns/lv2core#Specification");
-
- world->lv2_plugin_node = librdf_new_node_from_uri_string(world->world,
- (const unsigned char*)"http://lv2plug.in/ns/lv2core#Plugin");
-
- world->lv2_binary_node = librdf_new_node_from_uri_string(world->world,
- (const unsigned char*)"http://lv2plug.in/ns/lv2core#binary");
-
- world->rdf_a_node = librdf_new_node_from_uri_string(world->world,
- (const unsigned char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
-
- world->xsd_integer_node = librdf_new_node_from_uri_string(world->world,
- (const unsigned char*)"http://www.w3.org/2001/XMLSchema#integer");
-
- world->xsd_decimal_node = librdf_new_node_from_uri_string(world->world,
- (const unsigned char*)"http://www.w3.org/2001/XMLSchema#decimal");
+#define NEW_URI(uri) librdf_new_node_from_uri_string(world->world, \
+ (const unsigned char*)uri);
+
+#define NS_LV2 "http://lv2plug.in/ns/lv2core#"
+#define NS_XSD "http://www.w3.org/2001/XMLSchema#"
+#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+
+ world->lv2_specification_node = NEW_URI(NS_LV2 "Specification");
+ world->lv2_plugin_node = NEW_URI(NS_LV2 "Plugin");
+ world->lv2_binary_node = NEW_URI(NS_LV2 "binary");
+ world->lv2_port_node = NEW_URI(NS_LV2 "port");
+ world->lv2_index_node = NEW_URI(NS_LV2 "index");
+ world->lv2_symbol_node = NEW_URI(NS_LV2 "symbol");
+ world->rdf_a_node = NEW_URI(NS_RDF "type");
+ world->xsd_integer_node = NEW_URI(NS_XSD "integer");
+ world->xsd_decimal_node = NEW_URI(NS_XSD "decimal");
world->lv2_plugin_class = slv2_plugin_class_new(world, NULL,
librdf_node_get_uri(world->lv2_plugin_node), "Plugin");
@@ -148,6 +147,9 @@ slv2_world_free(SLV2World world)
librdf_free_node(world->lv2_specification_node);
librdf_free_node(world->lv2_plugin_node);
librdf_free_node(world->lv2_binary_node);
+ librdf_free_node(world->lv2_port_node);
+ librdf_free_node(world->lv2_index_node);
+ librdf_free_node(world->lv2_symbol_node);
librdf_free_node(world->rdf_a_node);
librdf_free_node(world->xsd_integer_node);
librdf_free_node(world->xsd_decimal_node);