X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=mlt%2Fsrc%2Fframework%2Fmlt_repository.c;h=0928b371965bbef65d248e795ffc34e7b891345a;hb=4ed2712bbdac2182c7c0d6477ac77c9f92aaf02a;hp=9c41bf92da85cc21367446b652a0ad77eff27141;hpb=15934f863eff9ee542f8b65fb7335ad944508f2f;p=melted diff --git a/mlt/src/framework/mlt_repository.c b/mlt/src/framework/mlt_repository.c index 9c41bf9..0928b37 100644 --- a/mlt/src/framework/mlt_repository.c +++ b/mlt/src/framework/mlt_repository.c @@ -19,24 +19,190 @@ */ #include "mlt_repository.h" +#include "mlt_properties.h" + +#include #include +#include +#include struct mlt_repository_s { + struct mlt_properties_s parent; + mlt_properties object_list; }; -mlt_repository mlt_repository_init( char *file, char *symbol ) +static char *construct_full_file( char *output, char *prefix, char *file ) { - return NULL; + strcpy( output, prefix ); + if ( prefix[ strlen( prefix ) - 1 ] != '/' ) + strcat( output, "/" ); + strcat( output, file ); + return output; +} + +static char *chomp( char *input ) +{ + if ( input[ strlen( input ) - 1 ] == '\n' ) + input[ strlen( input ) - 1 ] = '\0'; + return input; +} + +static mlt_properties construct_object( char *prefix, char *id ) +{ + mlt_properties output = calloc( sizeof( struct mlt_properties_s ), 1 ); + mlt_properties_init( output, NULL ); + mlt_properties_set( output, "prefix", prefix ); + mlt_properties_set( output, "id", id ); + return output; +} + +static mlt_properties construct_service( mlt_properties object, char *id ) +{ + mlt_properties output = calloc( sizeof( struct mlt_properties_s ), 1 ); + mlt_properties_init( output, NULL ); + mlt_properties_set_data( output, "object", object, 0, NULL, NULL ); + mlt_properties_set( output, "id", id ); + return output; +} + +void *construct_instance( mlt_properties service_properties, char *symbol, void *input ) +{ + // Extract the service + char *service = mlt_properties_get( service_properties, "id" ); + + // Get the object properties + void *object_properties = mlt_properties_get_data( service_properties, "object", NULL ); + + // Get the dlopen'd object + void *object = mlt_properties_get_data( object_properties, "dlopen", NULL ); + + // Get the dlsym'd symbol + void *( *symbol_ptr )( char *, void * ) = mlt_properties_get_data( object_properties, symbol, NULL ); + + // Check that we have object and open if we don't + if ( object == NULL ) + { + char full_file[ 512 ]; + + // Get the prefix and id of the shared object + char *prefix = mlt_properties_get( object_properties, "prefix" ); + char *file = mlt_properties_get( object_properties, "id" ); + + // Construct the full file + construct_full_file( full_file, prefix, file ); + + // Open the shared object + object = dlopen( full_file, RTLD_NOW | RTLD_GLOBAL ); + + // Set it on the properties + mlt_properties_set_data( object_properties, "dlopen", object, 0, ( void (*)( void * ) )dlclose, NULL ); + } + + // Now check if we have this symbol pointer + if ( object != NULL && symbol_ptr == NULL ) + { + // Construct it now + symbol_ptr = dlsym( object, symbol ); + + // Set it on the properties + mlt_properties_set_data( object_properties, "dlsym", symbol_ptr, 0, NULL, NULL ); + } + + // Construct the service + return symbol_ptr != NULL ? symbol_ptr( service, input ) : NULL; +} + +void destroy_properties( void *arg ) +{ + mlt_properties_close( arg ); + free( arg ); +} + +mlt_repository mlt_repository_init( mlt_properties object_list, char *prefix, char *data, char *symbol ) +{ + char full_file[ 512 ]; + FILE *file; + + // Construct the repository + mlt_repository this = calloc( sizeof( struct mlt_repository_s ), 1 ); + mlt_properties_init( &this->parent, NULL ); + + // Add the symbol to THIS repository properties. + mlt_properties_set( &this->parent, "_symbol", symbol ); + + // Asociate the repository to the global object_list + this->object_list = object_list; + + // Construct full file + construct_full_file( full_file, prefix, data ); + + // Open the file + file = fopen( full_file, "r" ); + + // Parse the contents + if ( file != NULL ) + { + char full[ 512 ]; + char service[ 256 ]; + char object[ 256 ]; + + while( fgets( full, 512, file ) ) + { + chomp( full ); + + if ( full[ 0 ] != '#' && full[ 0 ] != '\0' && sscanf( full, "%s %s", service, object ) == 2 ) + { + // Get the object properties first + mlt_properties object_properties = mlt_properties_get_data( object_list, object, NULL ); + + // If their are no properties, create them now + if ( object_properties == NULL ) + { + // Construct the object + object_properties = construct_object( prefix, object ); + + // Add it to the object list + mlt_properties_set_data( object_list, object, object_properties, 0, destroy_properties, NULL ); + } + + // Now construct a property for the service + mlt_properties service_properties = construct_service( object_properties, service ); + + // Add it to the repository + mlt_properties_set_data( &this->parent, service, service_properties, 0, destroy_properties, NULL ); + } + } + + // Close the file + fclose( file ); + } + + return this; } void *mlt_repository_fetch( mlt_repository this, char *service, void *input ) { + // Get the service properties + mlt_properties service_properties = mlt_properties_get_data( &this->parent, service, NULL ); + + // If the service exists + if ( service_properties != NULL ) + { + // Get the symbol that is used to generate this service + char *symbol = mlt_properties_get( &this->parent, "_symbol" ); + + // Now get an instance of the service + return construct_instance( service_properties, symbol, input ); + } + return NULL; } void mlt_repository_close( mlt_repository this ) { + mlt_properties_close( &this->parent ); + free( this ); }