summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2014-07-15 19:48:59 +0000
committerDavid Robillard <d@drobilla.net>2014-07-15 19:48:59 +0000
commit45f02a1390bbea3f7acbef5fdb4807a9f9331f3d (patch)
treec0a04698cdc1d392b5671ebe3c20d302acae61bf /src
parentc067725cf5c187bca3c7b9a41c8b90a8ce50d95d (diff)
downloadlilv-45f02a1390bbea3f7acbef5fdb4807a9f9331f3d.tar.gz
lilv-45f02a1390bbea3f7acbef5fdb4807a9f9331f3d.tar.bz2
lilv-45f02a1390bbea3f7acbef5fdb4807a9f9331f3d.zip
Add lilv_world_unload_bundle() and lilv_world_unload_resource().
git-svn-id: http://svn.drobilla.net/lad/trunk/lilv@5413 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/state.c8
-rw-r--r--src/world.c126
2 files changed, 112 insertions, 22 deletions
diff --git a/src/state.c b/src/state.c
index 79b55ec..0a775c9 100644
--- a/src/state.c
+++ b/src/state.c
@@ -1,5 +1,5 @@
/*
- Copyright 2007-2012 David Robillard <http://drobilla.net>
+ Copyright 2007-2014 David Robillard <http://drobilla.net>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -439,6 +439,12 @@ new_state_from_model(LilvWorld* world,
const SordNode* node,
const char* dir)
{
+ // Check that we know at least something about this state subject
+ if (!sord_ask(model, node, 0, 0, 0)) {
+ return NULL;
+ }
+
+ // Allocate state
LilvState* const state = (LilvState*)malloc(sizeof(LilvState));
memset(state, '\0', sizeof(LilvState));
state->dir = lilv_strdup(dir);
diff --git a/src/world.c b/src/world.c
index 228db8a..48bf401 100644
--- a/src/world.c
+++ b/src/world.c
@@ -1,5 +1,5 @@
/*
- Copyright 2007-2011 David Robillard <http://drobilla.net>
+ Copyright 2007-2014 David Robillard <http://drobilla.net>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -362,7 +362,7 @@ lilv_world_add_spec(LilvWorld* world,
static void
lilv_world_add_plugin(LilvWorld* world,
const SordNode* plugin_node,
- SerdNode* manifest_uri,
+ const LilvNode* manifest_uri,
void* dynmanifest,
const SordNode* bundle_node)
{
@@ -385,7 +385,7 @@ lilv_world_add_plugin(LilvWorld* world,
// Add manifest as plugin data file (as if it were rdfs:seeAlso)
zix_tree_insert((ZixTree*)plugin->data_uris,
- lilv_new_uri(world, (const char*)manifest_uri->buf),
+ lilv_node_duplicate(manifest_uri),
NULL);
#ifdef LILV_DYN_MANIFEST
@@ -431,9 +431,9 @@ lilv_world_load_graph(LilvWorld* world, SordNode* graph, const LilvNode* uri)
}
static void
-lilv_world_load_dyn_manifest(LilvWorld* world,
- SordNode* bundle_node,
- SerdNode manifest_uri)
+lilv_world_load_dyn_manifest(LilvWorld* world,
+ SordNode* bundle_node,
+ const LilvNode* manifest)
{
#ifdef LILV_DYN_MANIFEST
if (!world->opt.dyn_manifest) {
@@ -542,9 +542,8 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
world->uris.lv2_Plugin,
dmanifest);
FOREACH_MATCH(plug_results) {
- const SordNode* plugin_node = sord_iter_get_node(plug_results, SORD_SUBJECT);
- lilv_world_add_plugin(world, plugin_node,
- &manifest_uri, desc, bundle_node);
+ const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT);
+ lilv_world_add_plugin(world, plug, manifest, desc, bundle_node);
}
sord_iter_free(plug_results);
@@ -554,6 +553,18 @@ lilv_world_load_dyn_manifest(LilvWorld* world,
#endif // LILV_DYN_MANIFEST
}
+static
+LilvNode*
+lilv_world_get_manifest_uri(LilvWorld* world, LilvNode* bundle_uri)
+{
+ SerdNode manifest_uri = lilv_new_uri_relative_to_base(
+ (const uint8_t*)"manifest.ttl",
+ (const uint8_t*)sord_node_get_string(bundle_uri->node));
+ LilvNode* manifest = lilv_new_uri(world, (const char*)manifest_uri.buf);
+ serd_node_free(&manifest_uri);
+ return manifest;
+}
+
LILV_API
void
lilv_world_load_bundle(LilvWorld* world, LilvNode* bundle_uri)
@@ -564,17 +575,14 @@ lilv_world_load_bundle(LilvWorld* world, LilvNode* bundle_uri)
return;
}
- SordNode* bundle_node = bundle_uri->node;
- SerdNode manifest_uri = lilv_new_uri_relative_to_base(
- (const uint8_t*)"manifest.ttl",
- (const uint8_t*)sord_node_get_string(bundle_node));
- LilvNode* manifest = lilv_new_uri(world, (const char*)manifest_uri.buf);
+ SordNode* bundle_node = bundle_uri->node;
+ LilvNode* manifest = lilv_world_get_manifest_uri(world, bundle_uri);
// Read manifest into model with graph = bundle_node
SerdStatus st = lilv_world_load_graph(world, bundle_node, manifest);
- lilv_node_free(manifest);
if (st > SERD_FAILURE) {
- LILV_ERRORF("Error reading %s\n", manifest_uri.buf);
+ LILV_ERRORF("Error reading %s\n", lilv_node_as_string(manifest));
+ lilv_node_free(manifest);
return;
}
@@ -586,13 +594,12 @@ lilv_world_load_bundle(LilvWorld* world, LilvNode* bundle_uri)
world->uris.lv2_Plugin,
bundle_node);
FOREACH_MATCH(plug_results) {
- const SordNode* plugin_node = sord_iter_get_node(plug_results, SORD_SUBJECT);
- lilv_world_add_plugin(world, plugin_node,
- &manifest_uri, NULL, bundle_node);
+ const SordNode* plug = sord_iter_get_node(plug_results, SORD_SUBJECT);
+ lilv_world_add_plugin(world, plug, manifest, NULL, bundle_node);
}
sord_iter_free(plug_results);
- lilv_world_load_dyn_manifest(world, bundle_node, manifest_uri);
+ lilv_world_load_dyn_manifest(world, bundle_node, manifest);
// ?specification a lv2:Specification
SordIter* spec_results = sord_search(
@@ -607,7 +614,51 @@ lilv_world_load_bundle(LilvWorld* world, LilvNode* bundle_uri)
}
sord_iter_free(spec_results);
- serd_node_free(&manifest_uri);
+ lilv_node_free(manifest);
+}
+
+static int
+lilv_world_drop_graph(LilvWorld* world, LilvNode* graph)
+{
+ SordIter* i = sord_search(world->model, NULL, NULL, NULL, graph->node);
+
+ while (!sord_iter_end(i)) {
+ // Get quad and increment iter so sord_remove doesn't invalidate it
+ SordQuad quad;
+ sord_iter_get(i, quad);
+ sord_iter_next(i);
+
+ // Remove quad (nodes may now be deleted, quad is invalid)
+ sord_remove(world->model, quad);
+ }
+ sord_iter_free(i);
+
+ return 0;
+}
+
+/** Remove loaded_files entry so file will be reloaded if requested. */
+static int
+lilv_world_unload_file(LilvWorld* world, LilvNode* file)
+{
+ ZixTreeIter* iter;
+ if (!zix_tree_find((ZixTree*)world->loaded_files, file, &iter)) {
+ zix_tree_remove(world->loaded_files, iter);
+ return 0;
+ }
+ return 1;
+}
+
+LILV_API
+int
+lilv_world_unload_bundle(LilvWorld* world, LilvNode* bundle_uri)
+{
+ // Remove loaded_files entry for manifest.ttl
+ LilvNode* manifest = lilv_world_get_manifest_uri(world, bundle_uri);
+ lilv_world_unload_file(world, manifest);
+ lilv_node_free(manifest);
+
+ // Drop everything in bundle graph
+ return lilv_world_drop_graph(world, bundle_uri);
}
static void
@@ -824,6 +875,39 @@ lilv_world_load_resource(LilvWorld* world,
}
LILV_API
+int
+lilv_world_unload_resource(LilvWorld* world,
+ const LilvNode* resource)
+{
+ if (!lilv_node_is_uri(resource) && !lilv_node_is_blank(resource)) {
+ LILV_ERRORF("Node `%s' is not a resource\n",
+ sord_node_get_string(resource->node));
+ return -1;
+ }
+
+ int n_dropped = 0;
+ SordIter* files = sord_search(world->model,
+ resource->node,
+ world->uris.rdfs_seeAlso,
+ NULL, NULL);
+ FOREACH_MATCH(files) {
+ const SordNode* file = sord_iter_get_node(files, SORD_OBJECT);
+ const uint8_t* file_str = sord_node_get_string(file);
+ LilvNode* file_node = lilv_node_new_from_node(world, file);
+ if (sord_node_get_type(file) != SORD_URI) {
+ LILV_ERRORF("rdfs:seeAlso node `%s' is not a URI\n", file_str);
+ } else if (!lilv_world_drop_graph(world, file_node)) {
+ lilv_world_unload_file(world, file_node);
+ ++n_dropped;
+ }
+ lilv_node_free(file_node);
+ }
+ sord_iter_free(files);
+
+ return n_dropped;
+}
+
+LILV_API
const LilvPluginClass*
lilv_world_get_plugin_class(const LilvWorld* world)
{