LCOV - code coverage report
Current view: directory - slv2/src - plugin.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 367 350 95.4 %
Date: 2009-05-26 Functions: 34 32 94.1 %

       1                 : /* SLV2
       2                 :  * Copyright (C) 2007-2009 Dave Robillard <http://drobilla.net>
       3                 :  *
       4                 :  * This library is free software; you can redistribute it and/or modify it
       5                 :  * under the terms of the GNU General Public License as published by the Free
       6                 :  * Software Foundation; either version 2 of the License, or (at your option)
       7                 :  * any later version.
       8                 :  *
       9                 :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10                 :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      11                 :  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      12                 :  * for more details.
      13                 :  *
      14                 :  * You should have received a copy of the GNU General Public License along
      15                 :  * with this program; if not, write to the Free Software Foundation, Inc.,
      16                 :  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
      17                 :  */
      18                 : 
      19                 : #define _XOPEN_SOURCE 500
      20                 : 
      21                 : #include <assert.h>
      22                 : #include <math.h>
      23                 : #include <stdlib.h>
      24                 : #include <string.h>
      25                 : #include <librdf.h>
      26                 : #include "slv2/types.h"
      27                 : #include "slv2/collections.h"
      28                 : #include "slv2/plugin.h"
      29                 : #include "slv2/pluginclass.h"
      30                 : #include "slv2/query.h"
      31                 : #include "slv2/util.h"
      32                 : #include "slv2_internal.h"
      33                 : 
      34                 : 
      35                 : /* private
      36                 :  * ownership of uri is taken */
      37                 : SLV2Plugin
      38                 : slv2_plugin_new(SLV2World world, SLV2Value uri, librdf_uri* bundle_uri)
      39            2628 : {
      40            2628 :         assert(bundle_uri);
      41            2628 :         struct _SLV2Plugin* plugin = malloc(sizeof(struct _SLV2Plugin));
      42            2628 :         plugin->world = world;
      43            2628 :         plugin->plugin_uri = uri;
      44            2628 :         plugin->bundle_uri = slv2_value_new_librdf_uri(world, bundle_uri);
      45            2628 :         plugin->binary_uri = NULL;
      46            2628 :         plugin->plugin_class = NULL;
      47            2628 :         plugin->data_uris = slv2_values_new();
      48            2628 :         plugin->ports = NULL;
      49            2628 :         plugin->storage = NULL;
      50            2628 :         plugin->rdf = NULL;
      51                 : 
      52            2628 :         return plugin;
      53                 : }
      54                 : 
      55                 : 
      56                 : /* private */
      57                 : void
      58                 : slv2_plugin_free(SLV2Plugin p)
      59            2628 : {
      60            2628 :         slv2_value_free(p->plugin_uri);
      61            2628 :         p->plugin_uri = NULL;
      62                 : 
      63            2628 :         slv2_value_free(p->bundle_uri);
      64            2628 :         p->bundle_uri = NULL;
      65                 : 
      66            2628 :         slv2_value_free(p->binary_uri);
      67            2628 :         p->binary_uri = NULL;
      68                 : 
      69            2628 :         if (p->ports)
      70               3 :                 raptor_free_sequence(p->ports);
      71            2628 :         p->ports = NULL;
      72                 : 
      73            2628 :         if (p->rdf) {
      74               7 :                 librdf_free_model(p->rdf);
      75               7 :                 p->rdf = NULL;
      76                 :         }
      77                 : 
      78            2628 :         if (p->storage) {
      79               7 :                 librdf_free_storage(p->storage);
      80               7 :                 p->storage = NULL;
      81                 :         }
      82                 : 
      83            2628 :         slv2_values_free(p->data_uris);
      84            2628 :         p->data_uris = NULL;
      85                 : 
      86            2628 :         free(p);
      87            2628 : }
      88                 : 
      89                 : 
      90                 : /** comparator for sorting */
      91                 : #if 0
      92                 : static int
      93                 : slv2_port_compare_by_index(const void* a, const void* b)
      94                 : {
      95                 :         SLV2Port port_a = *(SLV2Port*)a;
      96                 :         SLV2Port port_b = *(SLV2Port*)b;
      97                 : 
      98                 :         if (port_a->index < port_b->index)
      99                 :                 return -1;
     100                 :         else if (port_a->index == port_b->index)
     101                 :                 return 0;
     102                 :         else //if (port_a->index > port_b->index)
     103                 :                 return 1;
     104                 : }
     105                 : #endif
     106                 : 
     107                 : 
     108                 : /* private */
     109                 : void
     110                 : slv2_plugin_load_if_necessary(SLV2Plugin p)
     111              66 : {
     112              66 :         if (!p->rdf)
     113               6 :                 slv2_plugin_load(p);
     114              66 : }
     115                 : 
     116                 : 
     117                 : /* private */
     118                 : void
     119                 : slv2_plugin_load_ports_if_necessary(SLV2Plugin p)
     120              99 : {
     121              99 :         if (!p->rdf)
     122               1 :                 slv2_plugin_load(p);
     123                 : 
     124              99 :         if (!p->ports) {
     125               3 :                 p->ports = raptor_new_sequence((void (*)(void*))&slv2_port_free, NULL);
     126                 : 
     127                 :                 const unsigned char* query = (const unsigned char*)
     128                 :                         "PREFIX : <http://lv2plug.in/ns/lv2core#>\n"
     129                 :                         "SELECT DISTINCT ?type ?symbol ?index WHERE {\n"
     130                 :                         "<>    :port    ?port .\n"
     131                 :                         "?port a        ?type ;\n"
     132                 :                         "      :symbol  ?symbol ;\n"
     133                 :                         "      :index   ?index .\n"
     134               3 :                         "} ORDER BY (?index)";
     135                 : 
     136                 :                 librdf_query* q = librdf_new_query(p->world->world, "sparql",
     137               3 :                                 NULL, query, slv2_value_as_librdf_uri(p->plugin_uri));
     138                 : 
     139               3 :                 librdf_query_results* results = librdf_query_execute(q, p->rdf);
     140                 : 
     141               3 :                 int num_ports  = 0;
     142               3 :                 int last_index = -1;
     143                 : 
     144              22 :                 while (!librdf_query_results_finished(results)) {
     145                 : 
     146              16 :                         librdf_node* type_node = librdf_query_results_get_binding_value(results, 0);
     147              16 :                         librdf_node* symbol_node = librdf_query_results_get_binding_value(results, 1);
     148              16 :                         librdf_node* index_node = librdf_query_results_get_binding_value(results, 2);
     149                 : 
     150              16 :                         assert(librdf_node_is_literal(symbol_node));
     151              16 :                         assert(librdf_node_is_literal(index_node));
     152                 : 
     153              16 :                         const char* symbol = (const char*)librdf_node_get_literal_value(symbol_node);
     154              16 :                         const char* index = (const char*)librdf_node_get_literal_value(index_node);
     155                 : 
     156                 :                         //printf("PORT: %s %s %s\n", type, index, symbol);
     157                 : 
     158              16 :                         const int this_index = atoi(index);
     159              16 :                         SLV2Port  this_port  = NULL;
     160                 : 
     161                 :                         // ORDER BY guarantees order
     162              16 :                         assert(this_index <= num_ports);
     163                 : 
     164                 :                         // Create a new SLV2Port, and add to template
     165              16 :                         if (this_index == num_ports) {
     166               8 :                                 assert(this_index == last_index + 1);
     167               8 :                                 this_port = slv2_port_new(p->world, (unsigned)atoi(index), symbol);
     168               8 :                                 raptor_sequence_push(p->ports, this_port);
     169               8 :                                 ++num_ports;
     170               8 :                                 ++last_index;
     171                 : 
     172                 :                         // More information about a port we already created
     173               8 :                         } else if (this_index < num_ports) {
     174               8 :                                 this_port = slv2_plugin_get_port_by_index(p, this_index);
     175                 :                         }
     176                 : 
     177              16 :                         if (this_port) {
     178              16 :                                 raptor_sequence_push(this_port->classes,
     179                 :                                                 slv2_value_new_librdf_uri(p->world, librdf_node_get_uri(type_node)));
     180                 :                         }
     181                 : 
     182              16 :                         librdf_free_node(type_node);
     183              16 :                         librdf_free_node(symbol_node);
     184              16 :                         librdf_free_node(index_node);
     185                 : 
     186              16 :                         librdf_query_results_next(results);
     187                 :                 }
     188                 : 
     189               3 :                 librdf_free_query_results(results);
     190               3 :                 librdf_free_query(q);
     191                 :         }
     192              99 : }
     193                 : 
     194                 : 
     195                 : void
     196                 : slv2_plugin_load(SLV2Plugin p)
     197               7 : {
     198                 :         //printf("Loading cache for %s\n", slv2_value_as_string(p->plugin_uri));
     199                 : 
     200               7 :         if (!p->storage) {
     201               7 :                 assert(!p->rdf);
     202               7 :                 p->storage = librdf_new_storage(p->world->world, "trees", NULL, NULL);
     203               7 :                 if (!p->storage)
     204               0 :                         p->storage = librdf_new_storage(p->world->world, "memory", NULL, NULL);
     205               7 :                 p->rdf = librdf_new_model(p->world->world, p->storage, NULL);
     206                 :         }
     207                 : 
     208                 :         // Parse all the plugin's data files into RDF model
     209              21 :         for (unsigned i=0; i < slv2_values_size(p->data_uris); ++i) {
     210              14 :                 SLV2Value data_uri_val = slv2_values_get_at(p->data_uris, i);
     211                 :                 librdf_uri* data_uri = librdf_new_uri(p->world->world,
     212              14 :                                 (const unsigned char*)slv2_value_as_uri(data_uri_val));
     213              14 :                 librdf_parser_parse_into_model(p->world->parser, data_uri, NULL, p->rdf);
     214              14 :                 librdf_free_uri(data_uri);
     215                 :         }
     216               7 : }
     217                 : 
     218                 : 
     219                 : SLV2Value
     220                 : slv2_plugin_get_uri(SLV2Plugin p)
     221           54154 : {
     222           54154 :         assert(p);
     223           54154 :         assert(p->plugin_uri);
     224           54154 :         return p->plugin_uri;
     225                 : }
     226                 : 
     227                 : 
     228                 : SLV2Value
     229                 : slv2_plugin_get_bundle_uri(SLV2Plugin p)
     230               3 : {
     231               3 :         assert(p);
     232               3 :         assert(p->bundle_uri);
     233               3 :         return p->bundle_uri;
     234                 : }
     235                 : 
     236                 : 
     237                 : SLV2Value
     238                 : slv2_plugin_get_library_uri(SLV2Plugin p)
     239               3 : {
     240               3 :         assert(p);
     241               3 :         slv2_plugin_load_if_necessary(p);
     242               3 :         if (!p->binary_uri) {
     243                 :                 const unsigned char* query = (const unsigned char*)
     244                 :                         "PREFIX : <http://lv2plug.in/ns/lv2core#>\n"
     245               1 :                         "SELECT ?binary WHERE { <> :binary ?binary . }";
     246                 : 
     247                 :                 librdf_query* q = librdf_new_query(p->world->world, "sparql",
     248               1 :                                 NULL, query, slv2_value_as_librdf_uri(p->plugin_uri));
     249                 : 
     250               1 :                 librdf_query_results* results = librdf_query_execute(q, p->rdf);
     251                 : 
     252               1 :                 if (!librdf_query_results_finished(results)) {
     253               1 :                         librdf_node* binary_node = librdf_query_results_get_binding_value(results, 0);
     254               1 :                         librdf_uri* binary_uri = librdf_node_get_uri(binary_node);
     255                 : 
     256               1 :                         if (binary_uri) {
     257               1 :                                 SLV2Value binary = slv2_value_new_librdf_uri(p->world, binary_uri);
     258               1 :                                 p->binary_uri = binary;
     259                 :                         }
     260                 : 
     261               1 :                         librdf_free_node(binary_node);
     262                 :                 }
     263                 : 
     264               1 :                 librdf_free_query_results(results);
     265               1 :                 librdf_free_query(q);
     266                 :         }
     267               3 :         return p->binary_uri;
     268                 : }
     269                 : 
     270                 : 
     271                 : SLV2Values
     272                 : slv2_plugin_get_data_uris(SLV2Plugin p)
     273               2 : {
     274               2 :         return p->data_uris;
     275                 : }
     276                 : 
     277                 : 
     278                 : SLV2PluginClass
     279                 : slv2_plugin_get_class(SLV2Plugin p)
     280               2 : {
     281               2 :         slv2_plugin_load_if_necessary(p);
     282               2 :         if (!p->plugin_class) {
     283                 :                 const unsigned char* query = (const unsigned char*)
     284               2 :                         "SELECT DISTINCT ?class WHERE { <> a ?class }";
     285                 : 
     286                 :                 librdf_query* q = librdf_new_query(p->world->world, "sparql",
     287               2 :                                 NULL, query, slv2_value_as_librdf_uri(p->plugin_uri));
     288                 : 
     289               2 :                 librdf_query_results* results = librdf_query_execute(q, p->rdf);
     290                 : 
     291               4 :                 while (!librdf_query_results_finished(results)) {
     292               2 :                         librdf_node* class_node = librdf_query_results_get_binding_value(results, 0);
     293               2 :                         librdf_uri*  class_uri  = librdf_node_get_uri(class_node);
     294                 : 
     295               2 :                         if (!class_uri) {
     296               0 :                                 librdf_query_results_next(results);
     297               0 :                                 continue;
     298                 :                         }
     299                 : 
     300               2 :                         SLV2Value class = slv2_value_new_librdf_uri(p->world, class_uri);
     301                 : 
     302               2 :                         if ( ! slv2_value_equals(class, p->world->lv2_plugin_class->uri)) {
     303                 : 
     304                 :                                 SLV2PluginClass plugin_class = slv2_plugin_classes_get_by_uri(
     305               2 :                                                 p->world->plugin_classes, class);
     306                 : 
     307               2 :                                 librdf_free_node(class_node);
     308                 : 
     309               2 :                                 if (plugin_class) {
     310               2 :                                         p->plugin_class = plugin_class;
     311               2 :                                         slv2_value_free(class);
     312               2 :                                         break;
     313                 :                                 }
     314                 :                         }
     315                 : 
     316               0 :                         slv2_value_free(class);
     317               0 :                         librdf_query_results_next(results);
     318                 :                 }
     319                 : 
     320               2 :                 if (p->plugin_class == NULL)
     321               0 :                         p->plugin_class = p->world->lv2_plugin_class;
     322                 : 
     323               2 :                 librdf_free_query_results(results);
     324               2 :                 librdf_free_query(q);
     325                 :         }
     326                 : 
     327               2 :         return p->plugin_class;
     328                 : }
     329                 : 
     330                 : 
     331                 : bool
     332                 : slv2_plugin_verify(SLV2Plugin plugin)
     333               5 : {
     334                 :         char* query_str =
     335                 :                 "SELECT DISTINCT ?type ?name ?license ?port WHERE {\n"
     336                 :                 "<> a ?type ;\n"
     337                 :                 "doap:name    ?name ;\n"
     338                 :                 "doap:license ?license ;\n"
     339               5 :                 "lv2:port     [ lv2:index ?port ] .\n}";
     340                 : 
     341               5 :         SLV2Results results = slv2_plugin_query_sparql(plugin, query_str);
     342                 : 
     343               5 :         bool has_type    = false;
     344               5 :         bool has_name    = false;
     345               5 :         bool has_license = false;
     346               5 :         bool has_port    = false;
     347                 : 
     348              14 :         while (!librdf_query_results_finished(results->rdf_results)) {
     349               4 :                 librdf_node* type_node = librdf_query_results_get_binding_value(results->rdf_results, 0);
     350               4 :                 librdf_node* name_node = librdf_query_results_get_binding_value(results->rdf_results, 1);
     351               4 :                 librdf_node* license_node = librdf_query_results_get_binding_value(results->rdf_results, 2);
     352               4 :                 librdf_node* port_node = librdf_query_results_get_binding_value(results->rdf_results, 3);
     353                 : 
     354               4 :                 if (librdf_node_get_type(type_node) == LIBRDF_NODE_TYPE_RESOURCE)
     355               4 :                         has_type = true;
     356                 : 
     357               4 :                 if (name_node)
     358               4 :                         has_name = true;
     359                 : 
     360               4 :                 if (license_node)
     361               4 :                         has_license = true;
     362                 : 
     363               4 :                 if (port_node)
     364               4 :                         has_port = true;
     365                 : 
     366               4 :                 librdf_free_node(type_node);
     367               4 :                 librdf_free_node(name_node);
     368               4 :                 librdf_free_node(license_node);
     369               4 :                 librdf_free_node(port_node);
     370                 : 
     371               4 :                 librdf_query_results_next(results->rdf_results);
     372                 :         }
     373                 : 
     374               5 :         slv2_results_free(results);
     375                 : 
     376               5 :         if ( ! (has_type && has_name && has_license && has_port) ) {
     377               1 :                 fprintf(stderr, "Invalid LV2 Plugin %s\n",
     378                 :                                 slv2_value_as_uri(slv2_plugin_get_uri(plugin)));
     379               1 :                 return false;
     380                 :         } else {
     381               4 :                 return true;
     382                 :         }
     383                 : }
     384                 : 
     385                 : 
     386                 : SLV2Value
     387                 : slv2_plugin_get_name(SLV2Plugin plugin)
     388               3 : {
     389               3 :         SLV2Values results = slv2_plugin_get_value_by_qname_i18n(plugin, "doap:name");
     390               3 :         SLV2Value  ret     = NULL;
     391                 : 
     392               3 :         if (results) {
     393               3 :                 SLV2Value val = slv2_values_get_at(results, 0);
     394               3 :                 if (slv2_value_is_string(val))
     395               3 :                         ret = slv2_value_duplicate(val);
     396               3 :                 slv2_values_free(results);
     397                 :         } else {
     398               0 :                 results = slv2_plugin_get_value_by_qname(plugin, "doap:name");
     399               0 :                 SLV2Value val = slv2_values_get_at(results, 0);
     400               0 :                 if (slv2_value_is_string(val))
     401               0 :                         ret = slv2_value_duplicate(val);
     402               0 :                 slv2_values_free(results);
     403                 :         }
     404                 : 
     405               3 :         return ret;
     406                 : }
     407                 : 
     408                 : 
     409                 : SLV2Values
     410                 : slv2_plugin_get_value(SLV2Plugin p,
     411                 :                       SLV2Value  predicate)
     412               3 : {
     413               3 :         char* query = NULL;
     414                 : 
     415                 :         /* Hack around broken RASQAL, full URI predicates don't work :/ */
     416               3 :         query = slv2_strjoin(
     417                 :                 "PREFIX slv2predicate: <", slv2_value_as_string(predicate), ">\n",
     418                 :                 "SELECT DISTINCT ?value WHERE {\n"
     419                 :                 "<> slv2predicate: ?value .\n"
     420                 :                 "}\n", NULL);
     421                 : 
     422               3 :         SLV2Values result = slv2_plugin_query_variable(p, query, 0);
     423                 : 
     424               3 :         free(query);
     425                 : 
     426               3 :         return result;
     427                 : }
     428                 : 
     429                 : 
     430                 : /* internal */
     431                 : SLV2Values
     432                 : slv2_plugin_get_value_by_qname(SLV2Plugin  p,
     433                 :                                const char* predicate)
     434              20 : {
     435                 :         char* query = slv2_strjoin(
     436                 :                         "SELECT DISTINCT ?value WHERE { \n"
     437                 :                         "<> ", predicate, " ?value . \n"
     438              20 :                         "}\n", NULL);
     439                 : 
     440              20 :         SLV2Values result = slv2_plugin_query_variable(p, query, 0);
     441                 : 
     442              20 :         free(query);
     443                 : 
     444              20 :         return result;
     445                 : }
     446                 : 
     447                 : 
     448                 : /* internal: get i18n value if possible */
     449                 : SLV2Values
     450                 : slv2_plugin_get_value_by_qname_i18n(SLV2Plugin  p,
     451                 :                                     const char* predicate)
     452               3 : {
     453                 :         char* query = slv2_strjoin(
     454                 :                         "SELECT DISTINCT ?value WHERE { \n"
     455                 :                         "<> ", predicate, " ?value . \n"
     456                 :                         "FILTER(lang(?value) = \"", slv2_get_lang(), "\") \n"
     457               3 :                         "}\n", NULL);
     458                 : 
     459               3 :         SLV2Values result = slv2_plugin_query_variable(p, query, 0);
     460                 : 
     461               3 :         free(query);
     462                 : 
     463               3 :         return result;
     464                 : }
     465                 : 
     466                 : 
     467                 : SLV2Values
     468                 : slv2_plugin_get_value_for_subject(SLV2Plugin p,
     469                 :                                   SLV2Value  subject,
     470                 :                                   SLV2Value  predicate)
     471               2 : {
     472               2 :         if ( ! slv2_value_is_uri(subject)) {
     473               0 :                 fprintf(stderr, "slv2_plugin_get_value_for_subject error: "
     474                 :                                 "subject is not a URI\n");
     475               0 :                 return NULL;
     476                 :         }
     477                 : 
     478               2 :         char* query = NULL;
     479                 : 
     480                 : 
     481                 : 
     482               2 :         char* subject_token = slv2_value_get_turtle_token(subject);
     483                 : 
     484                 :         /* Hack around broken RASQAL, full URI predicates don't work :/ */
     485               2 :         query = slv2_strjoin(
     486                 :                 "PREFIX slv2predicate: <", slv2_value_as_string(predicate), ">\n",
     487                 :                 "SELECT DISTINCT ?value WHERE {\n",
     488                 :                 subject_token, " slv2predicate: ?value .\n"
     489                 :                 "}\n", NULL);
     490                 : 
     491               2 :         SLV2Values result = slv2_plugin_query_variable(p, query, 0);
     492                 : 
     493               2 :         free(query);
     494               2 :         free(subject_token);
     495                 : 
     496               2 :         return result;
     497                 : }
     498                 : 
     499                 : 
     500                 : SLV2Values
     501                 : slv2_plugin_get_properties(SLV2Plugin p)
     502               0 : {
     503                 :         // FIXME: APIBREAK: This predicate does not even exist.  Remove this function.
     504               0 :         return slv2_plugin_get_value_by_qname(p, "lv2:pluginProperty");
     505                 : }
     506                 : 
     507                 : 
     508                 : SLV2Values
     509                 : slv2_plugin_get_hints(SLV2Plugin p)
     510               0 : {
     511                 :         // FIXME: APIBREAK: This predicate does not even exist.  Remove this function.
     512               0 :         return slv2_plugin_get_value_by_qname(p, "lv2:pluginHint");
     513                 : }
     514                 : 
     515                 : 
     516                 : uint32_t
     517                 : slv2_plugin_get_num_ports(SLV2Plugin p)
     518              65 : {
     519              65 :         slv2_plugin_load_ports_if_necessary(p);
     520              65 :         return raptor_sequence_size(p->ports);
     521                 : }
     522                 : 
     523                 : 
     524                 : void
     525                 : slv2_plugin_get_port_float_values(SLV2Plugin  p,
     526                 :                                   const char* qname,
     527                 :                                   float*      values)
     528               6 : {
     529               6 :         slv2_plugin_load_ports_if_necessary(p);
     530                 : 
     531              24 :         for (int i = 0; i < raptor_sequence_size(p->ports); ++i)
     532              18 :                 values[i] = NAN;
     533                 : 
     534                 :         unsigned char* query = (unsigned char*)slv2_strjoin(
     535                 :                         "PREFIX : <http://lv2plug.in/ns/lv2core#>\n"
     536                 :                         "SELECT DISTINCT ?index ?value WHERE {\n"
     537                 :                         "<>    :port    ?port .\n"
     538                 :                         "?port :index   ?index .\n"
     539                 :                         "?port ", qname, " ?value .\n"
     540               6 :                         "} ", NULL);
     541                 : 
     542                 :         librdf_query* q = librdf_new_query(p->world->world, "sparql",
     543               6 :                         NULL, query, slv2_value_as_librdf_uri(p->plugin_uri));
     544                 : 
     545               6 :         librdf_query_results* results = librdf_query_execute(q, p->rdf);
     546                 : 
     547              24 :         while (!librdf_query_results_finished(results)) {
     548              12 :                 librdf_node* idx_node = librdf_query_results_get_binding_value(results, 0);
     549              12 :                 librdf_node* val_node = librdf_query_results_get_binding_value(results, 1);
     550              12 :                 if (idx_node && val_node && librdf_node_is_literal(idx_node)
     551                 :                                 && librdf_node_is_literal(val_node)) {
     552              12 :                         const int idx = atoi((const char*)librdf_node_get_literal_value(idx_node));
     553              12 :                         const float val = atof((const char*)librdf_node_get_literal_value(val_node));
     554              12 :                         values[idx] = val;
     555              12 :                         librdf_free_node(idx_node);
     556              12 :                         librdf_free_node(val_node);
     557                 :                 }
     558              12 :                 librdf_query_results_next(results);
     559                 :         }
     560                 : 
     561               6 :         librdf_free_query_results(results);
     562               6 :         librdf_free_query(q);
     563               6 :         free(query);
     564               6 : }
     565                 : 
     566                 : 
     567                 : void
     568                 : slv2_plugin_get_port_ranges_float(SLV2Plugin p,
     569                 :                                   float*     min_values,
     570                 :                                   float*     max_values,
     571                 :                                   float*     def_values)
     572               2 : {
     573               2 :         if (min_values)
     574               2 :                 slv2_plugin_get_port_float_values(p, ":minimum", min_values);
     575                 : 
     576               2 :         if (max_values)
     577               2 :                 slv2_plugin_get_port_float_values(p, ":maximum", max_values);
     578                 : 
     579               2 :         if (def_values)
     580               2 :                 slv2_plugin_get_port_float_values(p, ":default", def_values);
     581               2 : }
     582                 : 
     583                 : 
     584                 : uint32_t
     585                 : slv2_plugin_get_num_ports_of_class(SLV2Plugin p,
     586                 :                                    SLV2Value  class_1, ...)
     587              16 : {
     588              16 :         slv2_plugin_load_ports_if_necessary(p);
     589                 : 
     590              16 :         uint32_t ret = 0;
     591                 :         va_list  args;
     592                 : 
     593              64 :         for (unsigned i=0; i < slv2_plugin_get_num_ports(p); ++i) {
     594              48 :                 SLV2Port port = raptor_sequence_get_at(p->ports, i);
     595              48 :                 if (!slv2_port_is_a(p, port, class_1))
     596              24 :                         continue;
     597                 : 
     598              24 :                 va_start(args, class_1);
     599                 : 
     600              24 :                 bool matches = true;
     601              54 :                 for (SLV2Value class_i = NULL; (class_i = va_arg(args, SLV2Value)) != NULL ; ) {
     602              12 :                         if (!slv2_port_is_a(p, port, class_i)) {
     603               6 :                                 va_end(args);
     604               6 :                                 matches = false;
     605               6 :                                 break;
     606                 :                         }
     607                 :                 }
     608                 : 
     609              24 :                 if (matches)
     610              18 :                         ++ret;
     611                 : 
     612              24 :                 va_end(args);
     613                 :         }
     614                 : 
     615              16 :         return ret;
     616                 : }
     617                 : 
     618                 : 
     619                 : bool
     620                 : slv2_plugin_has_latency(SLV2Plugin p)
     621               2 : {
     622                 :     const char* const query =
     623                 :                 "SELECT ?index WHERE {\n"
     624                 :                 "  <>      lv2:port         ?port .\n"
     625                 :                 "  ?port   lv2:portProperty lv2:reportsLatency ;\n"
     626                 :                 "          lv2:index        ?index .\n"
     627               2 :                 "}\n";
     628                 : 
     629               2 :         SLV2Values results = slv2_plugin_query_variable(p, query, 0);
     630               2 :         const bool latent = (slv2_values_size(results) > 0);
     631               2 :         slv2_values_free(results);
     632                 : 
     633               2 :         return latent;
     634                 : }
     635                 : 
     636                 : 
     637                 : uint32_t
     638                 : slv2_plugin_get_latency_port_index(SLV2Plugin p)
     639               2 : {
     640                 :     const char* const query =
     641                 :                 "SELECT ?index WHERE {\n"
     642                 :                 "  <>      lv2:port         ?port .\n"
     643                 :                 "  ?port   lv2:portProperty lv2:reportsLatency ;\n"
     644                 :                 "          lv2:index        ?index .\n"
     645               2 :                 "}\n";
     646                 : 
     647               2 :         SLV2Values result = slv2_plugin_query_variable(p, query, 0);
     648                 : 
     649                 :         // FIXME: need a sane error handling strategy
     650               2 :         assert(slv2_values_size(result) > 0);
     651               2 :         SLV2Value val = slv2_values_get_at(result, 0);
     652               2 :         assert(slv2_value_is_int(val));
     653                 : 
     654               2 :         int ret = slv2_value_as_int(val);
     655               2 :         slv2_values_free(result);
     656               2 :         return ret;
     657                 : }
     658                 : 
     659                 : 
     660                 : bool
     661                 : slv2_plugin_has_feature(SLV2Plugin p,
     662                 :                         SLV2Value  feature)
     663               6 : {
     664               6 :         SLV2Values features = slv2_plugin_get_supported_features(p);
     665                 : 
     666               6 :         const bool ret = features && feature && slv2_values_contains(features, feature);
     667                 : 
     668               6 :         slv2_values_free(features);
     669               6 :         return ret;
     670                 : }
     671                 : 
     672                 : 
     673                 : SLV2Values
     674                 : slv2_plugin_get_supported_features(SLV2Plugin p)
     675               8 : {
     676               8 :         SLV2Values optional = slv2_plugin_get_optional_features(p);
     677               8 :         SLV2Values required = slv2_plugin_get_required_features(p);
     678                 : 
     679               8 :         SLV2Values result = slv2_values_new();
     680               8 :         unsigned n_optional = slv2_values_size(optional);
     681               8 :         unsigned n_required = slv2_values_size(required);
     682               8 :         unsigned i = 0;
     683              16 :         for ( ; i < n_optional; ++i)
     684               8 :                 slv2_values_set_at(result, i, raptor_sequence_pop(optional));
     685              16 :         for ( ; i < n_optional + n_required; ++i)
     686               8 :                 slv2_values_set_at(result, i, raptor_sequence_pop(required));
     687                 : 
     688               8 :         slv2_values_free(optional);
     689               8 :         slv2_values_free(required);
     690                 : 
     691               8 :         return result;
     692                 : }
     693                 : 
     694                 : 
     695                 : SLV2Values
     696                 : slv2_plugin_get_optional_features(SLV2Plugin p)
     697              10 : {
     698              10 :         return slv2_plugin_get_value_by_qname(p, "lv2:optionalFeature");
     699                 : }
     700                 : 
     701                 : 
     702                 : SLV2Values
     703                 : slv2_plugin_get_required_features(SLV2Plugin p)
     704              10 : {
     705              10 :         return slv2_plugin_get_value_by_qname(p, "lv2:requiredFeature");
     706                 : }
     707                 : 
     708                 : 
     709                 : SLV2Port
     710                 : slv2_plugin_get_port_by_index(SLV2Plugin p,
     711                 :                               uint32_t   index)
     712              10 : {
     713              10 :         slv2_plugin_load_ports_if_necessary(p);
     714              10 :         return raptor_sequence_get_at(p->ports, (int)index);
     715                 : }
     716                 : 
     717                 : 
     718                 : SLV2Port
     719                 : slv2_plugin_get_port_by_symbol(SLV2Plugin p,
     720                 :                                SLV2Value  symbol)
     721               2 : {
     722               2 :         slv2_plugin_load_ports_if_necessary(p);
     723               4 :         for (int i=0; i < raptor_sequence_size(p->ports); ++i) {
     724               3 :                 SLV2Port port = raptor_sequence_get_at(p->ports, i);
     725               3 :                 if (slv2_value_equals(port->symbol, symbol))
     726               1 :                         return port;
     727                 :         }
     728                 : 
     729               1 :         return NULL;
     730                 : }
     731                 : 
     732                 : 
     733                 : SLV2Value
     734                 : slv2_plugin_get_author_name(SLV2Plugin plugin)
     735               2 : {
     736               2 :         SLV2Value ret = NULL;
     737                 : 
     738                 :     const char* const query =
     739                 :                 "SELECT ?name WHERE {\n"
     740                 :                 "  <>      doap:maintainer ?maint . \n"
     741                 :                 "  ?maint  foaf:name ?name . \n"
     742               2 :                 "}\n";
     743                 : 
     744               2 :         SLV2Values results = slv2_plugin_query_variable(plugin, query, 0);
     745                 : 
     746               2 :         if (results && slv2_values_size(results) > 0) {
     747               2 :                 SLV2Value val = slv2_values_get_at(results, 0);
     748               2 :                 if (slv2_value_is_string(val))
     749               2 :                         ret = slv2_value_duplicate(val);
     750                 :         }
     751                 : 
     752               2 :         if (results)
     753               2 :                 slv2_values_free(results);
     754                 : 
     755               2 :         return ret;
     756                 : }
     757                 : 
     758                 : 
     759                 : SLV2Value
     760                 : slv2_plugin_get_author_email(SLV2Plugin plugin)
     761               2 : {
     762               2 :         SLV2Value ret = NULL;
     763                 : 
     764                 :     const char* const query =
     765                 :                 "SELECT ?email WHERE {\n"
     766                 :                 "  <>      doap:maintainer ?maint . \n"
     767                 :                 "  ?maint  foaf:mbox ?email . \n"
     768               2 :                 "}\n";
     769                 : 
     770               2 :         SLV2Values results = slv2_plugin_query_variable(plugin, query, 0);
     771                 : 
     772               2 :         if (results && slv2_values_size(results) > 0) {
     773               2 :                 SLV2Value val = slv2_values_get_at(results, 0);
     774               2 :                 if (slv2_value_is_uri(val))
     775               2 :                         ret = slv2_value_duplicate(val);
     776                 :         }
     777                 : 
     778               2 :         if (results)
     779               2 :                 slv2_values_free(results);
     780                 : 
     781               2 :         return ret;
     782                 : }
     783                 : 
     784                 : 
     785                 : SLV2Value
     786                 : slv2_plugin_get_author_homepage(SLV2Plugin plugin)
     787               2 : {
     788               2 :         SLV2Value ret = NULL;
     789                 : 
     790                 :     const char* const query =
     791                 :                 "SELECT ?page WHERE {\n"
     792                 :                 "  <>      doap:maintainer ?maint . \n"
     793                 :                 "  ?maint  foaf:homepage ?page . \n"
     794               2 :                 "}\n";
     795                 : 
     796               2 :         SLV2Values results = slv2_plugin_query_variable(plugin, query, 0);
     797                 : 
     798               2 :         if (results && slv2_values_size(results) > 0) {
     799               2 :                 SLV2Value val = slv2_values_get_at(results, 0);
     800               2 :                 if (slv2_value_is_uri(val))
     801               2 :                         ret = slv2_value_duplicate(val);
     802                 :         }
     803                 : 
     804               2 :         if (results)
     805               2 :                 slv2_values_free(results);
     806                 : 
     807               2 :         return ret;
     808                 : }
     809                 : 
     810                 : 
     811                 : SLV2UIs
     812                 : slv2_plugin_get_uis(SLV2Plugin plugin)
     813               3 : {
     814                 :     const char* const query_str =
     815                 :                 "PREFIX uiext: <http://lv2plug.in/ns/extensions/ui#>\n"
     816                 :                 "SELECT DISTINCT ?uri ?type ?binary WHERE {\n"
     817                 :                 "<>   uiext:ui     ?uri .\n"
     818                 :                 "?uri a            ?type ;\n"
     819                 :                 "     uiext:binary ?binary .\n"
     820               3 :                 "}\n";
     821                 : 
     822               3 :         SLV2Results results = slv2_plugin_query_sparql(plugin, query_str);
     823                 : 
     824               3 :         SLV2UIs result = slv2_uis_new();
     825                 : 
     826              10 :         while (!librdf_query_results_finished(results->rdf_results)) {
     827               4 :                 librdf_node* uri_node    = librdf_query_results_get_binding_value(results->rdf_results, 0);
     828               4 :                 librdf_node* type_node   = librdf_query_results_get_binding_value(results->rdf_results, 1);
     829               4 :                 librdf_node* binary_node = librdf_query_results_get_binding_value(results->rdf_results, 2);
     830                 : 
     831                 :                 SLV2UI ui = slv2_ui_new(plugin->world,
     832                 :                                 librdf_node_get_uri(uri_node),
     833                 :                                 librdf_node_get_uri(type_node),
     834               4 :                                 librdf_node_get_uri(binary_node));
     835                 : 
     836               4 :                 raptor_sequence_push(result, ui);
     837                 : 
     838               4 :                 librdf_free_node(uri_node);
     839               4 :                 librdf_free_node(type_node);
     840               4 :                 librdf_free_node(binary_node);
     841                 : 
     842               4 :                 librdf_query_results_next(results->rdf_results);
     843                 :         }
     844                 : 
     845               3 :         slv2_results_free(results);
     846                 : 
     847               3 :         if (slv2_uis_size(result) > 0) {
     848               1 :                 return result;
     849                 :         } else {
     850               2 :                 slv2_uis_free(result);
     851               2 :                 return NULL;
     852                 :         }
     853                 : }
     854                 : 

Generated by: LCOV version 1.7