Changeset 2105

Show
Ignore:
Timestamp:
06/14/09 15:28:29 (15 months ago)
Author:
drobilla
Message:

Updated LV2 dynamic manifest extension.

Location:
trunk/slv2/src
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/slv2/src/plugin.c

    r2094 r2105  
    3131#include "slv2/util.h" 
    3232#include "slv2_internal.h" 
     33#ifdef SLV2_DYN_MANIFEST 
     34#include <dlfcn.h> 
     35#endif 
    3336 
    3437 
     
    4447        plugin->bundle_uri = slv2_value_new_librdf_uri(world, bundle_uri); 
    4548        plugin->binary_uri = NULL; 
     49#ifdef SLV2_DYN_MANIFEST 
     50        plugin->dynman_uri = NULL; 
     51#endif 
    4652        plugin->plugin_class = NULL; 
    4753        plugin->data_uris = slv2_values_new(); 
     
    5157        plugin->num_ports = 0; 
    5258 
     59        /*printf("PLUGIN %s DATA URIs: %p\n", 
     60                        slv2_value_as_string(plugin->plugin_uri), 
     61                        (void*)plugin->data_uris);*/ 
     62 
    5363        return plugin; 
    5464} 
     
    6777        slv2_value_free(p->binary_uri); 
    6878        p->binary_uri = NULL; 
     79 
     80#ifdef SLV2_DYN_MANIFEST 
     81        slv2_value_free(p->dynman_uri); 
     82        p->dynman_uri = NULL; 
     83#endif 
    6984 
    7085        if (p->ports) { 
     
    206221                librdf_parser_parse_into_model(p->world->parser, data_uri, NULL, p->rdf); 
    207222        } 
     223 
     224#ifdef SLV2_DYN_MANIFEST 
     225        // Load and parse dynamic manifest data, if this is a library 
     226        if (p->dynman_uri) { 
     227                const char* lib_path = slv2_uri_to_path(slv2_value_as_string(p->dynman_uri)); 
     228                void* lib = dlopen(lib_path, RTLD_LAZY); 
     229                if (!lib) { 
     230                        SLV2_WARNF("Unable to open dynamic manifest %s\n", slv2_value_as_string(p->dynman_uri)); 
     231                        return; 
     232                } 
     233 
     234                typedef int (*OpenFunc)(LV2_Dyn_Manifest_Handle*, const LV2_Dyn_Manifest_Feature *const *); 
     235                OpenFunc open_func = (OpenFunc)dlsym(lib, "lv2_dyn_manifest_open"); 
     236                LV2_Dyn_Manifest_Handle handle = NULL; 
     237                if (open_func) 
     238                        open_func(&handle, &dman_features); 
     239 
     240                typedef int (*GetDataFunc)(LV2_Dyn_Manifest_Handle handle, 
     241                                           FILE*                   fp, 
     242                                           const char*             uri); 
     243                GetDataFunc get_data_func = (GetDataFunc)dlsym(lib, "lv2_dyn_manifest_get_data"); 
     244                if (get_data_func) { 
     245                        FILE* fd = tmpfile(); 
     246                        get_data_func(handle, fd, slv2_value_as_string(p->plugin_uri)); 
     247                        rewind(fd); 
     248                        librdf_parser_parse_file_handle_into_model(p->world->parser, 
     249                                        fd, 0, slv2_value_as_librdf_uri(p->plugin_uri), p->rdf); 
     250                        fclose(fd); 
     251                } 
     252 
     253                typedef int (*CloseFunc)(LV2_Dyn_Manifest_Handle); 
     254                CloseFunc close_func = (CloseFunc)dlsym(lib, "lv2_dyn_manifest_close"); 
     255                if (close_func) 
     256                        close_func(handle); 
     257        } 
     258#endif 
     259        assert(p->rdf); 
    208260} 
    209261 
  • trunk/slv2/src/slv2_internal.h

    r2090 r2105  
    1616 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 
    1717 */ 
     18 
     19#include "slv2-config.h" 
    1820 
    1921#ifndef __SLV2_INTERNAL_H__ 
     
    3133#include "slv2/types.h" 
    3234#include "slv2/lv2_ui.h" 
    33  
     35#ifdef SLV2_DYN_MANIFEST 
     36#include "lv2_dyn_manifest.h" 
     37#endif 
     38 
     39#define SLV2_NS_RDFS (const unsigned char*)"http://www.w3.org/2000/01/rdf-schema#" 
     40#define SLV2_NS_SLV2 (const unsigned char*)"http://drobilla.net/ns/slv2#" 
    3441 
    3542/* ********* PORT ********* */ 
     
    6067        SLV2Value            bundle_uri; ///< Bundle directory plugin was loaded from 
    6168        SLV2Value            binary_uri; ///< lv2:binary 
     69//#ifdef SLV2_DYN_MANIFEST 
     70        SLV2Value            dynman_uri; ///< dynamic manifest binary 
     71//#endif 
    6272        SLV2PluginClass      plugin_class; 
    6373        raptor_sequence*     data_uris;  ///< rdfs::seeAlso 
     
    245255char* slv2_get_lang(); 
    246256 
     257 
     258/* ********* Dynamic Manifest ********* */ 
     259#ifdef SLV2_DYN_MANIFEST 
     260static const LV2_Dyn_Manifest_Feature* const dman_features = { NULL }; 
     261#endif 
     262 
    247263#define SLV2_ERROR(str)       fprintf(stderr, "ERROR: %s: " str, __func__) 
    248264#define SLV2_ERRORF(fmt, ...) fprintf(stderr, "ERROR: %s: " fmt, __func__, __VA_ARGS__) 
  • trunk/slv2/src/world.c

    r2103 r2105  
    2525#include <string.h> 
    2626#include <librdf.h> 
    27 #include <dlfcn.h> 
    2827#include "slv2/types.h" 
    2928#include "slv2/world.h" 
     
    3231#include "slv2_internal.h" 
    3332#ifdef SLV2_DYN_MANIFEST 
    34 #include "lv2_dyn_manifest.h" 
     33#include <dlfcn.h> 
    3534#endif 
    3635 
     
    222221        librdf_query* query = librdf_new_query(world->world, "sparql", NULL, query_str, NULL); 
    223222        librdf_query_results* query_results = librdf_query_execute(query, manifest_model); 
    224         while (!librdf_query_results_finished(query_results)) { 
    225                 librdf_node* dynman_node = librdf_query_results_get_binding_value(query_results, 0); 
     223        for (; !librdf_query_results_finished(query_results); librdf_query_results_next(query_results)) { 
    226224                librdf_node* binary_node = librdf_query_results_get_binding_value(query_results, 1); 
    227225 
    228                 if (librdf_node_get_type(binary_node) == LIBRDF_NODE_TYPE_RESOURCE) { 
    229                         const char* lib_path = slv2_uri_to_path( 
    230                                         (const char*)librdf_uri_as_string(librdf_node_get_uri(binary_node))); 
    231  
    232                         if (lib_path) { 
    233                                 void* lib = dlopen(lib_path, RTLD_NOW); 
    234  
    235                                 // Open dynamic manifest 
    236                                 typedef int (*OpenFunc)(LV2_Dyn_Manifest_Handle*, 
    237                                                 const LV2_Dyn_Manifest_Feature *const *); 
    238                                 OpenFunc open_func = (OpenFunc)dlsym(lib, "lv2_dyn_manifest_open"); 
    239                                 open_func(&handle, &features); 
    240  
    241                                 // Get subjects (what would be in the manifest) 
    242                                 typedef int (*GetSubjectsFunc)(LV2_Dyn_Manifest_Handle, FILE*); 
    243                                 GetSubjectsFunc get_subjects_func = (GetSubjectsFunc)dlsym(lib, 
    244                                                 "lv2_dyn_manifest_get_subjects"); 
    245                                 if (get_subjects_func) { 
    246                                         printf("DYNAMIC MANIFEST <%s> @ <%s> {\n", 
    247                                                         librdf_uri_as_string(librdf_node_get_uri(dynman_node)), 
    248                                                         librdf_uri_as_string(librdf_node_get_uri(binary_node))); 
    249                                         //FILE* dyn_manifest = tmpfile(); 
    250                                         FILE* dyn_manifest = fopen("/tmp/naspro.ttl", "w+"); 
    251                                         get_subjects_func(handle, dyn_manifest); 
    252                                         rewind(dyn_manifest); 
    253                                         librdf_parser_parse_file_handle_into_model(world->parser, 
    254                                                         dyn_manifest, 0, manifest_uri, manifest_model); 
    255                                         fclose(dyn_manifest); 
    256                                 } 
    257                         } 
    258  
     226                if (librdf_node_get_type(binary_node) != LIBRDF_NODE_TYPE_RESOURCE) 
     227                        continue; 
     228 
     229                const unsigned char* lib_uri  = librdf_uri_as_string(librdf_node_get_uri(binary_node)); 
     230                const char*          lib_path = slv2_uri_to_path((const char*)lib_uri); 
     231                if (!lib_path) 
     232                        continue; 
     233 
     234                void* lib = dlopen(lib_path, RTLD_LAZY); 
     235                if (!lib) 
     236                        continue; 
     237 
     238                // Open dynamic manifest 
     239                typedef int (*OpenFunc)(LV2_Dyn_Manifest_Handle*, const LV2_Dyn_Manifest_Feature *const *); 
     240                OpenFunc open_func = (OpenFunc)dlsym(lib, "lv2_dyn_manifest_open"); 
     241                if (open_func) 
     242                        open_func(&handle, &features); 
     243 
     244                // Get subjects (the data that would be in manifest.ttl) 
     245                typedef int (*GetSubjectsFunc)(LV2_Dyn_Manifest_Handle, FILE*); 
     246                GetSubjectsFunc get_subjects_func = (GetSubjectsFunc)dlsym(lib, 
     247                                "lv2_dyn_manifest_get_subjects"); 
     248                if (!get_subjects_func) 
     249                        continue; 
     250 
     251                librdf_storage* dyn_manifest_storage = slv2_world_new_storage(world); 
     252                librdf_model* dyn_manifest_model = librdf_new_model(world->world, 
     253                        dyn_manifest_storage, NULL); 
     254 
     255                FILE* fd = tmpfile(); 
     256                get_subjects_func(handle, fd); 
     257                rewind(fd); 
     258                librdf_parser_parse_file_handle_into_model(world->parser, 
     259                                fd, 0, librdf_node_get_uri(binary_node), dyn_manifest_model); 
     260                fclose(fd); 
     261 
     262                // Query plugins from dynamic manifest 
     263                librdf_query* dyn_query = librdf_new_query(world->world, "sparql", NULL, 
     264                                (const unsigned char*) 
     265                                "PREFIX :       <http://lv2plug.in/ns/lv2core#>\n" 
     266                                "PREFIX dynman: <http://lv2plug.in/ns/ext/dynmanifest#>\n" 
     267                                "SELECT DISTINCT ?plugin WHERE {\n" 
     268                                "       ?plugin a :Plugin .\n" 
     269                                "}", NULL); 
     270 
     271                // Add ?plugin rdfs:seeAlso ?binary to dynamic model 
     272                librdf_query_results* r = librdf_query_execute(dyn_query, dyn_manifest_model); 
     273                for (; !librdf_query_results_finished(r); librdf_query_results_next(r)) { 
     274                        librdf_node* plugin = librdf_query_results_get_binding_value(r, 0); 
     275                        librdf_node* predicate = librdf_new_node_from_uri_string(world->world, 
     276                                        (const unsigned char*)(SLV2_NS_RDFS "seeAlso")); 
     277                        librdf_node* object = librdf_new_node_from_node(binary_node); 
     278                        librdf_model_add(dyn_manifest_model, plugin, predicate, object); 
    259279                } 
    260  
    261                 librdf_query_results_next(query_results); 
     280                librdf_free_query_results(r); 
     281                librdf_free_query(dyn_query); 
     282 
     283                /*printf("*************************************************\n"); 
     284                librdf_model_print(dyn_manifest_model, stdout); 
     285                printf("*************************************************\n");*/ 
     286 
     287                // Merge dynamic model into main manifest model 
     288                librdf_stream* dyn_manifest_stream = librdf_model_as_stream(dyn_manifest_model); 
     289                librdf_model_add_statements(manifest_model, dyn_manifest_stream); 
     290                librdf_free_stream(dyn_manifest_stream); 
     291                librdf_free_model(dyn_manifest_model); 
     292                librdf_free_storage(dyn_manifest_storage); 
    262293        } 
    263294        librdf_free_query_results(query_results); 
     
    279310                librdf_node* subject = plugin_node; 
    280311                librdf_node* predicate = librdf_new_node_from_uri_string(world->world, 
    281                                 (unsigned char*)"http://www.w3.org/2000/01/rdf-schema#seeAlso"); 
     312                                (const unsigned char*)(SLV2_NS_RDFS "seeAlso")); 
    282313                librdf_node* object = librdf_new_node_from_uri(world->world, 
    283314                                manifest_uri); 
    284  
    285315                librdf_model_add(world->model, subject, predicate, object); 
    286316 
     
    288318                subject = librdf_new_node_from_node(plugin_node); 
    289319                predicate = librdf_new_node_from_uri_string(world->world, 
    290                                 (unsigned char*)"http://drobilla.net/ns/slv2#bundleURI"); 
     320                                (const unsigned char*)(SLV2_NS_SLV2 "bundleURI")); 
    291321                object = librdf_new_node_from_uri(world->world, bundle_uri->val.uri_val); 
    292322 
     
    313343                librdf_node* subject = spec_node; 
    314344                librdf_node* predicate = librdf_new_node_from_uri_string(world->world, 
    315                                 (unsigned char*)"http://www.w3.org/2000/01/rdf-schema#seeAlso"); 
     345                                (const unsigned char*)(SLV2_NS_RDFS "seeAlso")); 
    316346                librdf_node* object = librdf_new_node_from_uri(world->world, 
    317347                                manifest_uri); 
     
    322352                subject = librdf_new_node_from_node(spec_node); 
    323353                predicate = librdf_new_node_from_uri_string(world->world, 
    324                                 (unsigned char*)"http://drobilla.net/ns/slv2#bundleURI"); 
     354                                (const unsigned char*)(SLV2_NS_SLV2 "bundleURI")); 
    325355                object = librdf_new_node_from_uri(world->world, bundle_uri->val.uri_val); 
    326356 
     
    592622                "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n" 
    593623                "PREFIX slv2: <http://drobilla.net/ns/slv2#>\n" 
    594                 "SELECT DISTINCT ?plugin ?data ?bundle\n" 
    595                 "WHERE { ?plugin a :Plugin; slv2:bundleURI ?bundle; rdfs:seeAlso ?data }\n"; 
     624                "SELECT DISTINCT ?plugin ?data ?bundle WHERE {\n" 
     625                "       ?plugin a                  :Plugin ;\n" 
     626                "           slv2:bundleURI     ?bundle ;\n" 
     627                "           rdfs:seeAlso       ?data .\n" 
     628                "}\n"; 
    596629 
    597630        librdf_query* q = librdf_new_query(world->world, "sparql", 
     
    659692                        plugin->world = world; 
    660693 
    661                         // FIXME: check for duplicates 
    662                         raptor_sequence_push(plugin->data_uris, 
    663                                         slv2_value_new_librdf_uri(plugin->world, data_uri)); 
     694#ifdef SLV2_DYN_MANIFEST 
     695                        const char* const data_uri_str = (const char*)librdf_uri_as_string(data_uri); 
     696                        void* lib = dlopen(slv2_uri_to_path(data_uri_str), RTLD_LAZY); 
     697                        if (lib) { 
     698                                plugin->dynman_uri = slv2_value_new_librdf_uri(world, data_uri); 
     699                                librdf_query_results_next(results); 
     700                        } else 
     701#endif 
     702                        if (data_uri) { 
     703                                assert(plugin->data_uris); 
     704                                // FIXME: check for duplicates 
     705                                raptor_sequence_push(plugin->data_uris, 
     706                                                slv2_value_new_librdf_uri(plugin->world, data_uri)); 
     707                        } 
    664708                } 
    665709