summaryrefslogtreecommitdiffstats
path: root/src/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugin.c')
-rw-r--r--src/plugin.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/plugin.c b/src/plugin.c
index 9564336..2aa9417 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -30,6 +30,9 @@
#include "slv2/query.h"
#include "slv2/util.h"
#include "slv2_internal.h"
+#ifdef SLV2_DYN_MANIFEST
+#include <dlfcn.h>
+#endif
/* private
@@ -43,6 +46,9 @@ slv2_plugin_new(SLV2World world, SLV2Value uri, librdf_uri* bundle_uri)
plugin->plugin_uri = uri;
plugin->bundle_uri = slv2_value_new_librdf_uri(world, bundle_uri);
plugin->binary_uri = NULL;
+#ifdef SLV2_DYN_MANIFEST
+ plugin->dynman_uri = NULL;
+#endif
plugin->plugin_class = NULL;
plugin->data_uris = slv2_values_new();
plugin->ports = NULL;
@@ -50,6 +56,10 @@ slv2_plugin_new(SLV2World world, SLV2Value uri, librdf_uri* bundle_uri)
plugin->rdf = NULL;
plugin->num_ports = 0;
+ /*printf("PLUGIN %s DATA URIs: %p\n",
+ slv2_value_as_string(plugin->plugin_uri),
+ (void*)plugin->data_uris);*/
+
return plugin;
}
@@ -67,6 +77,11 @@ slv2_plugin_free(SLV2Plugin p)
slv2_value_free(p->binary_uri);
p->binary_uri = NULL;
+#ifdef SLV2_DYN_MANIFEST
+ slv2_value_free(p->dynman_uri);
+ p->dynman_uri = NULL;
+#endif
+
if (p->ports) {
for (uint32_t i = 0; i < p->num_ports; ++i)
slv2_port_free(p->ports[i]);
@@ -205,6 +220,43 @@ slv2_plugin_load(SLV2Plugin p)
librdf_uri* data_uri = slv2_value_as_librdf_uri(data_uri_val);
librdf_parser_parse_into_model(p->world->parser, data_uri, NULL, p->rdf);
}
+
+#ifdef SLV2_DYN_MANIFEST
+ // Load and parse dynamic manifest data, if this is a library
+ if (p->dynman_uri) {
+ const char* lib_path = slv2_uri_to_path(slv2_value_as_string(p->dynman_uri));
+ void* lib = dlopen(lib_path, RTLD_LAZY);
+ if (!lib) {
+ SLV2_WARNF("Unable to open dynamic manifest %s\n", slv2_value_as_string(p->dynman_uri));
+ return;
+ }
+
+ typedef int (*OpenFunc)(LV2_Dyn_Manifest_Handle*, const LV2_Dyn_Manifest_Feature *const *);
+ OpenFunc open_func = (OpenFunc)dlsym(lib, "lv2_dyn_manifest_open");
+ LV2_Dyn_Manifest_Handle handle = NULL;
+ if (open_func)
+ open_func(&handle, &dman_features);
+
+ typedef int (*GetDataFunc)(LV2_Dyn_Manifest_Handle handle,
+ FILE* fp,
+ const char* uri);
+ GetDataFunc get_data_func = (GetDataFunc)dlsym(lib, "lv2_dyn_manifest_get_data");
+ if (get_data_func) {
+ FILE* fd = tmpfile();
+ get_data_func(handle, fd, slv2_value_as_string(p->plugin_uri));
+ rewind(fd);
+ librdf_parser_parse_file_handle_into_model(p->world->parser,
+ fd, 0, slv2_value_as_librdf_uri(p->plugin_uri), p->rdf);
+ fclose(fd);
+ }
+
+ typedef int (*CloseFunc)(LV2_Dyn_Manifest_Handle);
+ CloseFunc close_func = (CloseFunc)dlsym(lib, "lv2_dyn_manifest_close");
+ if (close_func)
+ close_func(handle);
+ }
+#endif
+ assert(p->rdf);
}