From cedf1a1f9e1e007aaf72757d896ed3455da10f69 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 28 Apr 2007 00:44:32 +0000 Subject: Reworked query/value system to expose data type. git-svn-id: http://svn.drobilla.net/lad/slv2@475 a436a847-0d15-0410-975c-d299462d15a1 --- doc/reference.doxygen.in | 15 ++++---- slv2/Makefile.am | 18 +++++----- slv2/plugin.h | 26 +++++++------- slv2/port.h | 6 ++-- slv2/slv2.h | 2 +- slv2/strings.h | 83 -------------------------------------------- slv2/types.h | 8 +++++ slv2/values.h | 81 +++++++++++++++++++++++++++++++++++++++++++ src/Makefile.am | 17 ++++----- src/plugin.c | 90 ++++++++++++++++++++++++++---------------------- src/plugins.c | 4 +-- src/port.c | 86 ++++++++++++++++++++++----------------------- src/query.c | 62 ++++++++++++++++++++------------- src/slv2_internal.h | 21 +++++++++++ src/strings.c | 65 ---------------------------------- src/values.c | 67 +++++++++++++++++++++++++++++++++++ src/world.c | 2 +- utils/lv2_inspect.c | 42 +++++++++++----------- 18 files changed, 372 insertions(+), 323 deletions(-) delete mode 100644 slv2/strings.h create mode 100644 slv2/values.h delete mode 100644 src/strings.c create mode 100644 src/values.c diff --git a/doc/reference.doxygen.in b/doc/reference.doxygen.in index a899bd3..bfcd911 100644 --- a/doc/reference.doxygen.in +++ b/doc/reference.doxygen.in @@ -420,19 +420,18 @@ WARN_LOGFILE = # with spaces. INPUT = @top_srcdir@/doc/mainpage.dox \ + @top_srcdir@/slv2/lv2.h \ @top_srcdir@/slv2/types.h \ + @top_srcdir@/slv2/util.h \ + @top_srcdir@/slv2/value.h \ + @top_srcdir@/slv2/values.h \ @top_srcdir@/slv2/world.h \ - @top_srcdir@/slv2/plugins.h \ - @top_srcdir@/slv2/strings.h \ + @top_srcdir@/slv2/plugin.h \ @top_srcdir@/slv2/pluginclass.h \ @top_srcdir@/slv2/pluginclasses.h \ - @top_srcdir@/slv2/plugin.h \ - @top_srcdir@/slv2/port.h \ @top_srcdir@/slv2/plugininstance.h \ - @top_srcdir@/slv2/util.h \ - @top_srcdir@/slv2/lv2.h #\ - #@top_srcdir@/slv2/query.h #\ - #@top_srcdir@/include + @top_srcdir@/slv2/plugins.h \ + @top_srcdir@/slv2/port.h # If the value of the INPUT tag contains directories, you can use the diff --git a/slv2/Makefile.am b/slv2/Makefile.am index 05fc432..8e57eb1 100644 --- a/slv2/Makefile.am +++ b/slv2/Makefile.am @@ -2,15 +2,15 @@ slv2includedir = $(includedir)/slv2 slv2include_HEADERS = \ lv2.h \ - types.h \ - slv2.h \ - world.h \ + plugin.h \ pluginclass.h \ pluginclasses.h \ - plugin.h \ - port.h \ - plugins.h \ plugininstance.h \ - strings.h \ - util.h - + plugins.h \ + port.h \ + slv2.h \ + types.h \ + util.h \ + value.h \ + values.h \ + world.h diff --git a/slv2/plugin.h b/slv2/plugin.h index 7ec073b..c6090a6 100644 --- a/slv2/plugin.h +++ b/slv2/plugin.h @@ -90,7 +90,7 @@ slv2_plugin_get_uri(SLV2Plugin plugin); * * Time = O(1) */ -SLV2Strings +SLV2Values slv2_plugin_get_data_uris(SLV2Plugin plugin); @@ -133,13 +133,13 @@ slv2_plugin_get_class(SLV2Plugin plugin); * <plugin-uri> predicate ?object * * May return NULL if the property was not found, or if object is not - * sensibly represented as an SLV2Strings (e.g. blank nodes). + * sensibly represented as an SLV2Values (e.g. blank nodes). * - * Return value must be freed by caller with slv2_strings_free. + * Return value must be freed by caller with slv2_values_free. * * Time = Query */ -SLV2Strings +SLV2Values slv2_plugin_get_value(SLV2Plugin p, const char* predicate); @@ -154,13 +154,13 @@ slv2_plugin_get_value(SLV2Plugin p, * (if information about it is contained in the plugin's data files). * * May return NULL if the property was not found, or if object is not - * sensibly represented as an SLV2Strings (e.g. blank nodes). + * sensibly represented as an SLV2Values (e.g. blank nodes). * - * Return value must be freed by caller with slv2_strings_free. + * Return value must be freed by caller with slv2_values_free. * * Time = Query */ -SLV2Strings +SLV2Values slv2_plugin_get_value_for_subject(SLV2Plugin p, const char* subject, const char* predicate); @@ -176,7 +176,7 @@ slv2_plugin_get_value_for_subject(SLV2Plugin p, * * Time = Query */ -SLV2Strings +SLV2Values slv2_plugin_get_properties(SLV2Plugin p); @@ -189,7 +189,7 @@ slv2_plugin_get_properties(SLV2Plugin p); * * Time = Query */ -SLV2Strings +SLV2Values slv2_plugin_get_hints(SLV2Plugin p); @@ -234,7 +234,7 @@ slv2_plugin_get_latency_port(SLV2Plugin p); * * Time = Query */ -SLV2Strings +SLV2Values slv2_plugin_get_supported_features(SLV2Plugin p); @@ -245,7 +245,7 @@ slv2_plugin_get_supported_features(SLV2Plugin p); * * Time = Query */ -SLV2Strings +SLV2Values slv2_plugin_get_required_features(SLV2Plugin p); @@ -257,7 +257,7 @@ slv2_plugin_get_required_features(SLV2Plugin p); * * Time = Query */ -SLV2Strings +SLV2Values slv2_plugin_get_optional_features(SLV2Plugin p); @@ -270,7 +270,7 @@ slv2_plugin_get_optional_features(SLV2Plugin p); * * Time = Query */ -SLV2Strings +SLV2Values slv2_plugin_simple_query(SLV2Plugin plugin, const char* sparql_str, const char* variable); diff --git a/slv2/port.h b/slv2/port.h index 165c1f1..10a2f3f 100644 --- a/slv2/port.h +++ b/slv2/port.h @@ -37,7 +37,7 @@ extern "C" { * * Time = Query */ -SLV2Strings +SLV2Values slv2_port_get_value(SLV2Plugin plugin, SLV2Port port, const char* property); @@ -47,7 +47,7 @@ slv2_port_get_value(SLV2Plugin plugin, * * Time = Query */ -SLV2Strings +SLV2Values slv2_port_get_properties(SLV2Plugin plugin, SLV2Port port); @@ -56,7 +56,7 @@ slv2_port_get_properties(SLV2Plugin plugin, * * Time = Query */ -SLV2Strings +SLV2Values slv2_port_get_hints(SLV2Plugin plugin, SLV2Port port); diff --git a/slv2/slv2.h b/slv2/slv2.h index ee0bcfa..f3a4a0d 100644 --- a/slv2/slv2.h +++ b/slv2/slv2.h @@ -30,7 +30,7 @@ extern "C" { #include #include #include -#include +#include #ifdef __cplusplus } diff --git a/slv2/strings.h b/slv2/strings.h deleted file mode 100644 index 20667ef..0000000 --- a/slv2/strings.h +++ /dev/null @@ -1,83 +0,0 @@ -/* SLV2 - * Copyright (C) 2007 Dave Robillard - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef __SLV2_STRINGS_H__ -#define __SLV2_STRINGS_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup strings Collections of strings - * - * SLV2Strings is an ordered collection of strings which is fast for random - * access by index (i.e. a fancy array). - * - * @{ - */ - - -typedef void* SLV2Strings; - - -/** Allocate a new, empty SLV2Strings - */ -SLV2Strings -slv2_strings_new(); - - -/** Get the number of elements in a string list. - */ -unsigned -slv2_strings_size(SLV2Strings list); - - -/** Get a string from a string list at the given index. - * - * @return the element at \a index, or NULL if index is out of range. - * - * Time = O(1) - */ -const char* -slv2_strings_get_at(SLV2Strings list, unsigned index); - - -/** Return whether \a list contains \a string. - * - * Time = O(n) - */ -bool -slv2_strings_contains(SLV2Strings list, const char* string); - - -/** Free a string list. - */ -void -slv2_strings_free(SLV2Strings); - - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* __SLV2_STRINGS_H__ */ - diff --git a/slv2/types.h b/slv2/types.h index 7e965be..d55b81d 100644 --- a/slv2/types.h +++ b/slv2/types.h @@ -64,6 +64,14 @@ typedef struct _PluginClass* SLV2PluginClass; typedef void* SLV2PluginClasses; +/** A typed value */ +typedef struct _Value* SLV2Value; + + +/** A collection of typed values. */ +typedef void* SLV2Values; + + #ifdef __cplusplus } #endif diff --git a/slv2/values.h b/slv2/values.h new file mode 100644 index 0000000..a8381cd --- /dev/null +++ b/slv2/values.h @@ -0,0 +1,81 @@ +/* SLV2 + * Copyright (C) 2007 Dave Robillard + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __SLV2_VALUES_H__ +#define __SLV2_VALUES_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup strings Collections of strings + * + * SLV2Values is an ordered collection of strings which is fast for random + * access by index (i.e. a fancy array). + * + * @{ + */ + + +/** Allocate a new, empty SLV2Values + */ +SLV2Values +slv2_values_new(); + + +/** Get the number of elements in a string list. + */ +unsigned +slv2_values_size(SLV2Values list); + + +/** Get a string from a string list at the given index. + * + * @return the element at \a index, or NULL if index is out of range. + * + * Time = O(1) + */ +SLV2Value +slv2_values_get_at(SLV2Values list, unsigned index); + + +/** Return whether \a list contains \a string. + * + * Time = O(n) + */ +bool +slv2_values_contains(SLV2Values list, SLV2Value value); + + +/** Free a string list. + */ +void +slv2_values_free(SLV2Values); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SLV2_VALUES_H__ */ + diff --git a/src/Makefile.am b/src/Makefile.am index cdc8793..f7b9f76 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,14 +5,15 @@ lib_LTLIBRARIES = libslv2.la libslv2_la_LIBADD = @REDLAND_LIBS@ libslv2_la_SOURCES = \ - slv2_internal.h \ - world.c \ + plugin.c \ pluginclass.c \ pluginclasses.c \ - plugin.c \ - query.c \ - port.c \ - plugins.c \ plugininstance.c \ - strings.c \ - util.c + plugins.c \ + port.c \ + query.c \ + slv2_internal.h \ + util.c \ + value.c \ + values.c \ + world.c diff --git a/src/plugin.c b/src/plugin.c index 7efe6b7..19418fe 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include "slv2_internal.h" @@ -38,7 +38,7 @@ slv2_plugin_new(SLV2World world, librdf_uri* uri, const char* binary_uri) plugin->plugin_uri = librdf_new_uri_from_uri(uri); plugin->binary_uri = strdup(binary_uri); plugin->plugin_class = NULL; - plugin->data_uris = slv2_strings_new(); + plugin->data_uris = slv2_values_new(); plugin->ports = raptor_new_sequence((void (*)(void*))&slv2_port_free, NULL); plugin->storage = NULL; plugin->rdf = NULL; @@ -70,7 +70,7 @@ slv2_plugin_free(SLV2Plugin p) p->storage = NULL; } - slv2_strings_free(p->data_uris); + slv2_values_free(p->data_uris); free(p); } @@ -94,9 +94,9 @@ slv2_plugin_duplicate(SLV2Plugin p) //result->bundle_url = strdup(p->bundle_url); result->binary_uri = strdup(p->binary_uri); - result->data_uris = slv2_strings_new(); - for (unsigned i=0; i < slv2_strings_size(p->data_uris); ++i) - raptor_sequence_push(result->data_uris, strdup(slv2_strings_get_at(p->data_uris, i))); + result->data_uris = slv2_values_new(); + for (unsigned i=0; i < slv2_values_size(p->data_uris); ++i) + raptor_sequence_push(result->data_uris, strdup(slv2_values_get_at(p->data_uris, i))); result->ports = raptor_new_sequence((void (*)(void*))&slv2_port_free, NULL); for (int i=0; i < raptor_sequence_size(p->ports); ++i) @@ -139,9 +139,10 @@ slv2_plugin_load(SLV2Plugin p) } // Parse all the plugin's data files into RDF model - for (unsigned i=0; i < slv2_strings_size(p->data_uris); ++i) { - const char* data_uri_str = slv2_strings_get_at(p->data_uris, i); - librdf_uri* data_uri = librdf_new_uri(p->world->world, (const unsigned char*)data_uri_str); + for (unsigned i=0; i < slv2_values_size(p->data_uris); ++i) { + SLV2Value data_uri_val = slv2_values_get_at(p->data_uris, i); + librdf_uri* data_uri = librdf_new_uri(p->world->world, + (const unsigned char*)slv2_value_as_uri(data_uri_val)); librdf_parser_parse_into_model(p->world->parser, data_uri, NULL, p->rdf); librdf_free_uri(data_uri); } @@ -235,7 +236,7 @@ slv2_plugin_get_uri(SLV2Plugin p) } -SLV2Strings +SLV2Values slv2_plugin_get_data_uris(SLV2Plugin p) { return p->data_uris; @@ -322,20 +323,23 @@ char* slv2_plugin_get_name(SLV2Plugin plugin) { char* result = NULL; - SLV2Strings prop = slv2_plugin_get_value(plugin, "doap:name"); + SLV2Values prop = slv2_plugin_get_value(plugin, "doap:name"); - // FIXME: guaranteed to be the untagged one? - if (prop && slv2_strings_size(prop) >= 1) - result = strdup(slv2_strings_get_at(prop, 0)); + // FIXME: lang? guaranteed to be the untagged one? + if (prop && slv2_values_size(prop) > 0) { + SLV2Value val = slv2_values_get_at(prop, 0); + if (slv2_value_is_string(val)) + result = strdup(slv2_value_as_string(val)); + } if (prop) - slv2_strings_free(prop); + slv2_values_free(prop); return result; } -SLV2Strings +SLV2Values slv2_plugin_get_value(SLV2Plugin p, const char* predicate) { @@ -346,7 +350,7 @@ slv2_plugin_get_value(SLV2Plugin p, "<> ", predicate, " ?value .\n" "}\n", NULL); - SLV2Strings result = slv2_plugin_simple_query(p, query, "value"); + SLV2Values result = slv2_plugin_simple_query(p, query, "value"); free(query); @@ -354,7 +358,7 @@ slv2_plugin_get_value(SLV2Plugin p, } -SLV2Strings +SLV2Values slv2_plugin_get_value_for_subject(SLV2Plugin p, const char* subject, const char* predicate) @@ -366,7 +370,7 @@ slv2_plugin_get_value_for_subject(SLV2Plugin p, subject, " ", predicate, " ?value .\n" "}\n", NULL); - SLV2Strings result = slv2_plugin_simple_query(p, query, "value"); + SLV2Values result = slv2_plugin_simple_query(p, query, "value"); free(query); @@ -374,14 +378,14 @@ slv2_plugin_get_value_for_subject(SLV2Plugin p, } -SLV2Strings +SLV2Values slv2_plugin_get_properties(SLV2Plugin p) { return slv2_plugin_get_value(p, "lv2:pluginProperty"); } -SLV2Strings +SLV2Values slv2_plugin_get_hints(SLV2Plugin p) { return slv2_plugin_get_value(p, "lv2:pluginHint"); @@ -399,18 +403,21 @@ bool slv2_plugin_has_latency(SLV2Plugin p) { const char* const query = - "SELECT DISTINCT ?port WHERE {\n" + "ASK WHERE {\n" " <> lv2:port ?port .\n" - " ?port lv2:portHint lv2:reportsLatency .\n" + " ?port lv2:portHint lv2:reportsLatency ;\n" + " lv2:index ?index .\n" "}\n"; - SLV2Strings results = slv2_plugin_simple_query(p, query, "port"); - - bool exists = (slv2_strings_size(results) > 0); + SLV2Values results = slv2_plugin_simple_query(p, query, "port"); - slv2_strings_free(results); - - return exists; + if (results) { + bool exists = (results && slv2_values_size(results) > 0); + slv2_values_free(results); + return exists; + } else { + return false; + } } @@ -418,25 +425,24 @@ uint32_t slv2_plugin_get_latency_port(SLV2Plugin p) { const char* const query = - "SELECT DISTINCT ?value WHERE {\n" + "SELECT DISTINCT ?index WHERE {\n" " <> lv2:port ?port .\n" " ?port lv2:portHint lv2:reportsLatency ;\n" " lv2:index ?index .\n" "}\n"; - SLV2Strings result = slv2_plugin_simple_query(p, query, "index"); + SLV2Values result = slv2_plugin_simple_query(p, query, "index"); // FIXME: need a sane error handling strategy - assert(slv2_strings_size(result) == 1); - char* endptr = 0; - uint32_t index = strtol(slv2_strings_get_at(result, 0), &endptr, 10); - // FIXME: check.. stuff.. + assert(slv2_values_size(result) > 0); + SLV2Value val = slv2_values_get_at(result, 0); + assert(slv2_value_is_int(val)); - return index; + return slv2_value_as_int(val); } -SLV2Strings +SLV2Values slv2_plugin_get_supported_features(SLV2Plugin p) { const char* const query = @@ -446,13 +452,13 @@ slv2_plugin_get_supported_features(SLV2Plugin p) " { <> lv2:requiredHostFeature ?feature }\n" "}\n"; - SLV2Strings result = slv2_plugin_simple_query(p, query, "feature"); + SLV2Values result = slv2_plugin_simple_query(p, query, "feature"); return result; } -SLV2Strings +SLV2Values slv2_plugin_get_optional_features(SLV2Plugin p) { const char* const query = @@ -460,13 +466,13 @@ slv2_plugin_get_optional_features(SLV2Plugin p) " <> lv2:optionalHostFeature ?feature .\n" "}\n"; - SLV2Strings result = slv2_plugin_simple_query(p, query, "feature"); + SLV2Values result = slv2_plugin_simple_query(p, query, "feature"); return result; } -SLV2Strings +SLV2Values slv2_plugin_get_required_features(SLV2Plugin p) { const char* const query = @@ -474,7 +480,7 @@ slv2_plugin_get_required_features(SLV2Plugin p) " <> lv2:requiredHostFeature ?feature .\n" "}\n"; - SLV2Strings result = slv2_plugin_simple_query(p, query, "feature"); + SLV2Values result = slv2_plugin_simple_query(p, query, "feature"); return result; } diff --git a/src/plugins.c b/src/plugins.c index ae450af..64f8430 100644 --- a/src/plugins.c +++ b/src/plugins.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include "slv2_internal.h" @@ -182,7 +182,7 @@ slv2_plugins_load_bundle(SLV2Plugins list, SLV2Plugin plugin = slv2_plugins_get_by_uri(list, subject); - if (plugin && data_uri && !slv2_strings_contains(plugin->data_uris, data_uri)) + if (plugin && data_uri && !slv2_values_contains(plugin->data_uris, data_uri)) raptor_sequence_push(plugin->data_uris, strdup(data_uri)); if (plugin && binary && !plugin->lib_uri) diff --git a/src/port.c b/src/port.c index 5d18c8a..6744274 100644 --- a/src/port.c +++ b/src/port.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "slv2_internal.h" @@ -66,7 +67,7 @@ SLV2PortClass slv2_port_get_class(SLV2Plugin p, SLV2Port port) { - SLV2Strings class = slv2_port_get_value(p, port, "rdf:type"); + SLV2Values class = slv2_port_get_value(p, port, "rdf:type"); assert(class); SLV2PortClass ret = SLV2_UNKNOWN_PORT_CLASS; @@ -74,18 +75,21 @@ slv2_port_get_class(SLV2Plugin p, int io = -1; // 0 = in, 1 = out enum { UNKNOWN, AUDIO, CONTROL, MIDI } type = UNKNOWN; - for (unsigned i=0; i < slv2_strings_size(class); ++i) { - const char* value = slv2_strings_get_at(class, i); - if (!strcmp(value, "http://lv2plug.in/ontology#InputPort")) - io = 0; - else if (!strcmp(value, "http://lv2plug.in/ontology#OutputPort")) - io = 1; - else if (!strcmp(value, "http://lv2plug.in/ontology#ControlPort")) - type = CONTROL; - else if (!strcmp(value, "http://lv2plug.in/ontology#AudioPort")) - type = AUDIO; - else if (!strcmp(value, "http://ll-plugins.nongnu.org/lv2/ext/MidiPort")) - type = MIDI; + for (unsigned i=0; i < slv2_values_size(class); ++i) { + SLV2Value val = slv2_values_get_at(class, i); + if (slv2_value_is_uri(val)) { + const char* uri = slv2_value_as_uri(val); + if (!strcmp(uri, "http://lv2plug.in/ontology#InputPort")) + io = 0; + else if (!strcmp(uri, "http://lv2plug.in/ontology#OutputPort")) + io = 1; + else if (!strcmp(uri, "http://lv2plug.in/ontology#ControlPort")) + type = CONTROL; + else if (!strcmp(uri, "http://lv2plug.in/ontology#AudioPort")) + type = AUDIO; + else if (!strcmp(uri, "http://ll-plugins.nongnu.org/lv2/ext/MidiPort")) + type = MIDI; + } } if (io == 0) { @@ -104,20 +108,20 @@ slv2_port_get_class(SLV2Plugin p, ret = SLV2_MIDI_OUTPUT; } - slv2_strings_free(class); + slv2_values_free(class); return ret; } -SLV2Strings +SLV2Values slv2_port_get_value(SLV2Plugin p, SLV2Port port, const char* property) { assert(property); - SLV2Strings result = NULL; + SLV2Values result = NULL; char* query = slv2_strjoin( "SELECT DISTINCT ?value WHERE {\n" @@ -138,12 +142,12 @@ slv2_port_get_symbol(SLV2Plugin p, { char* symbol = NULL; - SLV2Strings result = slv2_port_get_value(p, port, "lv2:symbol"); + SLV2Values result = slv2_port_get_value(p, port, "lv2:symbol"); - if (result && slv2_strings_size(result) == 1) - symbol = strdup(slv2_strings_get_at(result, 0)); + if (result && slv2_values_size(result) == 1) + symbol = strdup(slv2_value_as_string(slv2_values_get_at(result, 0))); - slv2_strings_free(result); + slv2_values_free(result); return symbol; } @@ -155,12 +159,12 @@ slv2_port_get_name(SLV2Plugin p, { char* name = NULL; - SLV2Strings result = slv2_port_get_value(p, port, "lv2:name"); + SLV2Values result = slv2_port_get_value(p, port, "lv2:name"); - if (result && slv2_strings_size(result) == 1) - name = strdup(slv2_strings_get_at(result, 0)); + if (result && slv2_values_size(result) == 1) + name = strdup(slv2_value_as_string(slv2_values_get_at(result, 0))); - slv2_strings_free(result); + slv2_values_free(result); return name; } @@ -170,16 +174,14 @@ float slv2_port_get_default_value(SLV2Plugin p, SLV2Port port) { - // FIXME: do casting properly in the SPARQL query - float value = 0.0f; - SLV2Strings result = slv2_port_get_value(p, port, "lv2:default"); + SLV2Values result = slv2_port_get_value(p, port, "lv2:default"); - if (result && slv2_strings_size(result) == 1) - value = atof(slv2_strings_get_at(result, 0)); + if (result && slv2_values_size(result) == 1) + value = slv2_value_as_float(slv2_values_get_at(result, 0)); - slv2_strings_free(result); + slv2_values_free(result); return value; } @@ -189,16 +191,14 @@ float slv2_port_get_minimum_value(SLV2Plugin p, SLV2Port port) { - // FIXME: need better access to literal types - float value = 0.0f; - SLV2Strings result = slv2_port_get_value(p, port, "lv2:minimum"); + SLV2Values result = slv2_port_get_value(p, port, "lv2:minimum"); - if (result && slv2_strings_size(result) == 1) - value = atof(slv2_strings_get_at(result, 0)); + if (result && slv2_values_size(result) == 1) + value = slv2_value_as_float(slv2_values_get_at(result, 0)); - slv2_strings_free(result); + slv2_values_free(result); return value; } @@ -208,22 +208,20 @@ float slv2_port_get_maximum_value(SLV2Plugin p, SLV2Port port) { - // FIXME: need better access to literal types - float value = 0.0f; - SLV2Strings result = slv2_port_get_value(p, port, "lv2:maximum"); + SLV2Values result = slv2_port_get_value(p, port, "lv2:maximum"); - if (result && slv2_strings_size(result) == 1) - value = atof(slv2_strings_get_at(result, 0)); + if (result && slv2_values_size(result) == 1) + value = slv2_value_as_float(slv2_values_get_at(result, 0)); - slv2_strings_free(result); + slv2_values_free(result); return value; } -SLV2Strings +SLV2Values slv2_port_get_properties(SLV2Plugin p, SLV2Port port) { @@ -231,7 +229,7 @@ slv2_port_get_properties(SLV2Plugin p, } -SLV2Strings +SLV2Values slv2_port_get_hints(SLV2Plugin p, SLV2Port port) { diff --git a/src/query.c b/src/query.c index 19eba56..bc1a7dc 100644 --- a/src/query.c +++ b/src/query.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include "slv2_internal.h" @@ -51,31 +51,46 @@ slv2_query_lang_filter(const char* variable) } #endif -SLV2Strings +SLV2Values slv2_query_get_variable_bindings(librdf_query_results* results, const char* variable) { - SLV2Strings result = NULL; + SLV2Values result = NULL; if (librdf_query_results_get_bindings_count(results) > 0) - result = slv2_strings_new(); + result = slv2_values_new(); while (!librdf_query_results_finished(results)) { librdf_node* node = librdf_query_results_get_binding_value_by_name(results, variable); - char* str = NULL; + librdf_uri* datatype_uri = NULL; + SLV2ValueType type = SLV2_VALUE_STRING; + + const char* str_val = NULL; switch (librdf_node_get_type(node)) { case LIBRDF_NODE_TYPE_RESOURCE: - str = strdup((const char*)librdf_uri_as_string(librdf_node_get_uri(node))); + type = SLV2_VALUE_URI; + str_val = (const char*)librdf_uri_as_string(librdf_node_get_uri(node)); break; case LIBRDF_NODE_TYPE_LITERAL: - str = strdup((const char*)librdf_node_get_literal_value(node)); + datatype_uri = librdf_node_get_literal_value_datatype_uri(node); + if (datatype_uri) { + if (!strcmp((const char*)librdf_uri_as_string(datatype_uri), + "http://www.w3.org/2001/XMLSchema#integer")) + type = SLV2_VALUE_INT; + else if (!strcmp((const char*)librdf_uri_as_string(datatype_uri), + "http://www.w3.org/2001/XMLSchema#decimal")) + type = SLV2_VALUE_FLOAT; + else + fprintf(stderr, "Unknown datatype %s\n", librdf_uri_as_string(datatype_uri)); + } + str_val = (const char*)librdf_node_get_literal_value(node); break; case LIBRDF_NODE_TYPE_BLANK: - str = strdup((const char*)librdf_node_get_blank_identifier(node)); + str_val = (const char*)librdf_node_get_blank_identifier(node); break; case LIBRDF_NODE_TYPE_UNKNOWN: default: @@ -83,10 +98,8 @@ slv2_query_get_variable_bindings(librdf_query_results* results, break; } - if (str) { - //printf("?%s = %s\n", variable, str); - raptor_sequence_push(result, str); - } + if (str_val) + raptor_sequence_push(result, slv2_value_new(type, str_val)); librdf_free_node(node); @@ -124,33 +137,33 @@ slv2_plugin_query(SLV2Plugin plugin, //printf("******** Query \n%s********\n", query_str); - librdf_query *rq = librdf_new_query(plugin->world->world, "sparql", NULL, + librdf_query* query = librdf_new_query(plugin->world->world, "sparql", NULL, (const unsigned char*)query_str, base_uri); - if (!rq) { + if (!query) { fprintf(stderr, "ERROR: Could not create query\n"); return NULL; } - librdf_query_results* results = librdf_query_execute(rq, plugin->rdf); + librdf_query_results* results = librdf_query_execute(query, plugin->rdf); - librdf_free_query(rq); - + librdf_free_query(query); free(query_str); - // FIXME: results leaked internally in places? return results; } /** Query a single variable */ -SLV2Strings +SLV2Values slv2_plugin_simple_query(SLV2Plugin plugin, const char* sparql_str, const char* variable) { librdf_query_results* results = slv2_plugin_query(plugin, sparql_str); - SLV2Strings ret = slv2_query_get_variable_bindings(results, variable); + + SLV2Values ret = slv2_query_get_variable_bindings(results, variable); + librdf_free_query_results(results); return ret; @@ -168,13 +181,14 @@ slv2_plugin_query_count(SLV2Plugin plugin, { librdf_query_results* results = slv2_plugin_query(plugin, sparql_str); + unsigned ret = 0; + if (results) { - unsigned ret = slv2_query_count_bindings(results); + ret = slv2_query_count_bindings(results); librdf_free_query_results(results); - return ret; - } else { - return 0; } + + return ret; } /* diff --git a/src/slv2_internal.h b/src/slv2_internal.h index a9683c3..180f07d 100644 --- a/src/slv2_internal.h +++ b/src/slv2_internal.h @@ -30,6 +30,7 @@ extern "C" { #include + /** Reference to a port on some plugin. */ struct _Port { @@ -119,6 +120,26 @@ slv2_world_load_path(SLV2World world, const char* search_path); +typedef enum _ValueType { + SLV2_VALUE_URI, + SLV2_VALUE_STRING, + SLV2_VALUE_INT, + SLV2_VALUE_FLOAT +} SLV2ValueType; + +struct _Value { + SLV2ValueType type; + char* str_val; ///< always present + union { + int int_val; + float float_val; + } val; +}; + +SLV2Value slv2_value_new(SLV2ValueType type, const char* val); +void slv2_value_free(SLV2Value val); + + #ifdef __cplusplus } #endif diff --git a/src/strings.c b/src/strings.c deleted file mode 100644 index 39da54f..0000000 --- a/src/strings.c +++ /dev/null @@ -1,65 +0,0 @@ -/* SLV2 - * Copyright (C) 2007 Dave Robillard - * - * This library is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include -#include - - -SLV2Strings -slv2_strings_new() -{ - return raptor_new_sequence(&free, NULL); -} - - -void -slv2_strings_free(SLV2Strings list) -{ - raptor_free_sequence(list); -} - - -unsigned -slv2_strings_size(SLV2Strings list) -{ - return raptor_sequence_size(list); -} - - -const char* -slv2_strings_get_at(SLV2Strings list, unsigned index) -{ - if (index > INT_MAX) - return NULL; - else - return (const char*)raptor_sequence_get_at(list, (int)index); -} - - -bool -slv2_strings_contains(SLV2Strings list, const char* str) -{ - for (unsigned i=0; i < slv2_strings_size(list); ++i) - if (!strcmp(slv2_strings_get_at(list, i), str)) - return true; - - return false; -} diff --git a/src/values.c b/src/values.c new file mode 100644 index 0000000..4920454 --- /dev/null +++ b/src/values.c @@ -0,0 +1,67 @@ +/* SLV2 + * Copyright (C) 2007 Dave Robillard + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include "slv2_internal.h" + + +SLV2Values +slv2_values_new() +{ + return raptor_new_sequence((void (*)(void*))&slv2_value_free, NULL); +} + + +void +slv2_values_free(SLV2Values list) +{ + raptor_free_sequence(list); +} + + +unsigned +slv2_values_size(SLV2Values list) +{ + return raptor_sequence_size(list); +} + + +SLV2Value +slv2_values_get_at(SLV2Values list, unsigned index) +{ + if (index > INT_MAX) + return NULL; + else + return (SLV2Value)raptor_sequence_get_at(list, (int)index); +} + + +bool +slv2_values_contains(SLV2Values list, SLV2Value value) +{ + for (unsigned i=0; i < slv2_values_size(list); ++i) + if (slv2_value_equals(slv2_values_get_at(list, i), value)) + return true; + + return false; +} + diff --git a/src/world.c b/src/world.c index fa4cf1e..556ccf4 100644 --- a/src/world.c +++ b/src/world.c @@ -329,7 +329,7 @@ slv2_world_load_all(SLV2World world) // FIXME: check for duplicates raptor_sequence_push(plugin->data_uris, - strdup((const char*)librdf_uri_as_string(data_uri))); + slv2_value_new(SLV2_VALUE_URI, (const char*)librdf_uri_as_string(data_uri))); librdf_free_node(plugin_node); librdf_free_node(data_node); diff --git a/utils/lv2_inspect.c b/utils/lv2_inspect.c index f1e1881..9245226 100644 --- a/utils/lv2_inspect.c +++ b/utils/lv2_inspect.c @@ -75,15 +75,15 @@ print_port(SLV2Plugin p, uint32_t index) printf("\t\tProperties:\n"); SLV2Strings properties = slv2_port_get_properties(p, port); - for (unsigned i=0; i < slv2_strings_size(properties); ++i) - printf("\t\t\t%s\n", slv2_strings_get_at(properties, i)); - slv2_strings_free(properties); + for (unsigned i=0; i < slv2_values_size(properties); ++i) + printf("\t\t\t%s\n", slv2_value_as_uri(slv2_values_get_at(properties, i))); + slv2_values_free(properties); printf("\t\tHints:\n"); SLV2Strings hints = slv2_port_get_hints(p, port); - for (unsigned i=0; i < slv2_strings_size(hints); ++i) - printf("\t\t\t%s\n", slv2_strings_get_at(hints, i)); - slv2_strings_free(hints); + for (unsigned i=0; i < slv2_values_size(hints); ++i) + printf("\t\t\t%s\n", slv2_value_as_uri(slv2_values_get_at(hints, i))); + slv2_values_free(hints); } void @@ -100,40 +100,42 @@ print_plugin(SLV2Plugin p) const char* class_label = slv2_plugin_class_get_label(slv2_plugin_get_class(p)); printf("\tClass: %s\n\n", class_label); - if (slv2_plugin_has_latency(p)) - printf("\tHas latency: yes\n\n"); - else + if (slv2_plugin_has_latency(p)) { + uint32_t latency_port = slv2_plugin_get_latency_port(p); + printf("\tHas latency: yes, reported by port %d\n\n", latency_port); + } else { printf("\tHas latency: no\n\n"); - + } + printf("\tBinary: %s\n\n", slv2_plugin_get_library_uri(p)); printf("\tData URIs:\n"); SLV2Strings data_uris = slv2_plugin_get_data_uris(p); - for (unsigned i=0; i < slv2_strings_size(data_uris); ++i) - printf("\t\t%s\n", slv2_strings_get_at(data_uris, i)); + for (unsigned i=0; i < slv2_values_size(data_uris); ++i) + printf("\t\t%s\n", slv2_value_as_uri(slv2_values_get_at(data_uris, i))); /* Properties */ SLV2Strings v = slv2_plugin_get_properties(p); - if (slv2_strings_size(v) > 0) + if (slv2_values_size(v) > 0) printf("\n\tProperties:\n"); - for (unsigned i=0; i < slv2_strings_size(v); ++i) - printf("\t\t%s\n", slv2_strings_get_at(v, i)); - slv2_strings_free(v); + for (unsigned i=0; i < slv2_values_size(v); ++i) + printf("\t\t%s\n", slv2_value_as_uri(slv2_values_get_at(v, i))); + slv2_values_free(v); /* Hints */ v = slv2_plugin_get_hints(p); - if (slv2_strings_size(v) > 0) + if (slv2_values_size(v) > 0) printf("\n\tHints:\n"); - for (unsigned i=0; i < slv2_strings_size(v); ++i) - printf("\t\t%s\n", slv2_strings_get_at(v, i)); - slv2_strings_free(v); + for (unsigned i=0; i < slv2_values_size(v); ++i) + printf("\t\t%s\n", slv2_value_as_uri(slv2_values_get_at(v, i))); + slv2_values_free(v); /* Ports */ -- cgit v1.2.1