1 /*
2 Copyright 2007-2019 David Robillard <d@drobilla.net>
3
4 Permission to use, copy, modify, and/or distribute this software for any
5 purpose with or without fee is hereby granted, provided that the above
6 copyright notice and this permission notice appear in all copies.
7
8 THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #ifndef LILV_INTERNAL_H
18 #define LILV_INTERNAL_H
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
24 #include "lilv_config.h" // IWYU pragma: keep
25
26 #include "lilv/lilv.h"
27 #include "lv2/core/lv2.h"
28 #include "serd/serd.h"
29 #include "sord/sord.h"
30 #include "zix/tree.h"
31
32 #include <stdbool.h>
33 #include <stdint.h>
34 #include <stdio.h>
35
36 #ifdef _WIN32
37 # include <direct.h>
38 # include <stdio.h>
39 # include <windows.h>
40 # define dlopen(path, flags) LoadLibrary(path)
41 # define dlclose(lib) FreeLibrary((HMODULE)lib)
42 # ifdef _MSC_VER
43 # define __func__ __FUNCTION__
44 # ifndef snprintf
45 # define snprintf _snprintf
46 # endif
47 # endif
48 # ifndef INFINITY
49 # define INFINITY DBL_MAX + DBL_MAX
50 # endif
51 # ifndef NAN
52 # define NAN INFINITY - INFINITY
53 # endif
54 static inline const char*
dlerror(void)55 dlerror(void)
56 {
57 return "Unknown error";
58 }
59 #else
60 # include <dlfcn.h>
61 #endif
62
63 #ifdef LILV_DYN_MANIFEST
64 # include "lv2/dynmanifest/dynmanifest.h"
65 #endif
66
67 /*
68 *
69 * Types
70 *
71 */
72
73 typedef void LilvCollection;
74
75 struct LilvPortImpl {
76 LilvNode* node; ///< RDF node
77 uint32_t index; ///< lv2:index
78 LilvNode* symbol; ///< lv2:symbol
79 LilvNodes* classes; ///< rdf:type
80 };
81
82 typedef struct LilvSpecImpl {
83 SordNode* spec;
84 SordNode* bundle;
85 LilvNodes* data_uris;
86 struct LilvSpecImpl* next;
87 } LilvSpec;
88
89 /**
90 Header of an LilvPlugin, LilvPluginClass, or LilvUI.
91 Any of these structs may be safely casted to LilvHeader, which is used to
92 implement collections using the same comparator.
93 */
94 struct LilvHeader {
95 LilvWorld* world;
96 LilvNode* uri;
97 };
98
99 #ifdef LILV_DYN_MANIFEST
100 typedef struct {
101 LilvNode* bundle;
102 void* lib;
103 LV2_Dyn_Manifest_Handle handle;
104 uint32_t refs;
105 } LilvDynManifest;
106 #endif
107
108 typedef struct {
109 LilvWorld* world;
110 LilvNode* uri;
111 char* bundle_path;
112 void* lib;
113 LV2_Descriptor_Function lv2_descriptor;
114 const LV2_Lib_Descriptor* desc;
115 uint32_t refs;
116 } LilvLib;
117
118 struct LilvPluginImpl {
119 LilvWorld* world;
120 LilvNode* plugin_uri;
121 LilvNode* bundle_uri; ///< Bundle plugin was loaded from
122 LilvNode* binary_uri; ///< lv2:binary
123 #ifdef LILV_DYN_MANIFEST
124 LilvDynManifest* dynmanifest;
125 #endif
126 const LilvPluginClass* plugin_class;
127 LilvNodes* data_uris; ///< rdfs::seeAlso
128 LilvPort** ports;
129 uint32_t num_ports;
130 bool loaded;
131 bool parse_errors;
132 bool replaced;
133 };
134
135 struct LilvPluginClassImpl {
136 LilvWorld* world;
137 LilvNode* uri;
138 LilvNode* parent_uri;
139 LilvNode* label;
140 };
141
142 struct LilvInstancePimpl {
143 LilvWorld* world;
144 LilvLib* lib;
145 };
146
147 typedef struct {
148 bool dyn_manifest;
149 bool filter_language;
150 char* lv2_path;
151 } LilvOptions;
152
153 struct LilvWorldImpl {
154 SordWorld* world;
155 SordModel* model;
156 SerdReader* reader;
157 unsigned n_read_files;
158 LilvPluginClass* lv2_plugin_class;
159 LilvPluginClasses* plugin_classes;
160 LilvSpec* specs;
161 LilvPlugins* plugins;
162 LilvPlugins* zombies;
163 LilvNodes* loaded_files;
164 ZixTree* libs;
165 struct {
166 SordNode* dc_replaces;
167 SordNode* dman_DynManifest;
168 SordNode* doap_name;
169 SordNode* lv2_Plugin;
170 SordNode* lv2_Specification;
171 SordNode* lv2_appliesTo;
172 SordNode* lv2_binary;
173 SordNode* lv2_default;
174 SordNode* lv2_designation;
175 SordNode* lv2_extensionData;
176 SordNode* lv2_index;
177 SordNode* lv2_latency;
178 SordNode* lv2_maximum;
179 SordNode* lv2_microVersion;
180 SordNode* lv2_minimum;
181 SordNode* lv2_minorVersion;
182 SordNode* lv2_name;
183 SordNode* lv2_optionalFeature;
184 SordNode* lv2_port;
185 SordNode* lv2_portProperty;
186 SordNode* lv2_reportsLatency;
187 SordNode* lv2_requiredFeature;
188 SordNode* lv2_symbol;
189 SordNode* lv2_prototype;
190 SordNode* owl_Ontology;
191 SordNode* pset_value;
192 SordNode* rdf_a;
193 SordNode* rdf_value;
194 SordNode* rdfs_Class;
195 SordNode* rdfs_label;
196 SordNode* rdfs_seeAlso;
197 SordNode* rdfs_subClassOf;
198 SordNode* xsd_base64Binary;
199 SordNode* xsd_boolean;
200 SordNode* xsd_decimal;
201 SordNode* xsd_double;
202 SordNode* xsd_integer;
203 SordNode* null_uri;
204 } uris;
205 LilvOptions opt;
206 };
207
208 typedef enum {
209 LILV_VALUE_URI,
210 LILV_VALUE_STRING,
211 LILV_VALUE_INT,
212 LILV_VALUE_FLOAT,
213 LILV_VALUE_BOOL,
214 LILV_VALUE_BLANK,
215 LILV_VALUE_BLOB
216 } LilvNodeType;
217
218 struct LilvNodeImpl {
219 LilvWorld* world;
220 SordNode* node;
221 LilvNodeType type;
222 union {
223 int int_val;
224 float float_val;
225 bool bool_val;
226 } val;
227 };
228
229 struct LilvScalePointImpl {
230 LilvNode* value;
231 LilvNode* label;
232 };
233
234 struct LilvUIImpl {
235 LilvWorld* world;
236 LilvNode* uri;
237 LilvNode* bundle_uri;
238 LilvNode* binary_uri;
239 LilvNodes* classes;
240 };
241
242 typedef struct LilvVersion {
243 int minor;
244 int micro;
245 } LilvVersion;
246
247 /*
248 *
249 * Functions
250 *
251 */
252
253 LilvPort*
254 lilv_port_new(LilvWorld* world,
255 const SordNode* node,
256 uint32_t index,
257 const char* symbol);
258 void
259 lilv_port_free(const LilvPlugin* plugin, LilvPort* port);
260
261 LilvPlugin*
262 lilv_plugin_new(LilvWorld* world, LilvNode* uri, LilvNode* bundle_uri);
263
264 void
265 lilv_plugin_clear(LilvPlugin* plugin, LilvNode* bundle_uri);
266
267 void
268 lilv_plugin_load_if_necessary(const LilvPlugin* plugin);
269
270 void
271 lilv_plugin_free(LilvPlugin* plugin);
272
273 LilvNode*
274 lilv_plugin_get_unique(const LilvPlugin* plugin,
275 const SordNode* subject,
276 const SordNode* predicate);
277
278 void
279 lilv_collection_free(LilvCollection* collection);
280
281 unsigned
282 lilv_collection_size(const LilvCollection* collection);
283
284 LilvIter*
285 lilv_collection_begin(const LilvCollection* collection);
286
287 void*
288 lilv_collection_get(const LilvCollection* collection, const LilvIter* i);
289
290 LilvPluginClass*
291 lilv_plugin_class_new(LilvWorld* world,
292 const SordNode* parent_node,
293 const SordNode* uri,
294 const char* label);
295
296 void
297 lilv_plugin_class_free(LilvPluginClass* plugin_class);
298
299 LilvLib*
300 lilv_lib_open(LilvWorld* world,
301 const LilvNode* uri,
302 const char* bundle_path,
303 const LV2_Feature* const* features);
304
305 const LV2_Descriptor*
306 lilv_lib_get_plugin(LilvLib* lib, uint32_t index);
307
308 void
309 lilv_lib_close(LilvLib* lib);
310
311 LilvNodes*
312 lilv_nodes_new(void);
313
314 LilvPlugins*
315 lilv_plugins_new(void);
316
317 LilvScalePoints*
318 lilv_scale_points_new(void);
319
320 LilvPluginClasses*
321 lilv_plugin_classes_new(void);
322
323 LilvUIs*
324 lilv_uis_new(void);
325
326 LilvNode*
327 lilv_world_get_manifest_uri(LilvWorld* world, const LilvNode* bundle_uri);
328
329 const uint8_t*
330 lilv_world_blank_node_prefix(LilvWorld* world);
331
332 SerdStatus
333 lilv_world_load_file(LilvWorld* world, SerdReader* reader, const LilvNode* uri);
334
335 SerdStatus
336 lilv_world_load_graph(LilvWorld* world, SordNode* graph, const LilvNode* uri);
337
338 LilvUI*
339 lilv_ui_new(LilvWorld* world,
340 LilvNode* uri,
341 LilvNode* type_uri,
342 LilvNode* binary_uri);
343
344 void
345 lilv_ui_free(LilvUI* ui);
346
347 LilvNode*
348 lilv_node_new(LilvWorld* world, LilvNodeType type, const char* str);
349
350 LilvNode*
351 lilv_node_new_from_node(LilvWorld* world, const SordNode* node);
352
353 int
354 lilv_header_compare_by_uri(const void* a, const void* b, void* user_data);
355
356 int
357 lilv_lib_compare(const void* a, const void* b, void* user_data);
358
359 int
360 lilv_ptr_cmp(const void* a, const void* b, void* user_data);
361
362 int
363 lilv_resource_node_cmp(const void* a, const void* b, void* user_data);
364
365 static inline int
lilv_version_cmp(const LilvVersion * a,const LilvVersion * b)366 lilv_version_cmp(const LilvVersion* a, const LilvVersion* b)
367 {
368 if (a->minor == b->minor && a->micro == b->micro) {
369 return 0;
370 }
371
372 if ((a->minor < b->minor) || (a->minor == b->minor && a->micro < b->micro)) {
373 return -1;
374 }
375
376 return 1;
377 }
378
379 struct LilvHeader*
380 lilv_collection_get_by_uri(const ZixTree* seq, const LilvNode* uri);
381
382 LilvScalePoint*
383 lilv_scale_point_new(LilvNode* value, LilvNode* label);
384
385 void
386 lilv_scale_point_free(LilvScalePoint* point);
387
388 SordIter*
389 lilv_world_query_internal(LilvWorld* world,
390 const SordNode* subject,
391 const SordNode* predicate,
392 const SordNode* object);
393
394 bool
395 lilv_world_ask_internal(LilvWorld* world,
396 const SordNode* subject,
397 const SordNode* predicate,
398 const SordNode* object);
399
400 LilvNodes*
401 lilv_world_find_nodes_internal(LilvWorld* world,
402 const SordNode* subject,
403 const SordNode* predicate,
404 const SordNode* object);
405
406 SordModel*
407 lilv_world_filter_model(LilvWorld* world,
408 SordModel* model,
409 const SordNode* subject,
410 const SordNode* predicate,
411 const SordNode* object,
412 const SordNode* graph);
413
414 #define FOREACH_MATCH(iter) for (; !sord_iter_end(iter); sord_iter_next(iter))
415
416 LilvNodes*
417 lilv_nodes_from_stream_objects(LilvWorld* world,
418 SordIter* stream,
419 SordQuadIndex field);
420
421 char*
422 lilv_strjoin(const char* first, ...);
423
424 char*
425 lilv_strdup(const char* str);
426
427 char*
428 lilv_get_lang(void);
429
430 char*
431 lilv_expand(const char* path);
432
433 char*
434 lilv_get_latest_copy(const char* path, const char* copy_path);
435
436 char*
437 lilv_find_free_path(const char* in_path,
438 bool (*exists)(const char*, const void*),
439 const void* user_data);
440
441 typedef void (*LilvVoidFunc)(void);
442
443 /** dlsym wrapper to return a function pointer (without annoying warning) */
444 static inline LilvVoidFunc
lilv_dlfunc(void * handle,const char * symbol)445 lilv_dlfunc(void* handle, const char* symbol)
446 {
447 #ifdef _WIN32
448 return (LilvVoidFunc)GetProcAddress((HMODULE)handle, symbol);
449 #else
450 typedef LilvVoidFunc (*VoidFuncGetter)(void*, const char*);
451 VoidFuncGetter dlfunc = (VoidFuncGetter)dlsym;
452 return dlfunc(handle, symbol);
453 #endif
454 }
455
456 #ifdef LILV_DYN_MANIFEST
457 static const LV2_Feature* const dman_features = {NULL};
458
459 void
460 lilv_dynmanifest_free(LilvDynManifest* dynmanifest);
461 #endif
462
463 #define LILV_ERROR(str) fprintf(stderr, "%s(): error: " str, __func__)
464 #define LILV_ERRORF(fmt, ...) \
465 fprintf(stderr, "%s(): error: " fmt, __func__, __VA_ARGS__)
466 #define LILV_WARN(str) fprintf(stderr, "%s(): warning: " str, __func__)
467 #define LILV_WARNF(fmt, ...) \
468 fprintf(stderr, "%s(): warning: " fmt, __func__, __VA_ARGS__)
469 #define LILV_NOTE(str) fprintf(stderr, "%s(): note: " str, __func__)
470 #define LILV_NOTEF(fmt, ...) \
471 fprintf(stderr, "%s(): note: " fmt, __func__, __VA_ARGS__)
472
473 #ifdef __cplusplus
474 }
475 #endif
476
477 #endif /* LILV_INTERNAL_H */
478