diff options
-rw-r--r-- | doc/reference.doxygen.in | 2 | ||||
-rw-r--r-- | hosts/lv2_jack_host.c | 63 | ||||
-rw-r--r-- | hosts/lv2_simple_jack_host.c | 53 | ||||
-rw-r--r-- | slv2/lv2_ui.h | 4 | ||||
-rw-r--r-- | slv2/plugin.h | 78 | ||||
-rw-r--r-- | slv2/pluginclass.h | 6 | ||||
-rw-r--r-- | slv2/pluginclasses.h | 2 | ||||
-rw-r--r-- | slv2/plugininstance.h | 6 | ||||
-rw-r--r-- | slv2/plugins.h | 2 | ||||
-rw-r--r-- | slv2/pluginui.h | 14 | ||||
-rw-r--r-- | slv2/pluginuis.h | 4 | ||||
-rw-r--r-- | slv2/port.h | 84 | ||||
-rw-r--r-- | slv2/types.h | 19 | ||||
-rw-r--r-- | slv2/util.h | 21 | ||||
-rw-r--r-- | slv2/world.h | 4 | ||||
-rw-r--r-- | src/plugin.c | 261 | ||||
-rw-r--r-- | src/pluginclass.c | 32 | ||||
-rw-r--r-- | src/pluginclasses.c | 7 | ||||
-rw-r--r-- | src/plugininstance.c | 10 | ||||
-rw-r--r-- | src/plugins.c | 5 | ||||
-rw-r--r-- | src/pluginui.c | 33 | ||||
-rw-r--r-- | src/pluginuiinstance.c | 13 | ||||
-rw-r--r-- | src/pluginuis.c | 5 | ||||
-rw-r--r-- | src/port.c | 170 | ||||
-rw-r--r-- | src/query.c | 8 | ||||
-rw-r--r-- | src/slv2_internal.h | 47 | ||||
-rw-r--r-- | src/util.c | 16 | ||||
-rw-r--r-- | src/value.c | 90 | ||||
-rw-r--r-- | src/values.c | 9 | ||||
-rw-r--r-- | src/world.c | 89 | ||||
-rw-r--r-- | utils/lv2_inspect.c | 78 | ||||
-rw-r--r-- | utils/lv2_list.c | 2 |
32 files changed, 649 insertions, 588 deletions
diff --git a/doc/reference.doxygen.in b/doc/reference.doxygen.in index 386c312..38118c8 100644 --- a/doc/reference.doxygen.in +++ b/doc/reference.doxygen.in @@ -472,8 +472,6 @@ INPUT = @SLV2_SRCDIR@/doc/mainpage.dox \ @SLV2_SRCDIR@/slv2/pluginuiinstance.h \ @SLV2_SRCDIR@/slv2/pluginuis.h \ @SLV2_SRCDIR@/slv2/port.h \ - @SLV2_SRCDIR@/slv2/portsignature.h \ - @SLV2_SRCDIR@/slv2/template.h \ @SLV2_SRCDIR@/slv2/types.h \ @SLV2_SRCDIR@/slv2/util.h \ @SLV2_SRCDIR@/slv2/value.h \ diff --git a/hosts/lv2_jack_host.c b/hosts/lv2_jack_host.c index 96d18cb..5caa8b8 100644 --- a/hosts/lv2_jack_host.c +++ b/hosts/lv2_jack_host.c @@ -18,6 +18,7 @@ #include CONFIG_H_PATH +#define _XOPEN_SOURCE 500 #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -57,12 +58,13 @@ struct JackHost { SLV2Plugin plugin; /**< Plugin "class" (actually just a few strings) */ SLV2Instance instance; /**< Plugin "instance" (loaded shared lib) */ uint32_t num_ports; /**< Size of the two following arrays: */ - struct Port* ports; /** Port array of size num_ports */ + struct Port* ports; /**< Port array of size num_ports */ SLV2Value input_class; /**< Input port class (URI) */ SLV2Value output_class; /**< Output port class (URI) */ SLV2Value control_class; /**< Control port class (URI) */ SLV2Value audio_class; /**< Audio port class (URI) */ SLV2Value midi_class; /**< MIDI port class (URI) */ + SLV2Value optional; /**< lv2:connectionOptional port property */ }; @@ -91,11 +93,12 @@ main(int argc, char** argv) host.control_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_CONTROL); host.audio_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_AUDIO); host.midi_class = slv2_value_new_uri(world, SLV2_PORT_CLASS_MIDI); + host.optional = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "connectionOptional"); /* Find the plugin to run */ - const char* plugin_uri = (argc == 2) ? argv[1] : NULL; + const char* plugin_uri_str = (argc == 2) ? argv[1] : NULL; - if (!plugin_uri) { + if (!plugin_uri_str) { fprintf(stderr, "\nYou must specify a plugin URI to load.\n"); fprintf(stderr, "\nKnown plugins:\n\n"); list_plugins(plugins); @@ -103,22 +106,39 @@ main(int argc, char** argv) return EXIT_FAILURE; } - printf("URI:\t%s\n", plugin_uri); + printf("URI:\t%s\n", plugin_uri_str); + + SLV2Value plugin_uri = slv2_value_new_uri(world, plugin_uri_str); host.plugin = slv2_plugins_get_by_uri(plugins, plugin_uri); + slv2_value_free(plugin_uri); if (!host.plugin) { - fprintf(stderr, "Failed to find plugin %s.\n", plugin_uri); + fprintf(stderr, "Failed to find plugin %s.\n", plugin_uri_str); slv2_world_free(world); return EXIT_FAILURE; } /* Get the plugin's name */ - char* name = slv2_plugin_get_name(host.plugin); - printf("Name:\t%s\n", name); + SLV2Value name = slv2_plugin_get_name(host.plugin); + const char* name_str = slv2_value_as_string(name); + printf("Plugin Name:\t%s\n", slv2_value_as_string(name)); + + /* Truncate plugin name to suit JACK (if necessary) */ + char* jack_name = NULL; + if (strlen(name_str) >= (unsigned)jack_client_name_size() - 1) { + jack_name = calloc(jack_client_name_size(), sizeof(char)); + strncpy(jack_name, name_str, jack_client_name_size() - 1); + } else { + jack_name = strdup(name_str); + } - /* Connect to JACK (with plugin name as client name) */ - host.jack_client = jack_client_open(name, JackNullOption, NULL); - free(name); + /* Connect to JACK */ + printf("JACK Name:\t%s\n", name_str); + host.jack_client = jack_client_open(jack_name, JackNullOption, NULL); + + free(jack_name); + slv2_value_free(name); + if (!host.jack_client) die("Failed to connect to JACK."); else @@ -175,6 +195,7 @@ main(int argc, char** argv) slv2_value_free(host.control_class); slv2_value_free(host.audio_class); slv2_value_free(host.midi_class); + slv2_value_free(host.optional); slv2_plugins_free(world, plugins); slv2_world_free(world); @@ -211,8 +232,9 @@ create_port(struct JackHost* host, slv2_instance_connect_port(host->instance, port_index, NULL); - /* Get the port symbol (label) for console printing */ - char* symbol = slv2_port_get_symbol(host->plugin, port->slv2_port); + /* Get the port symbol for console printing */ + SLV2Value symbol = slv2_port_get_symbol(host->plugin, port->slv2_port); + const char* symbol_str = slv2_value_as_string(symbol); enum JackPortFlags jack_flags = 0; if (slv2_port_is_a(host->plugin, port->slv2_port, host->input_class)) { @@ -221,7 +243,7 @@ create_port(struct JackHost* host, } else if (slv2_port_is_a(host->plugin, port->slv2_port, host->output_class)) { jack_flags = JackPortIsOutput; port->direction = OUTPUT; - } else if (slv2_port_has_property(host->plugin, port->slv2_port, SLV2_NAMESPACE_LV2 "connectionOptional")) { + } else if (slv2_port_has_property(host->plugin, port->slv2_port, host->optional)) { slv2_instance_connect_port(host->instance, port_index, NULL); } else { die("Mandatory port has unknown type (neither input or output)"); @@ -230,8 +252,11 @@ create_port(struct JackHost* host, /* Set control values */ if (slv2_port_is_a(host->plugin, port->slv2_port, host->control_class)) { port->type = CONTROL; - port->control = slv2_port_get_default_value(host->plugin, port->slv2_port); - printf("Set %s to %f\n", symbol, host->ports[port_index].control); + SLV2Value def; + slv2_port_get_range(host->plugin, port->slv2_port, &def, NULL, NULL); + port->control = slv2_value_as_float(def); + printf("Set %s to %f\n", symbol_str, host->ports[port_index].control); + slv2_value_free(def); } else if (slv2_port_is_a(host->plugin, port->slv2_port, host->audio_class)) { port->type = AUDIO; } else if (slv2_port_is_a(host->plugin, port->slv2_port, host->midi_class)) { @@ -245,11 +270,11 @@ create_port(struct JackHost* host, break; case AUDIO: port->jack_port = jack_port_register(host->jack_client, - symbol, JACK_DEFAULT_AUDIO_TYPE, jack_flags, 0); + symbol_str, JACK_DEFAULT_AUDIO_TYPE, jack_flags, 0); break; case MIDI: port->jack_port = jack_port_register(host->jack_client, - symbol, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); + symbol_str, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); port->midi_buffer = lv2midi_new(MIDI_BUFFER_SIZE); slv2_instance_connect_port(host->instance, port_index, port->midi_buffer); break; @@ -258,8 +283,6 @@ create_port(struct JackHost* host, slv2_instance_connect_port(host->instance, port_index, NULL); fprintf(stderr, "WARNING: Unknown port type, port not connected.\n"); } - - free(symbol); } @@ -355,6 +378,6 @@ list_plugins(SLV2Plugins list) { for (unsigned i=0; i < slv2_plugins_size(list); ++i) { SLV2Plugin p = slv2_plugins_get_at(list, i); - printf("%s\n", slv2_plugin_get_uri(p)); + printf("%s\n", slv2_value_as_uri(slv2_plugin_get_uri(p))); } } diff --git a/hosts/lv2_simple_jack_host.c b/hosts/lv2_simple_jack_host.c index 89bc904..cf50d86 100644 --- a/hosts/lv2_simple_jack_host.c +++ b/hosts/lv2_simple_jack_host.c @@ -16,6 +16,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ +#define _XOPEN_SOURCE 500 #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -68,9 +69,9 @@ main(int argc, char** argv) SLV2Plugins plugins = slv2_world_get_all_plugins(host.world); /* Find the plugin to run */ - const char* plugin_uri = (argc == 2) ? argv[1] : NULL; + const char* plugin_uri_str = (argc == 2) ? argv[1] : NULL; - if (!plugin_uri) { + if (!plugin_uri_str) { fprintf(stderr, "\nYou must specify a plugin URI to load.\n"); fprintf(stderr, "\nKnown plugins:\n\n"); list_plugins(plugins); @@ -78,22 +79,38 @@ main(int argc, char** argv) return EXIT_FAILURE; } - printf("URI:\t%s\n", plugin_uri); + printf("URI:\t%s\n", plugin_uri_str); + SLV2Value plugin_uri = slv2_value_new_uri(host.world, plugin_uri_str); host.plugin = slv2_plugins_get_by_uri(plugins, plugin_uri); + slv2_value_free(plugin_uri); if (!host.plugin) { - fprintf(stderr, "Failed to find plugin %s.\n", plugin_uri); + fprintf(stderr, "Failed to find plugin %s.\n", plugin_uri_str); slv2_world_free(host.world); return EXIT_FAILURE; } /* Get the plugin's name */ - char* name = slv2_plugin_get_name(host.plugin); - printf("Name:\t%s\n", name); + SLV2Value name = slv2_plugin_get_name(host.plugin); + const char* name_str = slv2_value_as_string(name); + printf("Plugin Name:\t%s\n", slv2_value_as_string(name)); + + /* Truncate plugin name to suit JACK (if necessary) */ + char* jack_name = NULL; + if (strlen(name_str) >= (unsigned)jack_client_name_size() - 1) { + jack_name = calloc(jack_client_name_size(), sizeof(char)); + strncpy(jack_name, name_str, jack_client_name_size() - 1); + } else { + jack_name = strdup(name_str); + } + + /* Connect to JACK */ + printf("JACK Name:\t%s\n", name_str); + host.jack_client = jack_client_open(jack_name, JackNullOption, NULL); - /* Connect to JACK (with plugin name as client name) */ - host.jack_client = jack_client_open(name, JackNullOption, NULL); - free(name); + free(jack_name); + slv2_value_free(name); + if (!host.jack_client) die("Failed to connect to JACK."); else @@ -176,7 +193,8 @@ create_port(struct JackHost* host, SLV2Port port = slv2_plugin_get_port_by_index(host->plugin, index); /* Get the port symbol (label) for console printing */ - char* symbol = slv2_port_get_symbol(host->plugin, port); + SLV2Value symbol = slv2_port_get_symbol(host->plugin, port); + const char* symbol_str = slv2_value_as_string(symbol); /* Initialize the port array elements */ host->jack_ports[index] = NULL; @@ -187,16 +205,19 @@ create_port(struct JackHost* host, /* Set default control values for inputs */ if (slv2_port_is_a(host->plugin, port, host->input_class)) { - host->controls[index] = slv2_port_get_default_value(host->plugin, port); - printf("Set %s to %f\n", symbol, host->controls[index]); + SLV2Value def; + slv2_port_get_range(host->plugin, port, &def, NULL, NULL); + host->controls[index] = slv2_value_as_float(def); + printf("Set %s to %f\n", symbol_str, host->controls[index]); + slv2_value_free(def); } slv2_instance_connect_port(host->instance, index, &host->controls[index]); } else if (slv2_port_is_a(host->plugin, port, host->audio_class)) { - host->jack_ports[index] = jack_port_register(host->jack_client, symbol, - JACK_DEFAULT_AUDIO_TYPE, + host->jack_ports[index] = jack_port_register(host->jack_client, + symbol_str, JACK_DEFAULT_AUDIO_TYPE, slv2_port_is_a(host->plugin, port, host->input_class) ? JackPortIsInput : JackPortIsOutput, 0); @@ -205,8 +226,6 @@ create_port(struct JackHost* host, // Simple examples don't have to be robust :) die("ERROR: Unknown port type, aborting messily!\n"); } - - free(symbol); } @@ -234,6 +253,6 @@ list_plugins(SLV2Plugins list) { for (unsigned i=0; i < slv2_plugins_size(list); ++i) { SLV2Plugin p = slv2_plugins_get_at(list, i); - printf("%s\n", slv2_plugin_get_uri(p)); + printf("%s\n", slv2_value_as_uri(slv2_plugin_get_uri(p))); } } diff --git a/slv2/lv2_ui.h b/slv2/lv2_ui.h index 744a71c..4e99232 100644 --- a/slv2/lv2_ui.h +++ b/slv2/lv2_ui.h @@ -189,8 +189,8 @@ typedef struct _LV2UI_Descriptor { as the first parameter of @c write_function.
@param host_data Data required from the host for instantiation.
The type of this depends on the RDF class of the UI.
- If the UI type does not specify anything to be passed
- here, the host should pass NULL.
+ If the UI type does not specify anything to be passed
+ here, the host should pass NULL.
@param widget A pointer to an LV2UI_Widget. The UI will write a
widget pointer to this location (what type of widget
depends on the RDF class of the UI) that will be the
diff --git a/slv2/plugin.h b/slv2/plugin.h index 3dc63a8..a3ae1f0 100644 --- a/slv2/plugin.h +++ b/slv2/plugin.h @@ -76,7 +76,7 @@ slv2_plugin_verify(SLV2Plugin plugin); * * Time = O(1) */ -const char* +SLV2Value slv2_plugin_get_uri(SLV2Plugin plugin); @@ -95,7 +95,7 @@ slv2_plugin_get_uri(SLV2Plugin plugin); * * Time = O(1) */ -const char* +SLV2Value slv2_plugin_get_bundle_uri(SLV2Plugin plugin); @@ -124,7 +124,7 @@ slv2_plugin_get_data_uris(SLV2Plugin plugin); * * Time = O(1) */ -const char* +SLV2Value slv2_plugin_get_library_uri(SLV2Plugin plugin); @@ -136,7 +136,7 @@ slv2_plugin_get_library_uri(SLV2Plugin plugin); * * Time = Query */ -char* +SLV2Value slv2_plugin_get_name(SLV2Plugin plugin); @@ -163,9 +163,19 @@ slv2_plugin_get_class(SLV2Plugin plugin); * Time = Query */ SLV2Values -slv2_plugin_get_value(SLV2Plugin p, - SLV2URIType predicate_type, - const char* predicate); +slv2_plugin_get_value(SLV2Plugin p, + SLV2Value predicate); + + +/** Get a value associated with the plugin in a plugin's data files. + * + * This function is identical to slv2_plugin_get_value, but takes a QName + * string parameter for a predicate instead of an SLV2Value, which may be + * more convenient. + */ +SLV2Values +slv2_plugin_get_value_by_qname(SLV2Plugin p, + const char* predicate); /** Get a value associated with some subject in a plugin's data files. @@ -189,9 +199,8 @@ slv2_plugin_get_value(SLV2Plugin p, */ SLV2Values slv2_plugin_get_value_for_subject(SLV2Plugin p, - SLV2Value subject, - SLV2URIType predicate_type, - const char* predicate); + SLV2Value subject_uri, + SLV2Value predicate_uri); /** Return whether a feature is supported by a plugin. @@ -202,8 +211,8 @@ slv2_plugin_get_value_for_subject(SLV2Plugin p, * Time = Query */ bool -slv2_plugin_has_feature(SLV2Plugin p, - const char* feature); +slv2_plugin_has_feature(SLV2Plugin p, + SLV2Value feature_uri); /** Get the LV2 Features supported (required or optionally) by a plugin. @@ -261,20 +270,6 @@ uint32_t slv2_plugin_get_num_ports(SLV2Plugin p); -/** Get the "template" (port signature) of this plugin. - * - * The template is intended to be all the basic information a host might - * want to know about a plugin's inputs and outputs (e.g. to determine if the - * plugin is appropriate for a given situation). Using this function is much, - * much faster than using the individual functions repeatedly to get the same - * information (since each call results in a single query). - * - * Time = Query - */ -SLV2Template -slv2_plugin_get_template(SLV2Plugin p); - - /** Return whether or not the plugin introduces (and reports) latency. * * The index of the latency port can be found with slv2_plugin_get_latency_port @@ -298,29 +293,32 @@ slv2_plugin_has_latency(SLV2Plugin p); * Time = Query */ uint32_t -slv2_plugin_get_latency_port(SLV2Plugin p); +slv2_plugin_get_latency_port_index(SLV2Plugin p); -/** Query a plugin for a single variable. +/** Query a plugin for a single variable (i.e. SELECT a single ?value). * * \param plugin The plugin to query. * \param sparql_str A SPARQL SELECT query. * \param variable The index of the variable to return results for - * (i.e. with "<code>SELECT ?foo ?bar</code>" foo is 0, and bar is 1). + * (e.g. with "<code>SELECT ?foo ?bar</code>" foo=0, bar=1). * \return All matches for \a variable. * * Time = Query */ SLV2Values -slv2_plugin_simple_query(SLV2Plugin plugin, - const char* sparql_str, - unsigned variable); +slv2_plugin_query_variable(SLV2Plugin plugin, + const char* sparql_str, + unsigned variable); /** Query a plugin and return the number of results found. * + * Note that this function will work, but is mostly meaningless for queries + * that are not SELECT DISTINCT. + * * \param plugin The plugin to query. - * \param sparql_str A SPARQL SELECT query. + * \param sparql_str A SPARQL SELECT DISTINCT query. * * Time = Query */ @@ -344,13 +342,15 @@ slv2_plugin_get_port_by_index(SLV2Plugin plugin, /** Get a port on this plugin by \a symbol. * * To perform multiple calls on a port, the returned value should - * be cached and used repeatedly. + * be cached and used repeatedly. Note this function is slower + * than slv2_plugin_get_port_by_index, especially on plugins + * with a very large number of ports. * * Time = O(n) */ SLV2Port -slv2_plugin_get_port_by_symbol(SLV2Plugin plugin, - const char* symbol); +slv2_plugin_get_port_by_symbol(SLV2Plugin plugin, + SLV2Value symbol); /** Get a list of all UIs available for this plugin. @@ -376,7 +376,7 @@ slv2_plugin_get_uis(SLV2Plugin plugin); * * Time = Query */ -char* +SLV2Value slv2_plugin_get_author_name(SLV2Plugin plugin); @@ -387,7 +387,7 @@ slv2_plugin_get_author_name(SLV2Plugin plugin); * * Time = Query */ -char* +SLV2Value slv2_plugin_get_author_email(SLV2Plugin plugin); @@ -398,7 +398,7 @@ slv2_plugin_get_author_email(SLV2Plugin plugin); * * Time = Query */ -char* +SLV2Value slv2_plugin_get_author_homepage(SLV2Plugin plugin); diff --git a/slv2/pluginclass.h b/slv2/pluginclass.h index 14449ab..790cc15 100644 --- a/slv2/pluginclass.h +++ b/slv2/pluginclass.h @@ -37,7 +37,7 @@ extern "C" { * * Time = O(1) */ -const char* slv2_plugin_class_get_parent_uri(SLV2PluginClass plugin_class); +SLV2Value slv2_plugin_class_get_parent_uri(SLV2PluginClass plugin_class); /** Get the URI of this plugin class. @@ -46,7 +46,7 @@ const char* slv2_plugin_class_get_parent_uri(SLV2PluginClass plugin_class); * * Time = O(1) */ -const char* slv2_plugin_class_get_uri(SLV2PluginClass plugin_class); +SLV2Value slv2_plugin_class_get_uri(SLV2PluginClass plugin_class); /** Get the label of this plugin class, ie "Oscillators". @@ -55,7 +55,7 @@ const char* slv2_plugin_class_get_uri(SLV2PluginClass plugin_class); * * Time = O(1) */ -const char* slv2_plugin_class_get_label(SLV2PluginClass plugin_class); +SLV2Value slv2_plugin_class_get_label(SLV2PluginClass plugin_class); /** Get the subclasses of this plugin class. diff --git a/slv2/pluginclasses.h b/slv2/pluginclasses.h index f283356..470e782 100644 --- a/slv2/pluginclasses.h +++ b/slv2/pluginclasses.h @@ -47,7 +47,7 @@ slv2_plugin_classes_size(SLV2PluginClasses list); */ SLV2PluginClass slv2_plugin_classes_get_by_uri(SLV2PluginClasses list, - const char* uri); + SLV2Value uri); /** Get a plugin from the list by index. diff --git a/slv2/plugininstance.h b/slv2/plugininstance.h index 8f2b7fd..383e404 100644 --- a/slv2/plugininstance.h +++ b/slv2/plugininstance.h @@ -30,6 +30,8 @@ extern "C" { typedef struct _InstanceImpl* SLV2InstanceImpl; +/** \cond IGNORE */ + /* Instance of a plugin. * * The LV2 descriptor and handle of this are exposed to allow inlining of @@ -44,6 +46,8 @@ typedef struct _Instance { SLV2InstanceImpl pimpl; ///< Private implementation }* SLV2Instance; +/** \endcond */ + /** \defgroup slv2_library Plugin library access * @@ -147,7 +151,7 @@ slv2_instance_run(SLV2Instance instance, assert(instance->lv2_descriptor); assert(instance->lv2_handle); - if (instance->lv2_descriptor->run) + /*if (instance->lv2_descriptor->run)*/ instance->lv2_descriptor->run(instance->lv2_handle, sample_count); } diff --git a/slv2/plugins.h b/slv2/plugins.h index 274696e..3290c4f 100644 --- a/slv2/plugins.h +++ b/slv2/plugins.h @@ -58,7 +58,7 @@ slv2_plugins_size(SLV2Plugins list); */ SLV2Plugin slv2_plugins_get_by_uri(SLV2Plugins list, - const char* uri); + SLV2Value uri); /** Get a plugin from the list by index. diff --git a/slv2/pluginui.h b/slv2/pluginui.h index b01bf34..8fc1f06 100644 --- a/slv2/pluginui.h +++ b/slv2/pluginui.h @@ -34,7 +34,7 @@ extern "C" { * * Time = O(1) */ -const char* +SLV2Value slv2_ui_get_uri(SLV2UI ui); @@ -50,14 +50,14 @@ slv2_ui_get_classes(SLV2UI ui); /** Check whether a plugin UI is a given type. * - * \param ui The Plugin UI - * \param type_uri The URI of the LV2 UI type to check this UI against + * \param ui The Plugin UI + * \param class_uri The URI of the LV2 UI type to check this UI against * * Time = O(1) */ bool -slv2_ui_is_a(SLV2UI ui, const char* type_uri); - +slv2_ui_is_a(SLV2UI ui, SLV2Value class_uri); + /** Get the URI for a Plugin UI's bundle. * @@ -65,7 +65,7 @@ slv2_ui_is_a(SLV2UI ui, const char* type_uri); * * Time = O(1) */ -const char* +SLV2Value slv2_ui_get_bundle_uri(SLV2UI ui); @@ -75,7 +75,7 @@ slv2_ui_get_bundle_uri(SLV2UI ui); * * Time = O(1) */ -const char* +SLV2Value slv2_ui_get_binary_uri(SLV2UI ui); diff --git a/slv2/pluginuis.h b/slv2/pluginuis.h index 6c91d45..7eacc4a 100644 --- a/slv2/pluginuis.h +++ b/slv2/pluginuis.h @@ -57,8 +57,8 @@ slv2_uis_size(SLV2UIs list); * \return NULL if plugin with \a url not found in \a list. */ SLV2UI -slv2_uis_get_by_uri(SLV2UIs list, - const char* uri); +slv2_uis_get_by_uri(SLV2UIs list, + SLV2Value uri); /** Get a plugin from the list by index. diff --git a/slv2/port.h b/slv2/port.h index 072417b..5c0549c 100644 --- a/slv2/port.h +++ b/slv2/port.h @@ -38,9 +38,9 @@ extern "C" { * Time = Query */ SLV2Values -slv2_port_get_value(SLV2Plugin plugin, - SLV2Port port, - const char* property_uri); +slv2_port_get_value_by_qname(SLV2Plugin plugin, + SLV2Port port, + const char* property_uri); /** Return the LV2 port properties of a port. @@ -57,9 +57,9 @@ slv2_port_get_properties(SLV2Plugin plugin, * Time = Query */ bool -slv2_port_has_property(SLV2Plugin p, - SLV2Port port, - const char* property_uri); +slv2_port_has_property(SLV2Plugin p, + SLV2Port port, + SLV2Value property_uri); /** Return whether a port is an event port and supports a certain event type. @@ -67,21 +67,19 @@ slv2_port_has_property(SLV2Plugin p, * Time = Query */ bool -slv2_port_supports_event(SLV2Plugin p, - SLV2Port port, - const char* event_uri); +slv2_port_supports_event(SLV2Plugin p, + SLV2Port port, + SLV2Value event_uri); -/** Get the symbol of a port given the index. +/** Get the symbol of a port. * * The 'symbol' is a short string, a valid C identifier. - * Returned string must be free()'d by caller. - * - * \return NULL when index is out of range + * Returned value is owned by \a port and must not be freed. * * Time = Query */ -char* +SLV2Value slv2_port_get_symbol(SLV2Plugin plugin, SLV2Port port); @@ -93,7 +91,7 @@ slv2_port_get_symbol(SLV2Plugin plugin, * * Time = Query */ -char* +SLV2Value slv2_port_get_name(SLV2Plugin plugin, SLV2Port port); @@ -129,56 +127,22 @@ slv2_port_is_a(SLV2Plugin plugin, SLV2Port port, SLV2Value port_class); -#if 0 -/** Get the direction (input, output) of a port. - * - * Time = Query - */ -SLV2PortDirection -slv2_port_get_direction(SLV2Plugin plugin, - SLV2Port port); - -/** Get the data type of a port. - * - * Time = Query - */ -SLV2PortDataType -slv2_port_get_data_type(SLV2Plugin plugin, - SLV2Port port); -#endif - - -/** Get the default value of a port. - * - * Only valid for ports with a data type of lv2:float. - * - * Time = Query - */ -float -slv2_port_get_default_value(SLV2Plugin plugin, - SLV2Port port); - - -/** Get the minimum value of a port. - * - * Only valid for ports with a data type of lv2:float. - * - * Time = Query - */ -float -slv2_port_get_minimum_value(SLV2Plugin plugin, - SLV2Port port); - -/** Get the maximum value of a port. +/** Get the default, minimum, and maximum values of a port. * - * Only valid for ports with a data type of lv2:float. + * @a def, @a min, and @a max are outputs, pass pointers to uninitialized + * (i.e. NOT created with slv2_value_new) SLV2Value variables. These will + * be set to point at new values (which must be freed by the caller using + * slv2_value_free), or NULL if the value does not exist. * * Time = Query */ -float -slv2_port_get_maximum_value(SLV2Plugin plugin, - SLV2Port port); +void +slv2_port_get_range(SLV2Plugin p, + SLV2Port port, + SLV2Value* def, + SLV2Value* min, + SLV2Value* max); /** @} */ diff --git a/slv2/types.h b/slv2/types.h index 0318a98..ce73fc3 100644 --- a/slv2/types.h +++ b/slv2/types.h @@ -36,25 +36,10 @@ extern "C" { #define SLV2_PORT_CLASS_EVENT "http://lv2plug.in/ns/ext/event#EventPort" -/** The format of a URI string. - * - * Full URI: http://example.org/foo - * QName: lv2:Plugin - */ -typedef enum _SLV2URIType { - SLV2_URI, - SLV2_QNAME -} SLV2URIType; - - /** A port on a plugin. Opaque, but valid to compare to NULL. */ typedef struct _SLV2Port* SLV2Port; -/** The port (I/O) signature of a plugin. Opaque, but valid to compare to NULL. */ -typedef struct _SLV2PortSignature* SLV2PortSignature; - - /** A plugin. Opaque, but valid to compare to NULL. */ typedef struct _SLV2Plugin* SLV2Plugin; @@ -79,10 +64,6 @@ typedef void* SLV2PluginClasses; typedef struct _SLV2Value* SLV2Value; -/** A plugin template (collection of port signatures). */ -typedef void* SLV2Template; - - /** A collection of typed values. */ typedef void* SLV2Values; diff --git a/slv2/util.h b/slv2/util.h index 60c5d4d..cba7af3 100644 --- a/slv2/util.h +++ b/slv2/util.h @@ -40,27 +40,6 @@ extern "C" { const char* slv2_uri_to_path(const char* uri); -/** Append \a suffix to \a *dst, reallocating \a dst as necessary. - * - * \a dst will (possibly) be freed, it must be dynamically allocated with malloc - * or NULL. - */ -void -slv2_strappend(char** dst, const char* suffix); - - -/** Join all arguments into one string. - * - * Arguments are not modified, return value must be free()'d. - */ -char* -slv2_strjoin(const char* first, ...); - - -char* -slv2_vstrjoin(const char** first, va_list args_list); - - /** @} */ #ifdef __cplusplus diff --git a/slv2/world.h b/slv2/world.h index 9d82dd7..e9c328d 100644 --- a/slv2/world.h +++ b/slv2/world.h @@ -107,8 +107,8 @@ slv2_world_load_all(SLV2World world); * Time = Query */ void -slv2_world_load_bundle(SLV2World world, - const char* bundle_uri); +slv2_world_load_bundle(SLV2World world, + SLV2Value bundle_uri); /** Get the parent of all other plugin classes, lv2:Plugin. diff --git a/src/plugin.c b/src/plugin.c index aee89ae..6ab21b4 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -32,15 +32,16 @@ #include <slv2/pluginuis.h> -/* private */ +/* private + * ownership of uri is taken */ SLV2Plugin -slv2_plugin_new(SLV2World world, librdf_uri* uri, librdf_uri* bundle_uri, librdf_uri* binary_uri) +slv2_plugin_new(SLV2World world, SLV2Value uri, librdf_uri* bundle_uri, librdf_uri* binary_uri) { struct _SLV2Plugin* plugin = malloc(sizeof(struct _SLV2Plugin)); plugin->world = world; - plugin->plugin_uri = librdf_new_uri_from_uri(uri); - plugin->bundle_uri = librdf_new_uri_from_uri(bundle_uri); - plugin->binary_uri = librdf_new_uri_from_uri(binary_uri); + plugin->plugin_uri = uri; + plugin->bundle_uri = slv2_value_new_librdf_uri(world, bundle_uri); + plugin->binary_uri = slv2_value_new_librdf_uri(world, binary_uri); plugin->plugin_class = NULL; plugin->data_uris = slv2_values_new(); plugin->ports = raptor_new_sequence((void (*)(void*))&slv2_port_free, NULL); @@ -55,13 +56,13 @@ slv2_plugin_new(SLV2World world, librdf_uri* uri, librdf_uri* bundle_uri, librdf void slv2_plugin_free(SLV2Plugin p) { - librdf_free_uri(p->plugin_uri); + slv2_value_free(p->plugin_uri); p->plugin_uri = NULL; - librdf_free_uri(p->bundle_uri); + slv2_value_free(p->bundle_uri); p->bundle_uri = NULL; - librdf_free_uri(p->binary_uri); + slv2_value_free(p->binary_uri); p->binary_uri = NULL; raptor_free_sequence(p->ports); @@ -84,40 +85,6 @@ slv2_plugin_free(SLV2Plugin p) } -// FIXME: ew -librdf_query_results* -slv2_plugin_query(SLV2Plugin plugin, - const char* sparql_str); - - -/* -SLV2Plugin -slv2_plugin_duplicate(SLV2Plugin p) -{ - assert(p); - struct _Plugin* result = malloc(sizeof(struct _Plugin)); - result->world = p->world; - result->plugin_uri = librdf_new_uri_from_uri(p->plugin_uri); - - //result->bundle_url = strdup(p->bundle_url); - result->binary_uri = strdup(p->binary_uri); - - 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) - raptor_sequence_push(result->ports, slv2_port_duplicate(raptor_sequence_get_at(p->ports, i))); - - result->storage = NULL; - result->rdf = NULL; - - return result; -} -*/ - - /** comparator for sorting */ int slv2_port_compare_by_index(const void* a, const void* b) @@ -161,29 +128,32 @@ slv2_plugin_load(SLV2Plugin p) "SELECT DISTINCT ?class WHERE { <> a ?class }"; librdf_query* q = librdf_new_query(p->world->world, "sparql", - NULL, query, p->plugin_uri); + NULL, query, slv2_value_as_librdf_uri(p->plugin_uri)); librdf_query_results* results = librdf_query_execute(q, p->rdf); while (!librdf_query_results_finished(results)) { librdf_node* class_node = librdf_query_results_get_binding_value(results, 0); librdf_uri* class_uri = librdf_node_get_uri(class_node); - assert(class_uri); - const char* class_uri_str = (const char*)librdf_uri_as_string(class_uri); + + SLV2Value class = slv2_value_new_librdf_uri(p->world, class_uri); - if ( ! librdf_uri_equals(class_uri, p->world->lv2_plugin_class->uri) ) { + if ( ! slv2_value_equals(class, p->world->lv2_plugin_class->uri)) { SLV2PluginClass plugin_class = slv2_plugin_classes_get_by_uri( - p->world->plugin_classes, class_uri_str); + p->world->plugin_classes, class); + librdf_free_node(class_node); if (plugin_class) { p->plugin_class = plugin_class; + slv2_value_free(class); break; } } + slv2_value_free(class); librdf_query_results_next(results); } @@ -204,7 +174,7 @@ slv2_plugin_load(SLV2Plugin p) "} ORDER BY (?index)"; q = librdf_new_query(p->world->world, "sparql", - NULL, query, p->plugin_uri); + NULL, query, slv2_value_as_librdf_uri(p->plugin_uri)); results = librdf_query_execute(q, p->rdf); @@ -231,7 +201,7 @@ slv2_plugin_load(SLV2Plugin p) // Create a new SLV2Port, and add to template if (this_index == num_ports) { assert(this_index == last_index + 1); - this_port = slv2_port_new((unsigned)atoi(index), symbol); + this_port = slv2_port_new(p->world, (unsigned)atoi(index), symbol); raptor_sequence_push(p->ports, this_port); ++num_ports; ++last_index; @@ -258,30 +228,30 @@ slv2_plugin_load(SLV2Plugin p) } -const char* +SLV2Value slv2_plugin_get_uri(SLV2Plugin p) { assert(p); assert(p->plugin_uri); - return (const char*)librdf_uri_as_string(p->plugin_uri); + return p->plugin_uri; } -const char* +SLV2Value slv2_plugin_get_bundle_uri(SLV2Plugin p) { assert(p); assert(p->bundle_uri); - return (const char*)librdf_uri_as_string(p->bundle_uri); + return p->bundle_uri; } -const char* +SLV2Value slv2_plugin_get_library_uri(SLV2Plugin p) { assert(p); assert(p->binary_uri); - return (const char*)librdf_uri_as_string(p->binary_uri); + return p->binary_uri; } @@ -352,7 +322,8 @@ slv2_plugin_verify(SLV2Plugin plugin) librdf_free_query_results(results); if ( ! (has_type && has_name && has_license && has_port) ) { - fprintf(stderr, "Invalid LV2 Plugin %s\n", slv2_plugin_get_uri(plugin)); + fprintf(stderr, "Invalid LV2 Plugin %s\n", + slv2_value_as_uri(slv2_plugin_get_uri(plugin))); return false; } else { return true; @@ -360,49 +331,73 @@ slv2_plugin_verify(SLV2Plugin plugin) } -char* +SLV2Value slv2_plugin_get_name(SLV2Plugin plugin) { - char* result = NULL; - SLV2Values prop = slv2_plugin_get_value(plugin, SLV2_QNAME, "doap:name"); + SLV2Values results = slv2_plugin_get_value_by_qname(plugin, "doap:name"); + SLV2Value ret = NULL; - // FIXME: lang? guaranteed to be the untagged one? - if (prop && slv2_values_size(prop) > 0) { - SLV2Value val = slv2_values_get_at(prop, 0); + // FIXME: lang? + + if (results && slv2_values_size(results) > 0) { + SLV2Value val = slv2_values_get_at(results, 0); if (slv2_value_is_string(val)) - result = strdup(slv2_value_as_string(val)); + ret = slv2_value_duplicate(val); } - if (prop) - slv2_values_free(prop); + if (results) + slv2_values_free(results); - return result; + return ret; } SLV2Values -slv2_plugin_get_value(SLV2Plugin p, - SLV2URIType predicate_type, - const char* predicate) +slv2_plugin_get_value(SLV2Plugin p, + SLV2Value predicate) { char* query = NULL; /* Hack around broken RASQAL, full URI predicates don't work :/ */ - if (predicate_type == SLV2_URI) { + if (predicate->type == SLV2_VALUE_URI) { query = slv2_strjoin( - "PREFIX slv2predicate: <", predicate, ">", + "PREFIX slv2predicate: <", slv2_value_as_string(predicate), ">", "SELECT DISTINCT ?value WHERE { \n" "<> slv2predicate: ?value \n" "}\n", NULL); - } else { + } else if (predicate->type == SLV2_VALUE_QNAME) { query = slv2_strjoin( "SELECT DISTINCT ?value WHERE { \n" - "<> ", predicate, " ?value \n" + "<> ", slv2_value_as_string(predicate), " ?value \n" "}\n", NULL); + } else { + fprintf(stderr, "slv2_plugin_get_value error: " + "predicate is not a URI or QNAME\n"); + return NULL; } - SLV2Values result = slv2_plugin_simple_query(p, query, 0); + SLV2Values result = slv2_plugin_query_variable(p, query, 0); + + free(query); + + return result; +} + + +/* internal */ +SLV2Values +slv2_plugin_get_value_by_qname(SLV2Plugin p, + const char* predicate) +{ + char* query = NULL; + + query = slv2_strjoin( + "SELECT DISTINCT ?value WHERE { \n" + "<> ", predicate, " ?value \n" + "}\n", NULL); + + SLV2Values result = slv2_plugin_query_variable(p, query, 0); free(query); @@ -413,12 +408,11 @@ slv2_plugin_get_value(SLV2Plugin p, SLV2Values slv2_plugin_get_value_for_subject(SLV2Plugin p, SLV2Value subject, - SLV2URIType predicate_type, - const char* predicate) + SLV2Value predicate) { if ( ! slv2_value_is_uri(subject)) { fprintf(stderr, "slv2_plugin_get_value_for_subject error: " - "passed non-URI subject\n"); + "subject is not a URI\n"); return NULL; } @@ -428,20 +422,25 @@ slv2_plugin_get_value_for_subject(SLV2Plugin p, char* subject_token = slv2_value_get_turtle_token(subject); - if (predicate_type == SLV2_URI) { + if (predicate->type == SLV2_VALUE_URI) { query = slv2_strjoin( "PREFIX slv2predicate: <", predicate, ">", "SELECT DISTINCT ?value WHERE { \n", subject_token, " slv2predicate: ?value \n" "}\n", NULL); - } else { + } else if (predicate->type == SLV2_VALUE_URI) { query = slv2_strjoin( "SELECT DISTINCT ?value WHERE { \n", subject_token, " ", predicate, " ?value \n" "}\n", NULL); + } else { + fprintf(stderr, "slv2_plugin_get_value error: " + "predicate is not a URI or QNAME\n"); + free(subject_token); + return NULL; } - SLV2Values result = slv2_plugin_simple_query(p, query, 0); + SLV2Values result = slv2_plugin_query_variable(p, query, 0); free(query); free(subject_token); @@ -453,14 +452,14 @@ slv2_plugin_get_value_for_subject(SLV2Plugin p, SLV2Values slv2_plugin_get_properties(SLV2Plugin p) { - return slv2_plugin_get_value(p, SLV2_QNAME, "lv2:pluginProperty"); + return slv2_plugin_get_value_by_qname(p, "lv2:pluginProperty"); } SLV2Values slv2_plugin_get_hints(SLV2Plugin p) { - return slv2_plugin_get_value(p, SLV2_QNAME, "lv2:pluginHint"); + return slv2_plugin_get_value_by_qname(p, "lv2:pluginHint"); } @@ -478,13 +477,13 @@ bool slv2_plugin_has_latency(SLV2Plugin p) { const char* const query = - "SELECT DISTINCT ?index WHERE {\n" + "SELECT ?index WHERE {\n" " <> lv2:port ?port .\n" " ?port lv2:portProperty lv2:reportsLatency ;\n" " lv2:index ?index .\n" "}\n"; - SLV2Values results = slv2_plugin_simple_query(p, query, 0); + SLV2Values results = slv2_plugin_query_variable(p, query, 0); const bool latent = (slv2_values_size(results) > 0); slv2_values_free(results); @@ -493,16 +492,16 @@ slv2_plugin_has_latency(SLV2Plugin p) uint32_t -slv2_plugin_get_latency_port(SLV2Plugin p) +slv2_plugin_get_latency_port_index(SLV2Plugin p) { const char* const query = - "SELECT DISTINCT ?index WHERE {\n" + "SELECT ?index WHERE {\n" " <> lv2:port ?port .\n" " ?port lv2:portProperty lv2:reportsLatency ;\n" " lv2:index ?index .\n" "}\n"; - SLV2Values result = slv2_plugin_simple_query(p, query, 0); + SLV2Values result = slv2_plugin_query_variable(p, query, 0); // FIXME: need a sane error handling strategy assert(slv2_values_size(result) > 0); @@ -514,19 +513,14 @@ slv2_plugin_get_latency_port(SLV2Plugin p) bool -slv2_plugin_has_feature(SLV2Plugin p, - const char* feature) +slv2_plugin_has_feature(SLV2Plugin p, + SLV2Value feature) { - assert(feature); SLV2Values features = slv2_plugin_get_supported_features(p); - SLV2Value val = slv2_value_new(p->world, SLV2_VALUE_URI, feature); - - const bool ret = features && slv2_values_contains(features, val); + const bool ret = features && feature && slv2_values_contains(features, feature); slv2_values_free(features); - slv2_value_free(val); - return ret; } @@ -541,7 +535,7 @@ slv2_plugin_get_supported_features(SLV2Plugin p) " { <> lv2:requiredFeature ?feature }\n" "}\n"; - SLV2Values result = slv2_plugin_simple_query(p, query, 0); + SLV2Values result = slv2_plugin_query_variable(p, query, 0); return result; } @@ -550,14 +544,14 @@ slv2_plugin_get_supported_features(SLV2Plugin p) SLV2Values slv2_plugin_get_optional_features(SLV2Plugin p) { - return slv2_plugin_get_value(p, SLV2_QNAME, "lv2:optionalFeature"); + return slv2_plugin_get_value_by_qname(p, "lv2:optionalFeature"); } SLV2Values slv2_plugin_get_required_features(SLV2Plugin p) { - return slv2_plugin_get_value(p, SLV2_QNAME, "lv2:requiredFeature"); + return slv2_plugin_get_value_by_qname(p, "lv2:requiredFeature"); } @@ -573,16 +567,15 @@ slv2_plugin_get_port_by_index(SLV2Plugin p, SLV2Port -slv2_plugin_get_port_by_symbol(SLV2Plugin p, - const char* symbol) +slv2_plugin_get_port_by_symbol(SLV2Plugin p, + SLV2Value symbol) { if (!p->rdf) slv2_plugin_load(p); - // FIXME: sort plugins and do a binary search for (int i=0; i < raptor_sequence_size(p->ports); ++i) { SLV2Port port = raptor_sequence_get_at(p->ports, i); - if (!strcmp(port->symbol, symbol)) + if (slv2_value_equals(port->symbol, symbol)) return port; } @@ -590,79 +583,79 @@ slv2_plugin_get_port_by_symbol(SLV2Plugin p, } -char* +SLV2Value slv2_plugin_get_author_name(SLV2Plugin plugin) { - char* ret = NULL; + SLV2Value ret = NULL; const char* const query = - "SELECT DISTINCT ?name WHERE {\n" + "SELECT ?name WHERE {\n" " <> doap:maintainer ?maint . \n" " ?maint foaf:name ?name . \n" "}\n"; - SLV2Values result = slv2_plugin_simple_query(plugin, query, 0); + SLV2Values results = slv2_plugin_query_variable(plugin, query, 0); - if (result && slv2_values_size(result) > 0) { - SLV2Value val = slv2_values_get_at(result, 0); + if (results && slv2_values_size(results) > 0) { + SLV2Value val = slv2_values_get_at(results, 0); if (slv2_value_is_string(val)) - ret = strdup(slv2_value_as_string(val)); + ret = slv2_value_duplicate(val); } - if (result) - slv2_values_free(result); + if (results) + slv2_values_free(results); return ret; } -char* +SLV2Value slv2_plugin_get_author_email(SLV2Plugin plugin) { - char* ret = NULL; + SLV2Value ret = NULL; const char* const query = - "SELECT DISTINCT ?email WHERE {\n" + "SELECT ?email WHERE {\n" " <> doap:maintainer ?maint . \n" " ?maint foaf:mbox ?email . \n" "}\n"; - - SLV2Values result = slv2_plugin_simple_query(plugin, query, 0); - if (result && slv2_values_size(result) > 0) { - SLV2Value val = slv2_values_get_at(result, 0); - if (slv2_value_is_string(val)) - ret = strdup(slv2_value_as_string(val)); + SLV2Values results = slv2_plugin_query_variable(plugin, query, 0); + + if (results && slv2_values_size(results) > 0) { + SLV2Value val = slv2_values_get_at(results, 0); + if (slv2_value_is_uri(val)) + ret = slv2_value_duplicate(val); } - if (result) - slv2_values_free(result); + if (results) + slv2_values_free(results); return ret; } -char* +SLV2Value slv2_plugin_get_author_homepage(SLV2Plugin plugin) { - char* ret = NULL; + SLV2Value ret = NULL; const char* const query = - "SELECT DISTINCT ?email WHERE {\n" + "SELECT ?page WHERE {\n" " <> doap:maintainer ?maint . \n" - " ?maint foaf:homepage ?email . \n" + " ?maint foaf:homepage ?page . \n" "}\n"; - - SLV2Values result = slv2_plugin_simple_query(plugin, query, 0); - if (result && slv2_values_size(result) > 0) { - SLV2Value val = slv2_values_get_at(result, 0); - if (slv2_value_is_string(val)) - ret = strdup(slv2_value_as_string(val)); + SLV2Values results = slv2_plugin_query_variable(plugin, query, 0); + + if (results && slv2_values_size(results) > 0) { + SLV2Value val = slv2_values_get_at(results, 0); + if (slv2_value_is_uri(val)) + ret = slv2_value_duplicate(val); } - if (result) - slv2_values_free(result); + if (results) + slv2_values_free(results); return ret; } diff --git a/src/pluginclass.c b/src/pluginclass.c index 383e458..e2f36d4 100644 --- a/src/pluginclass.c +++ b/src/pluginclass.c @@ -22,55 +22,57 @@ #include <stdlib.h> #include <string.h> #include <slv2/pluginclass.h> +#include <slv2/value.h> #include "slv2_internal.h" +/* private */ SLV2PluginClass -slv2_plugin_class_new(SLV2World world, const char* parent_uri, const char* uri, const char* label) +slv2_plugin_class_new(SLV2World world, librdf_uri* parent_uri, librdf_uri* uri, const char* label) { SLV2PluginClass plugin_class = (SLV2PluginClass)malloc(sizeof(struct _SLV2PluginClass)); plugin_class->world = world; if (parent_uri) - plugin_class->parent_uri = librdf_new_uri(world->world, (const unsigned char*)parent_uri); + plugin_class->parent_uri = slv2_value_new_librdf_uri(world, parent_uri); else plugin_class->parent_uri = NULL; - plugin_class->uri = librdf_new_uri(world->world, (const unsigned char*)uri); - plugin_class->label = strdup(label); + plugin_class->uri = slv2_value_new_librdf_uri(world, uri); + plugin_class->label = slv2_value_new(world, SLV2_VALUE_STRING, label); return plugin_class; } +/* private */ void slv2_plugin_class_free(SLV2PluginClass plugin_class) { assert(plugin_class->uri); - librdf_free_uri(plugin_class->uri); - if (plugin_class->parent_uri) - librdf_free_uri(plugin_class->parent_uri); - free(plugin_class->label); + slv2_value_free(plugin_class->uri); + slv2_value_free(plugin_class->parent_uri); + slv2_value_free(plugin_class->label); free(plugin_class); } -const char* +SLV2Value slv2_plugin_class_get_parent_uri(SLV2PluginClass plugin_class) { if (plugin_class->parent_uri) - return (const char*)librdf_uri_as_string(plugin_class->parent_uri); + return plugin_class->parent_uri; else return NULL; } -const char* +SLV2Value slv2_plugin_class_get_uri(SLV2PluginClass plugin_class) { assert(plugin_class->uri); - return (const char*)librdf_uri_as_string(plugin_class->uri); + return plugin_class->uri; } -const char* +SLV2Value slv2_plugin_class_get_label(SLV2PluginClass plugin_class) { return plugin_class->label; @@ -85,8 +87,8 @@ slv2_plugin_class_get_children(SLV2PluginClass plugin_class) for (int i=0; i < raptor_sequence_size(plugin_class->world->plugin_classes); ++i) { SLV2PluginClass c = raptor_sequence_get_at(plugin_class->world->plugin_classes, i); - const char* parent = slv2_plugin_class_get_parent_uri(c); - if (parent && !strcmp(slv2_plugin_class_get_uri(plugin_class), parent)) + SLV2Value parent = slv2_plugin_class_get_parent_uri(c); + if (parent && slv2_value_equals(slv2_plugin_class_get_uri(plugin_class), parent)) raptor_sequence_push(result, c); } diff --git a/src/pluginclasses.c b/src/pluginclasses.c index 26c56d2..a7bc088 100644 --- a/src/pluginclasses.c +++ b/src/pluginclasses.c @@ -22,10 +22,10 @@ #include <limits.h> #include <librdf.h> #include "slv2_internal.h" +#include <slv2/value.h> #include <slv2/pluginclass.h> #include <slv2/pluginclasses.h> - SLV2PluginClasses slv2_plugin_classes_new() @@ -51,7 +51,7 @@ slv2_plugin_classes_size(SLV2PluginClasses list) SLV2PluginClass -slv2_plugin_classes_get_by_uri(SLV2PluginClasses list, const char* uri) +slv2_plugin_classes_get_by_uri(SLV2PluginClasses list, SLV2Value uri) { // good old fashioned binary search @@ -64,7 +64,8 @@ slv2_plugin_classes_get_by_uri(SLV2PluginClasses list, const char* uri) SLV2PluginClass p = raptor_sequence_get_at(list, i); - const int cmp = strcmp(slv2_plugin_class_get_uri(p), uri); + const int cmp = strcmp(slv2_value_as_uri(slv2_plugin_class_get_uri(p)), + slv2_value_as_uri(uri)); if (cmp == 0) return p; diff --git a/src/plugininstance.c b/src/plugininstance.c index c0111ac..8a75e27 100644 --- a/src/plugininstance.c +++ b/src/plugininstance.c @@ -43,7 +43,7 @@ slv2_plugin_instantiate(SLV2Plugin plugin, local_features[0] = NULL; } - const char* const lib_uri = slv2_plugin_get_library_uri(plugin); + const char* const lib_uri = slv2_value_as_uri(slv2_plugin_get_library_uri(plugin)); const char* const lib_path = slv2_uri_to_path(lib_uri); if (!lib_path) @@ -67,7 +67,9 @@ slv2_plugin_instantiate(SLV2Plugin plugin, // Search for plugin by URI // FIXME: Kluge to get bundle path (containing directory of binary) - const char* bundle_path = slv2_uri_to_path(slv2_plugin_get_bundle_uri(plugin)); + const char* bundle_path = slv2_uri_to_path(slv2_value_as_uri( + slv2_plugin_get_bundle_uri(plugin))); + //printf("Bundle path: %s\n", bundle_path); for (uint32_t i=0; 1; ++i) { @@ -76,10 +78,10 @@ slv2_plugin_instantiate(SLV2Plugin plugin, if (!ld) { fprintf(stderr, "Did not find plugin %s in %s\n", - slv2_plugin_get_uri(plugin), lib_path); + slv2_value_as_uri(slv2_plugin_get_uri(plugin)), lib_path); dlclose(lib); break; // return NULL - } else if (!strcmp(ld->URI, slv2_plugin_get_uri(plugin))) { + } else if (!strcmp(ld->URI, slv2_value_as_uri(slv2_plugin_get_uri(plugin)))) { assert(plugin->plugin_uri); diff --git a/src/plugins.c b/src/plugins.c index ac8b863..f1774e8 100644 --- a/src/plugins.c +++ b/src/plugins.c @@ -69,7 +69,7 @@ slv2_plugins_size(SLV2Plugins list) SLV2Plugin -slv2_plugins_get_by_uri(SLV2Plugins list, const char* uri) +slv2_plugins_get_by_uri(SLV2Plugins list, SLV2Value uri) { // good old fashioned binary search @@ -82,7 +82,8 @@ slv2_plugins_get_by_uri(SLV2Plugins list, const char* uri) SLV2Plugin p = raptor_sequence_get_at(list, i); - const int cmp = strcmp(slv2_plugin_get_uri(p), uri); + const int cmp = strcmp(slv2_value_as_uri(slv2_plugin_get_uri(p)), + slv2_value_as_uri(uri)); if (cmp == 0) return p; diff --git a/src/pluginui.c b/src/pluginui.c index 5de3dcb..9835e41 100644 --- a/src/pluginui.c +++ b/src/pluginui.c @@ -38,16 +38,16 @@ slv2_ui_new(SLV2World world, struct _SLV2UI* ui = malloc(sizeof(struct _SLV2UI)); ui->world = world; - ui->uri = librdf_new_uri_from_uri(uri); - ui->binary_uri = librdf_new_uri_from_uri(binary_uri); + ui->uri = slv2_value_new_librdf_uri(world, uri); + ui->binary_uri = slv2_value_new_librdf_uri(world, binary_uri); assert(ui->binary_uri); // FIXME: kludge - char* bundle = strdup((const char*)librdf_uri_as_string(ui->binary_uri)); + char* bundle = strdup(slv2_value_as_string(ui->binary_uri)); char* last_slash = strrchr(bundle, '/') + 1; *last_slash = '\0'; - ui->bundle_uri = librdf_new_uri(world->world, (const unsigned char*)bundle); + ui->bundle_uri = slv2_value_new_uri(world, bundle); free(bundle); ui->classes = slv2_values_new(); @@ -61,13 +61,13 @@ slv2_ui_new(SLV2World world, void slv2_ui_free(SLV2UI ui) { - librdf_free_uri(ui->uri); + slv2_value_free(ui->uri); ui->uri = NULL; - librdf_free_uri(ui->bundle_uri); + slv2_value_free(ui->bundle_uri); ui->bundle_uri = NULL; - librdf_free_uri(ui->binary_uri); + slv2_value_free(ui->binary_uri); ui->binary_uri = NULL; slv2_values_free(ui->classes); @@ -76,12 +76,12 @@ slv2_ui_free(SLV2UI ui) } -const char* +SLV2Value slv2_ui_get_uri(SLV2UI ui) { assert(ui); assert(ui->uri); - return (const char*)librdf_uri_as_string(ui->uri); + return ui->uri; } @@ -93,29 +93,26 @@ slv2_ui_get_classes(SLV2UI ui) bool -slv2_ui_is_a(SLV2UI ui, const char* type_uri) +slv2_ui_is_a(SLV2UI ui, SLV2Value ui_class_uri) { - SLV2Value type = slv2_value_new(ui->world, SLV2_VALUE_URI, type_uri); - bool ret = slv2_values_contains(ui->classes, type); - slv2_value_free(type); - return ret; + return slv2_values_contains(ui->classes, ui_class_uri); } -const char* +SLV2Value slv2_ui_get_bundle_uri(SLV2UI ui) { assert(ui); assert(ui->bundle_uri); - return (const char*)librdf_uri_as_string(ui->bundle_uri); + return ui->bundle_uri; } -const char* +SLV2Value slv2_ui_get_binary_uri(SLV2UI ui) { assert(ui); assert(ui->binary_uri); - return (const char*)librdf_uri_as_string(ui->binary_uri); + return ui->binary_uri; } diff --git a/src/pluginuiinstance.c b/src/pluginuiinstance.c index f6457ba..f87f4b7 100644 --- a/src/pluginuiinstance.c +++ b/src/pluginuiinstance.c @@ -48,7 +48,7 @@ slv2_ui_instantiate(SLV2Plugin plugin, ((LV2_Feature**)features)[0] = NULL; } - const char* const lib_uri = slv2_ui_get_binary_uri(ui); + const char* const lib_uri = slv2_value_as_string(slv2_ui_get_binary_uri(ui)); const char* const lib_path = slv2_uri_to_path(lib_uri); if (!lib_path) @@ -70,7 +70,7 @@ slv2_ui_instantiate(SLV2Plugin plugin, return NULL; } else { - const char* bundle_path = slv2_uri_to_path(slv2_ui_get_bundle_uri(ui)); + const char* bundle_path = slv2_uri_to_path(slv2_value_as_uri(slv2_ui_get_bundle_uri(ui))); for (uint32_t i=0; 1; ++i) { @@ -78,16 +78,15 @@ slv2_ui_instantiate(SLV2Plugin plugin, if (!ld) { fprintf(stderr, "Did not find UI %s in %s\n", - slv2_ui_get_uri(ui), lib_path); + slv2_value_as_uri(slv2_ui_get_uri(ui)), lib_path); dlclose(lib); break; // return NULL - } else if (!strcmp(ld->URI, slv2_ui_get_uri(ui))) { - + } else if (!strcmp(ld->URI, slv2_value_as_uri(slv2_ui_get_uri(ui)))) { assert(plugin->plugin_uri); printf("Found UI %s at index %u in:\n\t%s\n\n", - librdf_uri_as_string(plugin->plugin_uri), i, lib_path); + slv2_value_as_uri(plugin->plugin_uri), i, lib_path); assert(ld->instantiate); @@ -96,7 +95,7 @@ slv2_ui_instantiate(SLV2Plugin plugin, struct _SLV2UIInstanceImpl* impl = malloc(sizeof(struct _SLV2UIInstanceImpl)); impl->lv2ui_descriptor = ld; impl->lv2ui_handle = ld->instantiate(ld, - slv2_plugin_get_uri(plugin), + slv2_value_as_uri(slv2_plugin_get_uri(plugin)), (char*)bundle_path, write_function, controller, diff --git a/src/pluginuis.c b/src/pluginuis.c index 2fe5c71..1cf0fb9 100644 --- a/src/pluginuis.c +++ b/src/pluginuis.c @@ -54,7 +54,7 @@ slv2_uis_size(SLV2UIs list) SLV2UI -slv2_uis_get_by_uri(SLV2UIs list, const char* uri) +slv2_uis_get_by_uri(SLV2UIs list, SLV2Value uri) { // good old fashioned binary search @@ -67,7 +67,8 @@ slv2_uis_get_by_uri(SLV2UIs list, const char* uri) SLV2UI ui = raptor_sequence_get_at(list, i); - const int cmp = strcmp(slv2_ui_get_uri(ui), uri); + const int cmp = strcmp(slv2_value_as_uri(slv2_ui_get_uri(ui)), + slv2_value_as_uri(uri)); if (cmp == 0) return ui; @@ -31,11 +31,11 @@ /* private */ SLV2Port -slv2_port_new(uint32_t index, const char* symbol/*, const char* node_id*/) +slv2_port_new(SLV2World world, uint32_t index, const char* symbol) { struct _SLV2Port* port = malloc(sizeof(struct _SLV2Port)); port->index = index; - port->symbol = strdup(symbol); + port->symbol = slv2_value_new(world, SLV2_VALUE_STRING, symbol); port->classes = slv2_values_new(); //port->node_id = strdup(node_id); return port; @@ -46,8 +46,8 @@ slv2_port_new(uint32_t index, const char* symbol/*, const char* node_id*/) void slv2_port_free(SLV2Port port) { - free(port->symbol); slv2_values_free(port->classes); + slv2_value_free(port->symbol); free(port); } @@ -56,10 +56,10 @@ slv2_port_free(SLV2Port port) SLV2Port slv2_port_duplicate(SLV2Port port) { - SLV2Port result = malloc(sizeof(struct _SLV2Port)); - result->index = port->index; - result->symbol = strdup(port->symbol); - return result; + SLV2Port ret = malloc(sizeof(struct _SLV2Port)); + ret->index = port->index; + ret->symbol = slv2_value_duplicate(port->symbol); + return ret; } @@ -77,42 +77,42 @@ slv2_port_is_a(SLV2Plugin plugin, bool -slv2_port_has_property(SLV2Plugin p, - SLV2Port port, - const char* property) +slv2_port_has_property(SLV2Plugin p, + SLV2Port port, + SLV2Value property) { assert(property); - SLV2Values result = NULL; + SLV2Values results = NULL; char* query = slv2_strjoin( "SELECT DISTINCT ?port WHERE {\n" - "<", librdf_uri_as_string(p->plugin_uri), "> lv2:port ?port ." - "?port lv2:symbol \"", port->symbol, "\";\n", - " lv2:portProperty <", property, "> .\n}", NULL); + "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port ." + "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n", + " lv2:portProperty <", slv2_value_as_uri(property), "> .\n}", NULL); - result = slv2_plugin_simple_query(p, query, 0); + results = slv2_plugin_query_variable(p, query, 0); - const bool ret = (slv2_values_size(result) > 0); + const bool ret = (slv2_values_size(results) > 0); free(query); - free(result); + free(results); return ret; } bool -slv2_port_supports_event(SLV2Plugin p, - SLV2Port port, - const char* event) +slv2_port_supports_event(SLV2Plugin p, + SLV2Port port, + SLV2Value event) { assert(event); char* query = slv2_strjoin( "ASK WHERE {\n" - "<", librdf_uri_as_string(p->plugin_uri), "> lv2:port ?port ." - "?port lv2:symbol \"", port->symbol, "\";\n", + "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port ." + "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n", " lv2ev:supportsEvent <", event, "> .\n" "}", NULL); @@ -129,59 +129,47 @@ slv2_port_supports_event(SLV2Plugin p, SLV2Values -slv2_port_get_value(SLV2Plugin p, - SLV2Port port, - const char* property) +slv2_port_get_value_by_qname(SLV2Plugin p, + SLV2Port port, + const char* property) { assert(property); - - SLV2Values result = NULL; + SLV2Values results = NULL; char* query = slv2_strjoin( "SELECT DISTINCT ?value WHERE {\n" - "<", librdf_uri_as_string(p->plugin_uri), "> lv2:port ?port .\n" - "?port lv2:symbol \"", port->symbol, "\";\n\t", + "<", 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}", NULL); - result = slv2_plugin_simple_query(p, query, 0); + results = slv2_plugin_query_variable(p, query, 0); free(query); - - return result; + return results; } -char* +SLV2Value slv2_port_get_symbol(SLV2Plugin p, SLV2Port port) { - char* symbol = NULL; - - SLV2Values result = slv2_port_get_value(p, port, "lv2:symbol"); - - if (result && slv2_values_size(result) == 1) - symbol = strdup(slv2_value_as_string(slv2_values_get_at(result, 0))); - - slv2_values_free(result); - - return symbol; + return port->symbol; } -char* +SLV2Value slv2_port_get_name(SLV2Plugin p, SLV2Port port) { - char* name = NULL; - - SLV2Values result = slv2_port_get_value(p, port, "lv2:name"); + SLV2Value ret = NULL; + SLV2Values results = slv2_port_get_value_by_qname(p, port, "lv2:name"); - if (result && slv2_values_size(result) == 1) - name = strdup(slv2_value_as_string(slv2_values_get_at(result, 0))); + if (results && slv2_values_size(results) == 1) + ret = slv2_value_duplicate(slv2_values_get_at(results, 0)); - slv2_values_free(result); + slv2_values_free(results); - return name; + return ret; } @@ -193,54 +181,52 @@ slv2_port_get_classes(SLV2Plugin p, } -float -slv2_port_get_default_value(SLV2Plugin p, - SLV2Port port) -{ - float value = 0.0f; - - SLV2Values result = slv2_port_get_value(p, port, "lv2:default"); - - if (result && slv2_values_size(result) == 1) - value = slv2_value_as_float(slv2_values_get_at(result, 0)); - - slv2_values_free(result); - - return value; -} - - -float -slv2_port_get_minimum_value(SLV2Plugin p, - SLV2Port port) +void +slv2_port_get_range(SLV2Plugin p, + SLV2Port port, + SLV2Value* def, + SLV2Value* min, + SLV2Value* max) { - float value = 0.0f; - - SLV2Values result = slv2_port_get_value(p, port, "lv2:minimum"); + if (def) + *def = NULL; + if (min) + *min = NULL; + if (max) + *max = NULL; - if (result && slv2_values_size(result) == 1) - value = slv2_value_as_float(slv2_values_get_at(result, 0)); + char* query = slv2_strjoin( + "SELECT DISTINCT ?def ?min ?max WHERE {\n" + "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n" + "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\".\n", + "OPTIONAL { ?port lv2:default ?def }\n", + "OPTIONAL { ?port lv2:minimum ?min }\n", + "OPTIONAL { ?port lv2:maximum ?max }\n", + "\n}", NULL); - slv2_values_free(result); + librdf_query_results* results = slv2_plugin_query(p, query); - return value; -} + while (!librdf_query_results_finished(results)) { + librdf_node* def_node = librdf_query_results_get_binding_value(results, 0); + librdf_node* min_node = librdf_query_results_get_binding_value(results, 1); + librdf_node* max_node = librdf_query_results_get_binding_value(results, 2); + if (def && def_node && !*def) + *def = slv2_value_new_librdf_node(p->world, def_node); + if (min && min_node && !*min) + *min = slv2_value_new_librdf_node(p->world, min_node); + if (max && max_node && !*max) + *max = slv2_value_new_librdf_node(p->world, max_node); -float -slv2_port_get_maximum_value(SLV2Plugin p, - SLV2Port port) -{ - float value = 0.0f; - - SLV2Values result = slv2_port_get_value(p, port, "lv2:maximum"); + if ((!def || *def) && (!min || *min) && (!max || *max)) + break; - if (result && slv2_values_size(result) == 1) - value = slv2_value_as_float(slv2_values_get_at(result, 0)); - - slv2_values_free(result); + librdf_query_results_next(results); + } + + librdf_free_query_results(results); - return value; + free(query); } @@ -248,6 +234,6 @@ SLV2Values slv2_port_get_properties(SLV2Plugin p, SLV2Port port) { - return slv2_port_get_value(p, port, "lv2:portProperty"); + return slv2_port_get_value_by_qname(p, port, "lv2:portProperty"); } diff --git a/src/query.c b/src/query.c index 988e117..cc1349a 100644 --- a/src/query.c +++ b/src/query.c @@ -129,7 +129,7 @@ slv2_plugin_query(SLV2Plugin plugin, if (!plugin->rdf) slv2_plugin_load(plugin); - librdf_uri* base_uri = plugin->plugin_uri; + librdf_uri* base_uri = slv2_value_as_librdf_uri(plugin->plugin_uri); char* query_str = slv2_strjoin(slv2_query_prefixes, sparql_str, NULL); @@ -161,9 +161,9 @@ slv2_plugin_query(SLV2Plugin plugin, /** Query a single variable */ SLV2Values -slv2_plugin_simple_query(SLV2Plugin plugin, - const char* sparql_str, - unsigned variable) +slv2_plugin_query_variable(SLV2Plugin plugin, + const char* sparql_str, + unsigned variable) { assert(variable < INT_MAX); diff --git a/src/slv2_internal.h b/src/slv2_internal.h index 06c432d..eda0abd 100644 --- a/src/slv2_internal.h +++ b/src/slv2_internal.h @@ -38,12 +38,12 @@ extern "C" { /** Reference to a port on some plugin. */ struct _SLV2Port { uint32_t index; ///< lv2:index - char* symbol; ///< lv2:symbol + SLV2Value symbol; ///< lv2:symbol SLV2Values classes; ///< rdf:type }; -SLV2Port slv2_port_new(uint32_t index, const char* symbol); +SLV2Port slv2_port_new(SLV2World world, uint32_t index, const char* symbol); SLV2Port slv2_port_duplicate(SLV2Port port); void slv2_port_free(SLV2Port port); @@ -59,9 +59,9 @@ void slv2_port_free(SLV2Port port); */ struct _SLV2Plugin { struct _SLV2World* world; - librdf_uri* plugin_uri; - librdf_uri* bundle_uri; ///< Bundle directory plugin was loaded from - librdf_uri* binary_uri; ///< lv2:binary + SLV2Value plugin_uri; + SLV2Value bundle_uri; ///< Bundle directory plugin was loaded from + SLV2Value binary_uri; ///< lv2:binary SLV2PluginClass plugin_class; raptor_sequence* data_uris; ///< rdfs::seeAlso raptor_sequence* ports; @@ -69,7 +69,7 @@ struct _SLV2Plugin { librdf_model* rdf; }; -SLV2Plugin slv2_plugin_new(SLV2World world, librdf_uri* uri, librdf_uri* bundle_uri, librdf_uri* binary_uri); +SLV2Plugin slv2_plugin_new(SLV2World world, SLV2Value uri, librdf_uri* bundle_uri, librdf_uri* binary_uri); void slv2_plugin_load(SLV2Plugin p); void slv2_plugin_free(SLV2Plugin plugin); @@ -113,13 +113,13 @@ struct _SLV2UIInstanceImpl { struct _SLV2PluginClass { struct _SLV2World* world; - librdf_uri* parent_uri; - librdf_uri* uri; - char* label; + SLV2Value parent_uri; + SLV2Value uri; + SLV2Value label; }; -SLV2PluginClass slv2_plugin_class_new(SLV2World world, const char* parent_uri, - const char* uri, const char* label); +SLV2PluginClass slv2_plugin_class_new(SLV2World world, librdf_uri* parent_uri, + librdf_uri* uri, const char* label); void slv2_plugin_class_free(SLV2PluginClass plugin_class); @@ -148,6 +148,8 @@ struct _SLV2World { librdf_node* lv2_specification_node; librdf_node* lv2_plugin_node; librdf_node* rdf_a_node; + librdf_node* xsd_integer_node; + librdf_node* xsd_decimal_node; }; /** Load all bundles found in \a search_path. @@ -175,9 +177,9 @@ slv2_world_load_file(SLV2World world, librdf_uri* file_uri); struct _SLV2UI { struct _SLV2World* world; - librdf_uri* uri; - librdf_uri* bundle_uri; - librdf_uri* binary_uri; + SLV2Value uri; + SLV2Value bundle_uri; + SLV2Value binary_uri; SLV2Values classes; }; @@ -195,6 +197,7 @@ void slv2_ui_free(SLV2UI ui); typedef enum _SLV2ValueType { SLV2_VALUE_URI, + SLV2_VALUE_QNAME, SLV2_VALUE_STRING, SLV2_VALUE_INT, SLV2_VALUE_FLOAT, @@ -210,9 +213,21 @@ struct _SLV2Value { } val; }; -SLV2Value slv2_value_new(SLV2World world, SLV2ValueType type, const char* val); -SLV2Value slv2_value_new_librdf_uri(SLV2World world, librdf_uri* uri); +SLV2Value slv2_value_new(SLV2World world, SLV2ValueType type, const char* val); +SLV2Value slv2_value_new_librdf_node(SLV2World world, librdf_node* node); +SLV2Value slv2_value_new_librdf_uri(SLV2World world, librdf_uri* uri); +void slv2_value_set_numerics_from_string(SLV2Value val); +librdf_uri* slv2_value_as_librdf_uri(SLV2Value value); + +/* ********* Values ********* */ + +void slv2_values_set_at(SLV2Values list, unsigned index, void* value); + + +/* String utility functions */ + +char* slv2_strjoin(const char* first, ...); #ifdef __cplusplus @@ -25,23 +25,11 @@ #include <slv2/util.h> -void -slv2_strappend(char** dst, const char* suffix) -{ - assert(dst); - assert(*dst); - assert(suffix); - - const size_t new_length = strlen((char*)*dst) + strlen((char*)suffix) + 1; - *dst = realloc(*dst, (new_length * sizeof(char))); - assert(dst); - strcat((char*)*dst, (char*)suffix); -} - - char* slv2_strjoin(const char* first, ...) { + /* FIXME: This is, in fact, as stupid as it looks */ + size_t len = strlen(first); char* result = NULL; va_list args; diff --git a/src/value.c b/src/value.c index 498fdfd..f1d2731 100644 --- a/src/value.c +++ b/src/value.c @@ -43,24 +43,77 @@ slv2_value_new(SLV2World world, SLV2ValueType type, const char* str) } else { val->str_val = strdup(str); } - + + slv2_value_set_numerics_from_string(val); + + return val; +} + + +/* private */ +void +slv2_value_set_numerics_from_string(SLV2Value val) +{ + if (!val) + return; + // FIXME: locale kludges to work around librdf bug char* locale = strdup(setlocale(LC_NUMERIC, NULL)); - if (type == SLV2_VALUE_INT) { + if (val->type == SLV2_VALUE_INT) { char* endptr = 0; setlocale(LC_NUMERIC, "POSIX"); - val->val.int_val = strtol(str, &endptr, 10); + val->val.int_val = strtol(val->str_val, &endptr, 10); setlocale(LC_NUMERIC, locale); - } else if (type == SLV2_VALUE_FLOAT) { + } else if (val->type == SLV2_VALUE_FLOAT) { char* endptr = 0; setlocale(LC_NUMERIC, "POSIX"); - val->val.float_val = strtod(str, &endptr); + val->val.float_val = strtod(val->str_val, &endptr); setlocale(LC_NUMERIC, locale); } - + free(locale); +} + +/* private */ +SLV2Value +slv2_value_new_librdf_node(SLV2World world, librdf_node* node) +{ + SLV2Value val = (SLV2Value)malloc(sizeof(struct _SLV2Value)); + val->type = SLV2_VALUE_STRING; + val->str_val = NULL; + + librdf_uri* datatype_uri = NULL; + + switch (librdf_node_get_type(node)) { + case LIBRDF_NODE_TYPE_RESOURCE: + val->type = SLV2_VALUE_URI; + val->val.uri_val = librdf_node_get_uri(node); + val->str_val = (char*)librdf_uri_as_string(val->val.uri_val); + break; + case LIBRDF_NODE_TYPE_LITERAL: + datatype_uri = librdf_node_get_literal_value_datatype_uri(node); + if (datatype_uri) { + if (librdf_uri_equals(datatype_uri, librdf_node_get_uri(world->xsd_integer_node))) + val->type = SLV2_VALUE_INT; + else if (librdf_uri_equals(datatype_uri, librdf_node_get_uri(world->xsd_decimal_node))) + val->type = SLV2_VALUE_FLOAT; + else + fprintf(stderr, "Unknown datatype %s\n", librdf_uri_as_string(datatype_uri)); + } + val->str_val = strdup((char*)librdf_node_get_literal_value(node)); + break; + case LIBRDF_NODE_TYPE_BLANK: + case LIBRDF_NODE_TYPE_UNKNOWN: + default: + fprintf(stderr, "slv2_value_new_librdf_node error: Unknown node type."); + free(val); + val = NULL; + break; + } + + slv2_value_set_numerics_from_string(val); return val; } @@ -76,7 +129,7 @@ slv2_value_new_librdf_uri(SLV2World world, librdf_uri* uri) return val; } - + SLV2Value slv2_value_new_uri(SLV2World world, const char* uri) { @@ -92,6 +145,7 @@ slv2_value_duplicate(SLV2Value val) if (val->type == SLV2_VALUE_URI) { result->val.uri_val = librdf_new_uri_from_uri(val->val.uri_val); + result->str_val = (char*)librdf_uri_as_string(val->val.uri_val); } else { result->str_val = strdup(val->str_val); result->val = val->val; @@ -128,6 +182,7 @@ slv2_value_equals(SLV2Value value, SLV2Value other) switch (value->type) { case SLV2_VALUE_URI: return (librdf_uri_equals(value->val.uri_val, other->val.uri_val) != 0); + case SLV2_VALUE_QNAME: case SLV2_VALUE_STRING: return ! strcmp(value->str_val, other->str_val); case SLV2_VALUE_INT: @@ -155,6 +210,7 @@ slv2_value_get_turtle_token(SLV2Value value) result = calloc(len, sizeof(char)); snprintf(result, len, "<%s>", value->str_val); break; + case SLV2_VALUE_QNAME: case SLV2_VALUE_STRING: result = strdup(value->str_val); break; @@ -184,7 +240,7 @@ slv2_value_get_turtle_token(SLV2Value value) bool slv2_value_is_uri(SLV2Value value) { - return (value->type == SLV2_VALUE_URI); + return (value && value->type == SLV2_VALUE_URI); } @@ -195,19 +251,28 @@ slv2_value_as_uri(SLV2Value value) return value->str_val; } + +/* private */ +librdf_uri* +slv2_value_as_librdf_uri(SLV2Value value) +{ + assert(slv2_value_is_uri(value)); + return value->val.uri_val; +} + bool slv2_value_is_literal(SLV2Value value) { // No blank nodes - return (value->type != SLV2_VALUE_URI); + return (value && value->type != SLV2_VALUE_URI); } bool slv2_value_is_string(SLV2Value value) { - return (value->type == SLV2_VALUE_STRING); + return (value && value->type == SLV2_VALUE_STRING); } @@ -221,13 +286,14 @@ slv2_value_as_string(SLV2Value value) bool slv2_value_is_int(SLV2Value value) { - return (value->type == SLV2_VALUE_INT); + return (value && value->type == SLV2_VALUE_INT); } int slv2_value_as_int(SLV2Value value) { + assert(value); assert(slv2_value_is_int(value)); return value->val.int_val; } @@ -236,7 +302,7 @@ slv2_value_as_int(SLV2Value value) bool slv2_value_is_float(SLV2Value value) { - return (value->type == SLV2_VALUE_FLOAT); + return (value && value->type == SLV2_VALUE_FLOAT); } diff --git a/src/values.c b/src/values.c index 02544cd..9046edf 100644 --- a/src/values.c +++ b/src/values.c @@ -56,6 +56,15 @@ slv2_values_get_at(SLV2Values list, unsigned index) } +/* private */ +void +slv2_values_set_at(SLV2Values list, unsigned index, void* value) +{ + if (index <= INT_MAX) + raptor_sequence_set_at(list, index, value); +} + + bool slv2_values_contains(SLV2Values list, SLV2Value value) { diff --git a/src/world.c b/src/world.c index 08a1f83..18eec53 100644 --- a/src/world.c +++ b/src/world.c @@ -56,26 +56,32 @@ slv2_world_new() if (!world->parser) goto fail; - static const char* lv2_plugin_uri = "http://lv2plug.in/ns/lv2core#Plugin"; - world->lv2_plugin_class = slv2_plugin_class_new(world, NULL, lv2_plugin_uri, "Plugin"); - world->plugin_classes = slv2_plugin_classes_new(); world->plugins = slv2_plugins_new(); world->lv2_specification_node = librdf_new_node_from_uri_string(world->world, - (unsigned char*)"http://lv2plug.in/ns/lv2core#Specification"); + (const unsigned char*)"http://lv2plug.in/ns/lv2core#Specification"); world->lv2_plugin_node = librdf_new_node_from_uri_string(world->world, - (unsigned char*)lv2_plugin_uri); + (const unsigned char*)"http://lv2plug.in/ns/lv2core#Plugin"); world->rdf_a_node = librdf_new_node_from_uri_string(world->world, - (unsigned char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); + (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"); + + world->lv2_plugin_class = slv2_plugin_class_new(world, NULL, + librdf_node_get_uri(world->lv2_plugin_node), "Plugin"); return world; fail: - free(world); + /* keep on rockin' in the */ free(world); return NULL; } @@ -104,26 +110,32 @@ slv2_world_new_using_rdf_world(librdf_world* rdf_world) if (!world->parser) goto fail; - static const char* lv2_plugin_uri = "http://lv2plug.in/ns/lv2core#Plugin"; - world->lv2_plugin_class = slv2_plugin_class_new(world, NULL, lv2_plugin_uri, "Plugin"); - world->plugin_classes = slv2_plugin_classes_new(); world->plugins = slv2_plugins_new(); world->lv2_specification_node = librdf_new_node_from_uri_string(world->world, - (unsigned char*)"http://lv2plug.in/ns/lv2core#Specification"); + (const unsigned char*)"http://lv2plug.in/ns/lv2core#Specification"); - world->lv2_plugin_node = librdf_new_node_from_uri_string(rdf_world, - (unsigned char*)lv2_plugin_uri); + world->lv2_plugin_node = librdf_new_node_from_uri_string(world->world, + (const unsigned char*)"http://lv2plug.in/ns/lv2core#Plugin"); world->rdf_a_node = librdf_new_node_from_uri_string(rdf_world, - (unsigned char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); + (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"); + + world->lv2_plugin_class = slv2_plugin_class_new(world, NULL, + librdf_node_get_uri(world->lv2_plugin_node), "Plugin"); return world; fail: - free(world); + /* keep on rockin' in the */ free(world); return NULL; } @@ -131,17 +143,19 @@ fail: void slv2_world_free(SLV2World world) { + slv2_plugin_class_free(world->lv2_plugin_class); + world->lv2_plugin_class = NULL; + librdf_free_node(world->lv2_specification_node); librdf_free_node(world->lv2_plugin_node); librdf_free_node(world->rdf_a_node); + librdf_free_node(world->xsd_integer_node); + librdf_free_node(world->xsd_decimal_node); for (int i=0; i < raptor_sequence_size(world->plugins); ++i) slv2_plugin_free(raptor_sequence_get_at(world->plugins, i)); raptor_free_sequence(world->plugins); world->plugins = NULL; - - slv2_plugin_class_free(world->lv2_plugin_class); - world->lv2_plugin_class = NULL; slv2_plugin_classes_free(world->plugin_classes); world->plugin_classes = NULL; @@ -187,13 +201,10 @@ slv2_world_load_file(SLV2World world, librdf_uri* file_uri) void -slv2_world_load_bundle(SLV2World world, const char* bundle_uri_str) +slv2_world_load_bundle(SLV2World world, SLV2Value bundle_uri) { - librdf_uri* bundle_uri = librdf_new_uri(world->world, - (const unsigned char*)bundle_uri_str); - librdf_uri* manifest_uri = librdf_new_uri_relative_to_base( - bundle_uri, (const unsigned char*)"manifest.ttl"); + bundle_uri->val.uri_val, (const unsigned char*)"manifest.ttl"); /* Parse the manifest into a temporary model */ librdf_storage* manifest_storage = librdf_new_storage(world->world, @@ -228,7 +239,7 @@ slv2_world_load_bundle(SLV2World world, const char* bundle_uri_str) subject = librdf_new_node_from_node(plugin_node); predicate = librdf_new_node_from_uri_string(world->world, (unsigned char*)"http://drobilla.net/ns/slv2#bundleURI"); - object = librdf_new_node_from_uri(world->world, bundle_uri); + object = librdf_new_node_from_uri(world->world, bundle_uri->val.uri_val); librdf_model_add(world->model, subject, predicate, object); @@ -263,7 +274,7 @@ slv2_world_load_bundle(SLV2World world, const char* bundle_uri_str) subject = librdf_new_node_from_node(spec_node); predicate = librdf_new_node_from_uri_string(world->world, (unsigned char*)"http://drobilla.net/ns/slv2#bundleURI"); - object = librdf_new_node_from_uri(world->world, bundle_uri); + object = librdf_new_node_from_uri(world->world, bundle_uri->val.uri_val); librdf_model_add(world->model, subject, predicate, object); @@ -281,7 +292,6 @@ slv2_world_load_bundle(SLV2World world, const char* bundle_uri_str) librdf_free_model(manifest_model); librdf_free_storage(manifest_storage); librdf_free_uri(manifest_uri); - librdf_free_uri(bundle_uri); } @@ -307,7 +317,9 @@ slv2_world_load_directory(SLV2World world, const char* dir) if (bundle_dir != NULL) { closedir(bundle_dir); - slv2_world_load_bundle(world, uri); + SLV2Value uri_val = slv2_value_new_uri(world, uri); + slv2_world_load_bundle(world, uri_val); + slv2_value_free(uri_val); } free(uri); @@ -347,8 +359,8 @@ slv2_plugin_compare_by_uri(const void* a, const void* b) SLV2Plugin plugin_a = *(SLV2Plugin*)a; SLV2Plugin plugin_b = *(SLV2Plugin*)b; - return strcmp((const char*)librdf_uri_as_string(plugin_a->plugin_uri), - (const char*)librdf_uri_as_string(plugin_b->plugin_uri)); + return strcmp(slv2_value_as_uri(plugin_a->plugin_uri), + slv2_value_as_uri(plugin_b->plugin_uri)); } @@ -359,8 +371,8 @@ slv2_plugin_class_compare_by_uri(const void* a, const void* b) SLV2PluginClass class_a = *(SLV2PluginClass*)a; SLV2PluginClass class_b = *(SLV2PluginClass*)b; - return strcmp((const char*)librdf_uri_as_string(class_a->uri), - (const char*)librdf_uri_as_string(class_b->uri)); + return strcmp(slv2_value_as_uri(class_a->uri), + slv2_value_as_uri(class_b->uri)); } @@ -430,9 +442,7 @@ slv2_world_load_plugin_classes(SLV2World world) assert(class_uri); SLV2PluginClass plugin_class = slv2_plugin_class_new(world, - parent_uri ? (const char*)librdf_uri_as_string(parent_uri) : NULL, - (const char*)librdf_uri_as_string(class_uri), - label); + parent_uri, class_uri, label); raptor_sequence_push(world->plugin_classes, plugin_class); // FIXME: Slow! ORDER BY broken in certain versions of redland? raptor_sequence_sort(world->plugin_classes, slv2_plugin_class_compare_by_uri); @@ -519,17 +529,20 @@ slv2_world_load_all(SLV2World world) assert(plugin_uri); assert(data_uri); - //printf("PLUGIN: %s\n", librdf_uri_as_string(plugin_uri)); + // printf("PLUGIN: %s\n", librdf_uri_as_string(plugin_uri)); - SLV2Plugin plugin = slv2_plugins_get_by_uri(world->plugins, - (const char*)librdf_uri_as_string(plugin_uri)); + SLV2Value uri = slv2_value_new_librdf_uri(world, plugin_uri); + + SLV2Plugin plugin = slv2_plugins_get_by_uri(world->plugins, uri); // Create a new SLV2Plugin if (!plugin) { - plugin = slv2_plugin_new(world, plugin_uri, bundle_uri, binary_uri); + plugin = slv2_plugin_new(world, uri, bundle_uri, binary_uri); raptor_sequence_push(world->plugins, plugin); // FIXME: Slow! ORDER BY broken in certain versions of redland? raptor_sequence_sort(world->plugins, slv2_plugin_compare_by_uri); + } else { + slv2_value_free(uri); } plugin->world = world; diff --git a/utils/lv2_inspect.c b/utils/lv2_inspect.c index eda6d8a..fca4d6c 100644 --- a/utils/lv2_inspect.c +++ b/utils/lv2_inspect.c @@ -31,8 +31,6 @@ print_port(SLV2Plugin p, uint32_t index) { SLV2Port port = slv2_plugin_get_port_by_index(p, index); - char* str = NULL; - printf("\n\tPort %d:\n", index); SLV2Values classes = slv2_port_get_classes(p, port); @@ -43,7 +41,7 @@ print_port(SLV2Plugin p, uint32_t index) } if (slv2_port_is_a(p, port, event_class)) { - SLV2Values supported = slv2_port_get_value(p, port, + SLV2Values supported = slv2_port_get_value_by_qname(p, port, "lv2ev:supportsEvent"); if (slv2_values_size(supported) > 0) { printf("\n\t\tSupported events:\n"); @@ -54,18 +52,19 @@ print_port(SLV2Plugin p, uint32_t index) slv2_values_free(supported); } - str = slv2_port_get_symbol(p, port); - printf("\n\t\tSymbol: %s\n", str); - free(str); + SLV2Value val = slv2_port_get_symbol(p, port); + printf("\n\t\tSymbol: %s\n", slv2_value_as_string(val)); - str = slv2_port_get_name(p, port); - printf("\t\tName: %s\n", str); - free(str); + val = slv2_port_get_name(p, port); + printf("\t\tName: %s\n", slv2_value_as_string(val)); + slv2_value_free(val); if (slv2_port_is_a(p, port, control_class)) { - printf("\t\tMinimum: %f\n", slv2_port_get_minimum_value(p, port)); - printf("\t\tMaximum: %f\n", slv2_port_get_maximum_value(p, port)); - printf("\t\tDefault: %f\n", slv2_port_get_default_value(p, port)); + SLV2Value def, min, max; + slv2_port_get_range(p, port, &def, &min, &max); + printf("\t\tMinimum: %f\n", slv2_value_as_float(min)); + printf("\t\tMaximum: %f\n", slv2_value_as_float(max)); + printf("\t\tDefault: %f\n", slv2_value_as_float(def)); } SLV2Values properties = slv2_port_get_properties(p, port); @@ -83,45 +82,65 @@ print_port(SLV2Plugin p, uint32_t index) void print_plugin(SLV2Plugin p) { - char* str = NULL; + SLV2Value val = NULL; + + printf("%s\n\n", slv2_value_as_uri(slv2_plugin_get_uri(p))); + + val = slv2_plugin_get_name(p); + printf("\tName: %s\n", slv2_value_as_string(val)); + slv2_value_free(val); + + SLV2Value class_label = slv2_plugin_class_get_label(slv2_plugin_get_class(p)); + printf("\tClass: %s\n", slv2_value_as_string(class_label)); - printf("%s\n\n", slv2_plugin_get_uri(p)); + val = slv2_plugin_get_author_name(p); + if (val) { + printf("\tAuthor: %s\n", slv2_value_as_string(val)); + slv2_value_free(val); + } - str = slv2_plugin_get_name(p); - printf("\tName: %s\n", str); - free(str); + val = slv2_plugin_get_author_email(p); + if (val) { + printf("\tAuthor Email: %s\n", slv2_value_as_uri(val)); + slv2_value_free(val); + } - const char* class_label = slv2_plugin_class_get_label(slv2_plugin_get_class(p)); - printf("\tClass: %s\n", class_label); + val = slv2_plugin_get_author_homepage(p); + if (val) { + printf("\tAuthor Homepage: %s\n", slv2_value_as_uri(val)); + slv2_value_free(val); + } if (slv2_plugin_has_latency(p)) { - uint32_t latency_port = slv2_plugin_get_latency_port(p); + uint32_t latency_port = slv2_plugin_get_latency_port_index(p); printf("\tHas latency: yes, reported by port %d\n", latency_port); } else { printf("\tHas latency: no\n"); } - printf("\tBundle: %s\n", slv2_plugin_get_bundle_uri(p)); - printf("\tBinary: %s\n", slv2_plugin_get_library_uri(p)); + printf("\tBundle: %s\n", slv2_value_as_uri(slv2_plugin_get_bundle_uri(p))); + printf("\tBinary: %s\n", slv2_value_as_uri(slv2_plugin_get_library_uri(p))); SLV2UIs uis = slv2_plugin_get_uis(p); if (slv2_values_size(uis) > 0) { printf("\tGUI: "); for (unsigned i=0; i < slv2_uis_size(uis); ++i) { SLV2UI ui = slv2_uis_get_at(uis, i); - printf("%s\n", slv2_ui_get_uri(ui)); + printf("%s\n", slv2_value_as_uri(slv2_ui_get_uri(ui))); - const char* binary = slv2_ui_get_binary_uri(ui); + const char* binary = slv2_value_as_uri(slv2_ui_get_binary_uri(ui)); SLV2Values types = slv2_ui_get_classes(ui); for (unsigned i=0; i < slv2_values_size(types); ++i) { - printf("\t\t\tClass: %s\n", slv2_value_as_uri(slv2_values_get_at(types, i))); + printf("\t Class: %s\n", + slv2_value_as_uri(slv2_values_get_at(types, i))); } if (binary) - printf("\t\t\tBinary: %s\n", binary); + printf("\t Binary: %s\n", binary); - printf("\t\t\tBundle: %s\n", slv2_ui_get_bundle_uri(ui)); + printf("\t Bundle: %s\n", + slv2_value_as_uri(slv2_ui_get_bundle_uri(ui))); } } slv2_uis_free(uis); @@ -226,16 +245,17 @@ main(int argc, char** argv) } SLV2Plugins plugins = slv2_world_get_all_plugins(world); + SLV2Value uri = slv2_value_new_uri(world, argv[1]); - SLV2Plugin p = slv2_plugins_get_by_uri(plugins, argv[1]); + SLV2Plugin p = slv2_plugins_get_by_uri(plugins, uri); if (p) { print_plugin(p); } else { fprintf(stderr, "Plugin not found.\n"); - return -1; } + slv2_value_free(uri); slv2_plugins_free(world, plugins); slv2_world_free(world); diff --git a/utils/lv2_list.c b/utils/lv2_list.c index dbef82b..1996a91 100644 --- a/utils/lv2_list.c +++ b/utils/lv2_list.c @@ -27,7 +27,7 @@ list_plugins(SLV2Plugins list) { for (unsigned i=0; i < slv2_plugins_size(list); ++i) { SLV2Plugin p = slv2_plugins_get_at(list, i); - printf("%s\n", slv2_plugin_get_uri(p)); + printf("%s\n", slv2_value_as_uri(slv2_plugin_get_uri(p))); } } |