summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2006-09-03 05:11:57 +0000
committerDavid Robillard <d@drobilla.net>2006-09-03 05:11:57 +0000
commit056f394151a48e9d129691fd7451a3d0bcbde3ba (patch)
treec7c95bccfc503e704003e33b9385aa4657d2a57a
parent6c8dc477bda2d6e67893f4475e603a11cf507017 (diff)
downloadlilv-056f394151a48e9d129691fd7451a3d0bcbde3ba.tar.gz
lilv-056f394151a48e9d129691fd7451a3d0bcbde3ba.tar.bz2
lilv-056f394151a48e9d129691fd7451a3d0bcbde3ba.zip
Saner (internal) query API, though still needs work.
Preliminary (untested) support for host features/extensions/whatever. Documentation fixes and minor cleanups. git-svn-id: http://svn.drobilla.net/lad/libslv2@113 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--slv2/plugin.h44
-rw-r--r--slv2/query.h25
-rw-r--r--src/plugin.c110
-rw-r--r--src/port.c14
-rw-r--r--src/query.c127
5 files changed, 233 insertions, 87 deletions
diff --git a/slv2/plugin.h b/slv2/plugin.h
index 57fa266..95d933e 100644
--- a/slv2/plugin.h
+++ b/slv2/plugin.h
@@ -179,6 +179,50 @@ slv2_plugin_has_latency(const SLV2Plugin* p);
uint32_t
slv2_plugin_get_latency_port(const SLV2Plugin* p);
+#if 0
+/** Return whether or not a plugin supports the given host feature / extension.
+ *
+ * This will return true for both supported and required host features.
+ */
+bool
+slv2_plugin_supports_feature(const SLV2Plugin* p, const char* feature_uri);
+
+
+/** Return whether or not a plugin requires the given host feature / extension.
+ *
+ * If a plugin requires a feature, that feature MUST be passed to the plugin's
+ * instantiate method or the plugin will fail to instantiate.
+ */
+bool
+slv2_plugin_requires_features(const SLV2Plugin* p, const char* feature_uri);
+#endif
+
+/** Get a plugin's supported host features / extensions.
+ *
+ * This returns a list of all supported features (both required and optional).
+ */
+SLV2Property
+slv2_plugin_get_supported_features(const SLV2Plugin* p);
+
+
+/** Get a plugin's requires host features / extensions.
+ *
+ * All feature URI's returned by this call MUST be passed to the plugin's
+ * instantiate method for the plugin to instantiate successfully.
+ */
+SLV2Property
+slv2_plugin_get_required_features(const SLV2Plugin* p);
+
+
+/** Get a plugin's optional host features / extensions.
+ *
+ * If the feature URI's returned by this method are passed to the plugin's
+ * instantiate method, those features will be used by the function, otherwise
+ * the plugin will act as it would if it did not support that feature at all.
+ */
+SLV2Property
+slv2_plugin_get_optional_features(const SLV2Plugin* p);
+
/** @} */
diff --git a/slv2/query.h b/slv2/query.h
index 9f1c93d..a23df0e 100644
--- a/slv2/query.h
+++ b/slv2/query.h
@@ -74,23 +74,32 @@ char*
slv2_query_lang_filter(const char* variable);
-/** Run a SPARQL query on a plugin's data file.
+/** Run a SPARQL query on a plugin's data file and return variable matches.
*
* Header from slv2query_header will be prepended to passed query string (so
* the default prefixes will be already defined, you don't need to add them
* yourself).
*
- * rasqal_init() must be called by the caller before calling this function.
+ * Returned is a list of all matches for the query variable \a var_name.
*/
-rasqal_query_results*
-slv2_plugin_run_query(const SLV2Plugin* p,
- const char* query_string);
+SLV2Property
+slv2_query_get_results(const SLV2Plugin* p,
+ const char* query_string,
+ const char* var_name);
+
+/** Run a SPARQL query on a plugin's data file and just count the matches.
+ *
+ * Header from slv2query_header will be prepended to passed query string (so
+ * the default prefixes will be already defined, you don't need to add them
+ * yourself).
+ *
+ * Returned is the total of all variable matches resulting from the query.
+ */
size_t
-slv2_query_get_num_results(rasqal_query_results* results, const char* var_name);
+slv2_query_count_results(const SLV2Plugin* p,
+ const char* query_string);
-SLV2Property
-slv2_query_get_results(rasqal_query_results* results, const char* var_name);
/** Free an SLV2Property. */
void
diff --git a/src/plugin.c b/src/plugin.c
index a024077..65903da 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -130,7 +130,6 @@ SLV2Property
slv2_plugin_get_property(const SLV2Plugin* p,
const char* property)
{
- assert(p);
assert(property);
/*
@@ -147,19 +146,13 @@ slv2_plugin_get_property(const SLV2Plugin* p,
free(header);
free(lang_filter);*/
- rasqal_init();
-
char* query = strjoin(
"SELECT DISTINCT ?value FROM data: WHERE { \n"
"plugin: ", property, " ?value . \n"
"} \n", NULL);
- rasqal_query_results* results = slv2_plugin_run_query(p, query);
+ SLV2Property result = slv2_query_get_results(p, query, "value");
- SLV2Property result = slv2_query_get_results(results, "value");
-
- rasqal_free_query_results(results);
- rasqal_finish();
free(query);
return result;
@@ -169,54 +162,45 @@ slv2_plugin_get_property(const SLV2Plugin* p,
uint32_t
slv2_plugin_get_num_ports(const SLV2Plugin* p)
{
- rasqal_init();
-
char* query = strjoin(
"SELECT DISTINCT ?value FROM data: WHERE { \n"
"plugin: lv2:port ?value . \n"
"} \n", NULL);
- rasqal_query_results* results = slv2_plugin_run_query(p, query);
- const size_t result = slv2_query_get_num_results(results, "value");
+ SLV2Property results = slv2_query_get_results(p, query, "value");
+
+ size_t count = results->num_values;
- rasqal_free_query_results(results);
- rasqal_finish();
free(query);
+ slv2_property_free(results);
- return result;
+ return count;
}
bool
slv2_plugin_has_latency(const SLV2Plugin* p)
{
- assert(p);
-
- rasqal_init();
-
char* query =
"SELECT DISTINCT ?value FROM data: WHERE { \n"
" plugin: lv2:port ?port . \n"
" ?port lv2:portHint lv2:reportsLatency . \n"
"}\n";
- rasqal_query_results* results = slv2_plugin_run_query(p, query);
- bool result = ( rasqal_query_results_get_bindings_count(results) > 0 );
+ SLV2Property results = slv2_query_get_results(p, query, "port");
+
+ bool exists = (results->num_values > 0);
- rasqal_free_query_results(results);
- rasqal_finish();
- free(query);
+ free(query);
+ slv2_property_free(results);
- return result;
+ return exists;
}
+
uint32_t
slv2_plugin_get_latency_port(const SLV2Plugin* p)
{
- assert(p);
-
- rasqal_init();
-
char* query =
"SELECT DISTINCT ?value FROM data: WHERE { \n"
" plugin: lv2:port ?port . \n"
@@ -224,9 +208,7 @@ slv2_plugin_get_latency_port(const SLV2Plugin* p)
" lv2:index ?index . \n"
"}\n";
- rasqal_query_results* results = slv2_plugin_run_query(p, query);
-
- struct _Property* result = slv2_query_get_results(results, "index");
+ SLV2Property result = slv2_query_get_results(p, query, "index");
// FIXME: need a sane error handling strategy
assert(result->num_values == 1);
@@ -234,10 +216,70 @@ slv2_plugin_get_latency_port(const SLV2Plugin* p)
uint32_t index = strtol(result->values[0], &endptr, 10);
// FIXME: check.. stuff..
- rasqal_free_query_results(results);
- rasqal_finish();
free(query);
return index;
}
+/*
+bool
+slv2_plugin_supports_feature(const SLV2Plugin* p, const char* feature_uri)
+{
+}
+
+
+bool
+slv2_plugin_requires_feature(const SLV2Plugin* p, const char* feature_uri)
+{
+}
+*/
+
+SLV2Property
+slv2_plugin_get_supported_features(const SLV2Plugin* p)
+{
+ char* query =
+ "SELECT DISTINCT ?feature FROM data: WHERE { \n"
+ " { plugin: lv2:requiredHostFeature ?feature } \n"
+ " UNION \n"
+ " { plugin: lv2:supportedHostFeature ?feature } \n"
+ "}\n";
+
+ SLV2Property result = slv2_query_get_results(p, query, "feature");
+
+ free(query);
+
+ return result;
+}
+
+
+SLV2Property
+slv2_plugin_get_optional_features(const SLV2Plugin* p)
+{
+ char* query =
+ "SELECT DISTINCT ?feature FROM data: WHERE { \n"
+ " plugin: lv2:supportedHostFeature ?feature . \n"
+ "}\n";
+
+ SLV2Property result = slv2_query_get_results(p, query, "feature");
+
+ free(query);
+
+ return result;
+}
+
+
+SLV2Property
+slv2_plugin_get_required_features(const SLV2Plugin* p)
+{
+ char* query =
+ "SELECT DISTINCT ?feature FROM data: WHERE { \n"
+ " plugin: lv2:requiredHostFeature ?feature . \n"
+ "}\n";
+
+ SLV2Property result = slv2_query_get_results(p, query, "feature");
+
+ free(query);
+
+ return result;
+}
+
diff --git a/src/port.c b/src/port.c
index 111517d..1ca149d 100644
--- a/src/port.c
+++ b/src/port.c
@@ -73,13 +73,10 @@ slv2_port_get_property(SLV2Plugin* p,
uint32_t index,
const char* property)
{
- assert(p);
assert(property);
- char index_str[4];
- snprintf(index_str, (size_t)4, "%u", index);
-
- rasqal_init();
+ char index_str[16];
+ snprintf(index_str, (size_t)16, "%u", index);
char* query = strjoin(
"SELECT DISTINCT ?value FROM data: WHERE { \n"
@@ -87,12 +84,8 @@ slv2_port_get_property(SLV2Plugin* p,
"?port lv2:index ", index_str, " . \n"
"?port ", property, " ?value . \n}\n", NULL);
- rasqal_query_results* results = slv2_plugin_run_query(p, query);
+ SLV2Property result = slv2_query_get_results(p, query, "value");
- SLV2Property result = slv2_query_get_results(results, "value");
-
- rasqal_free_query_results(results);
- rasqal_finish();
free(query);
return result;
@@ -103,7 +96,6 @@ char*
slv2_port_get_symbol(SLV2Plugin* p,
uint32_t index)
{
- // FIXME: leaks
char* result = NULL;
SLV2Property prop
diff --git a/src/query.c b/src/query.c
index 56903ac..177d06e 100644
--- a/src/query.c
+++ b/src/query.c
@@ -58,9 +58,55 @@ slv2_query_lang_filter(const char* variable)
}
-rasqal_query_results*
-slv2_plugin_run_query(const SLV2Plugin* p,
- const char* query)
+SLV2Property
+slv2_query_get_variable_bindings(rasqal_query_results* results, const char* var_name)
+{
+ struct _Property* result = NULL;
+
+ if (rasqal_query_results_get_bindings_count(results) > 0) {
+ result = malloc(sizeof(struct _Property));
+ result->num_values = 0;
+ result->values = NULL;
+ }
+
+ while (!rasqal_query_results_finished(results)) {
+
+ rasqal_literal* literal =
+ rasqal_query_results_get_binding_value_by_name(results, (const unsigned char*)var_name);
+ assert(literal != NULL);
+
+ // Add value on to the array, reallocing all the way.
+ // Yes, this is disgusting. Roughly as disgusting as the rasqal query
+ // results API. coincidentally.
+ result->num_values++;
+ result->values = realloc(result->values, result->num_values * sizeof(char*));
+ result->values[result->num_values-1] = strdup((const char*)rasqal_literal_as_string(literal));
+
+ rasqal_query_results_next(results);
+ }
+
+ return result;
+}
+
+
+size_t
+slv2_query_count_variable_bindings(rasqal_query_results* results)
+{
+ size_t count = 0;
+
+ while (!rasqal_query_results_finished(results)) {
+ ++count;
+ rasqal_query_results_next(results);
+ }
+
+ return count;
+}
+
+
+SLV2Property
+slv2_query_get_results(const SLV2Plugin* p,
+ const char* query,
+ const char* var_name)
{
char* header = slv2_query_header(p);
char* query_str = strjoin(header, query, NULL);
@@ -68,21 +114,63 @@ slv2_plugin_run_query(const SLV2Plugin* p,
assert(p);
assert(query_str);
+ rasqal_init();
+
rasqal_query *rq = rasqal_new_query("sparql", NULL);
//printf("Query: \n%s\n\n", query_str);
rasqal_query_prepare(rq, (unsigned char*)query_str, NULL);
rasqal_query_results* results = rasqal_query_execute(rq);
+ assert(results);
+ SLV2Property ret = slv2_query_get_variable_bindings(results, var_name);
+ rasqal_free_query_results(results);
rasqal_free_query(rq);
+ rasqal_finish();
+
free(query_str);
free(header);
+
+ return ret;
+}
+
+
+size_t
+slv2_query_count_results(const SLV2Plugin* p,
+ const char* query)
+{
+ char* header = slv2_query_header(p);
+ char* query_str = strjoin(header, query, NULL);
+
+ assert(p);
+ assert(query_str);
+
+ rasqal_init();
+
+ rasqal_query *rq = rasqal_new_query("sparql", NULL);
+
+ //printf("Query: \n%s\n\n", query_str);
+
+ rasqal_query_prepare(rq, (unsigned char*)query_str, NULL);
+ rasqal_query_results* results = rasqal_query_execute(rq);
+ assert(results);
- return results;
+ size_t count = slv2_query_count_variable_bindings(results);
+
+ rasqal_free_query_results(results);
+ rasqal_free_query(rq);
+
+ rasqal_finish();
+
+ free(query_str);
+ free(header);
+
+ return count;
}
+/*
size_t
slv2_query_get_num_results(rasqal_query_results* results, const char* var_name)
{
@@ -97,36 +185,7 @@ slv2_query_get_num_results(rasqal_query_results* results, const char* var_name)
return result;
}
-
-SLV2Property
-slv2_query_get_results(rasqal_query_results* results, const char* var_name)
-{
- struct _Property* result = NULL;
-
- if (rasqal_query_results_get_bindings_count(results) > 0) {
- result = malloc(sizeof(struct _Property));
- result->num_values = 0;
- result->values = NULL;
- }
-
- while (!rasqal_query_results_finished(results)) {
-
- rasqal_literal* literal =
- rasqal_query_results_get_binding_value_by_name(results, (const unsigned char*)var_name);
- assert(literal != NULL);
-
- // Add value on to the array, reallocing all the way.
- // Yes, this is disgusting. Roughly as disgusting as the rasqal query
- // results API. coincidentally.
- result->num_values++;
- result->values = realloc(result->values, result->num_values * sizeof(char*));
- result->values[result->num_values-1] = strdup((const char*)rasqal_literal_as_string(literal));
-
- rasqal_query_results_next(results);
- }
-
- return result;
-}
+*/
void
slv2_property_free(struct _Property* prop)