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 : #include <assert.h>
21 : #include <stdlib.h>
22 : #include <stdio.h>
23 : #include <string.h>
24 : #include <limits.h>
25 : #include "slv2/types.h"
26 : #include "slv2/collections.h"
27 : #include "slv2/port.h"
28 : #include "slv2/query.h"
29 : #include "slv2/util.h"
30 : #include "slv2_internal.h"
31 :
32 :
33 : /* private */
34 : SLV2Port
35 : slv2_port_new(SLV2World world, uint32_t index, const char* symbol)
36 8 : {
37 8 : struct _SLV2Port* port = malloc(sizeof(struct _SLV2Port));
38 8 : port->index = index;
39 8 : port->symbol = slv2_value_new(world, SLV2_VALUE_STRING, symbol);
40 8 : port->classes = slv2_values_new();
41 : //port->node_id = strdup(node_id);
42 8 : return port;
43 : }
44 :
45 :
46 : /* private */
47 : void
48 : slv2_port_free(SLV2Port port)
49 8 : {
50 8 : slv2_values_free(port->classes);
51 8 : slv2_value_free(port->symbol);
52 8 : free(port);
53 8 : }
54 :
55 :
56 : /* private */
57 : #if 0
58 : SLV2Port
59 : slv2_port_duplicate(SLV2Port port)
60 : {
61 : SLV2Port ret = malloc(sizeof(struct _SLV2Port));
62 : ret->index = port->index;
63 : ret->symbol = slv2_value_duplicate(port->symbol);
64 : return ret;
65 : }
66 : #endif
67 :
68 :
69 : bool
70 : slv2_port_is_a(SLV2Plugin plugin,
71 : SLV2Port port,
72 : SLV2Value port_class)
73 63 : {
74 138 : for (unsigned i=0; i < slv2_values_size(port->classes); ++i)
75 107 : if (slv2_value_equals(slv2_values_get_at(port->classes, i), port_class))
76 32 : return true;
77 :
78 31 : return false;
79 : }
80 :
81 :
82 : bool
83 : slv2_port_has_property(SLV2Plugin p,
84 : SLV2Port port,
85 : SLV2Value property)
86 2 : {
87 2 : assert(property);
88 : char* query = slv2_strjoin(
89 : "SELECT DISTINCT ?port WHERE {\n"
90 : "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port ."
91 : "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n",
92 2 : " lv2:portProperty <", slv2_value_as_uri(property), "> .\n}", NULL);
93 :
94 2 : SLV2Values results = slv2_plugin_query_variable(p, query, 0);
95 2 : const bool ret = (slv2_values_size(results) > 0);
96 2 : slv2_values_free(results);
97 2 : free(query);
98 :
99 2 : return ret;
100 : }
101 :
102 :
103 : bool
104 : slv2_port_supports_event(SLV2Plugin p,
105 : SLV2Port port,
106 : SLV2Value event)
107 2 : {
108 2 : assert(event);
109 :
110 : char* query = slv2_strjoin(
111 : "ASK WHERE {\n"
112 : "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port ."
113 : "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n",
114 : " lv2ev:supportsEvent <", slv2_value_as_uri(event), "> .\n"
115 2 : "}", NULL);
116 :
117 2 : SLV2Results results = slv2_plugin_query_sparql(p, query);
118 2 : assert(librdf_query_results_is_boolean(results->rdf_results));
119 :
120 2 : const bool ret = librdf_query_results_get_boolean(results->rdf_results);
121 :
122 2 : free(query);
123 2 : slv2_results_free(results);
124 :
125 2 : return ret;
126 : }
127 :
128 :
129 : SLV2Values
130 : slv2_port_get_value_by_qname(SLV2Plugin p,
131 : SLV2Port port,
132 : const char* property)
133 1 : {
134 1 : assert(property);
135 1 : SLV2Values results = NULL;
136 :
137 : char* query = slv2_strjoin(
138 : "SELECT DISTINCT ?value WHERE {\n"
139 : "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n"
140 : "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n\t",
141 : property, " ?value .\n"
142 1 : "FILTER(lang(?value) = \"\") }", NULL);
143 :
144 1 : results = slv2_plugin_query_variable(p, query, 0);
145 :
146 1 : free(query);
147 1 : return results;
148 : }
149 :
150 :
151 : SLV2Values
152 : slv2_port_get_value(SLV2Plugin p,
153 : SLV2Port port,
154 : SLV2Value predicate)
155 3 : {
156 3 : char* query = NULL;
157 :
158 : /* Hack around broken RASQAL, full URI predicates don't work :/ */
159 3 : query = slv2_strjoin(
160 : "PREFIX slv2predicate: <", slv2_value_as_string(predicate), ">",
161 : "SELECT DISTINCT ?value WHERE { \n"
162 : "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n"
163 : "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n\t",
164 : " slv2predicate: ?value .\n"
165 : "}\n", NULL);
166 :
167 3 : SLV2Values result = slv2_plugin_query_variable(p, query, 0);
168 :
169 3 : free(query);
170 :
171 3 : return result;
172 : }
173 :
174 :
175 : SLV2Values
176 : slv2_port_get_value_by_qname_i18n(SLV2Plugin p,
177 : SLV2Port port,
178 : const char* property)
179 1 : {
180 1 : assert(property);
181 1 : SLV2Values results = NULL;
182 :
183 : char* query = slv2_strjoin(
184 : "SELECT DISTINCT ?value WHERE {\n"
185 : "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n"
186 : "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\";\n\t",
187 : property, " ?value .\n"
188 : "FILTER(lang(?value) = \"", slv2_get_lang(),
189 1 : "\") }", NULL);
190 :
191 1 : results = slv2_plugin_query_variable(p, query, 0);
192 :
193 1 : free(query);
194 1 : return results;
195 : }
196 :
197 :
198 : SLV2Value
199 : slv2_port_get_symbol(SLV2Plugin p,
200 : SLV2Port port)
201 1 : {
202 1 : return port->symbol;
203 : }
204 :
205 :
206 : SLV2Value
207 : slv2_port_get_name(SLV2Plugin p,
208 : SLV2Port port)
209 1 : {
210 1 : SLV2Value ret = NULL;
211 1 : SLV2Values results = slv2_port_get_value_by_qname_i18n(p, port, "lv2:name");
212 :
213 2 : if (results && slv2_values_size(results) > 0) {
214 1 : ret = slv2_value_duplicate(slv2_values_get_at(results, 0));
215 : } else {
216 0 : results = slv2_port_get_value_by_qname(p, port, "lv2:name");
217 0 : if (results && slv2_values_size(results) > 0)
218 0 : ret = slv2_value_duplicate(slv2_values_get_at(results, 0));
219 : }
220 :
221 1 : slv2_values_free(results);
222 :
223 1 : return ret;
224 : }
225 :
226 :
227 : SLV2Values
228 : slv2_port_get_classes(SLV2Plugin p,
229 : SLV2Port port)
230 2 : {
231 2 : return port->classes;
232 : }
233 :
234 :
235 : void
236 : slv2_port_get_range(SLV2Plugin p,
237 : SLV2Port port,
238 : SLV2Value* def,
239 : SLV2Value* min,
240 : SLV2Value* max)
241 1 : {
242 1 : if (def)
243 1 : *def = NULL;
244 1 : if (min)
245 1 : *min = NULL;
246 1 : if (max)
247 1 : *max = NULL;
248 :
249 : char* query = slv2_strjoin(
250 : "SELECT DISTINCT ?def ?min ?max WHERE {\n"
251 : "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n"
252 : "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\".\n",
253 : "OPTIONAL { ?port lv2:default ?def }\n",
254 : "OPTIONAL { ?port lv2:minimum ?min }\n",
255 : "OPTIONAL { ?port lv2:maximum ?max }\n",
256 1 : "\n}", NULL);
257 :
258 1 : SLV2Results results = slv2_plugin_query_sparql(p, query);
259 :
260 2 : while (!librdf_query_results_finished(results->rdf_results)) {
261 1 : librdf_node* def_node = librdf_query_results_get_binding_value(results->rdf_results, 0);
262 1 : librdf_node* min_node = librdf_query_results_get_binding_value(results->rdf_results, 1);
263 1 : librdf_node* max_node = librdf_query_results_get_binding_value(results->rdf_results, 2);
264 :
265 1 : if (def && def_node && !*def)
266 1 : *def = slv2_value_new_librdf_node(p->world, def_node);
267 1 : if (min && min_node && !*min)
268 1 : *min = slv2_value_new_librdf_node(p->world, min_node);
269 1 : if (max && max_node && !*max)
270 1 : *max = slv2_value_new_librdf_node(p->world, max_node);
271 :
272 1 : if ((!def || *def) && (!min || *min) && (!max || *max))
273 : break;
274 :
275 0 : librdf_query_results_next(results->rdf_results);
276 : }
277 :
278 1 : slv2_results_free(results);
279 :
280 1 : free(query);
281 1 : }
282 :
283 :
284 : SLV2ScalePoints
285 : slv2_port_get_scale_points(SLV2Plugin p,
286 : SLV2Port port)
287 1 : {
288 : char* query = slv2_strjoin(
289 : "SELECT DISTINCT ?value ?label WHERE {\n"
290 : "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port ?port .\n"
291 : "?port lv2:symbol \"", slv2_value_as_string(port->symbol), "\" ;\n",
292 : " lv2:scalePoint ?point .\n"
293 : "?point rdf:value ?value ;\n"
294 : " rdfs:label ?label .\n"
295 1 : "\n} ORDER BY ?value", NULL);
296 :
297 1 : SLV2Results results = slv2_plugin_query_sparql(p, query);
298 :
299 1 : SLV2ScalePoints ret = NULL;
300 :
301 1 : if (!slv2_results_finished(results))
302 1 : ret = slv2_scale_points_new();
303 :
304 4 : while (!slv2_results_finished(results)) {
305 2 : SLV2Value value = slv2_results_get_binding_value(results, 0);
306 2 : SLV2Value label = slv2_results_get_binding_value(results, 1);
307 :
308 2 : if (value && label)
309 2 : raptor_sequence_push(ret, slv2_scale_point_new(value, label));
310 :
311 2 : slv2_results_next(results);
312 : }
313 :
314 1 : slv2_results_free(results);
315 :
316 1 : free(query);
317 :
318 1 : assert(!ret || slv2_values_size(ret) > 0);
319 :
320 1 : return ret;
321 : }
322 :
323 :
324 :
325 : SLV2Values
326 : slv2_port_get_properties(SLV2Plugin p,
327 : SLV2Port port)
328 1 : {
329 1 : return slv2_port_get_value_by_qname(p, port, "lv2:portProperty");
330 : }
331 :
|