WvStreams
moduleloader.cc
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002  *
00003  * XPLC - Cross-Platform Lightweight Components
00004  * Copyright (C) 2002-2004, Net Integration Technologies, Inc.
00005  * Copyright (C) 2002-2004, Pierre Phaneuf
00006  * Copyright (C) 2002-2004, Stéphane Lajoie
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation; either version 2.1 of
00011  * the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021  * USA
00022  */
00023 
00024 #include <assert.h>
00025 #include <xplc/ICategoryManager.h>
00026 #include <xplc/uuidops.h>
00027 #include "moduleloader.h"
00028 #include "loader.h"
00029 
00030 UUID_MAP_BEGIN(ModuleLoader)
00031   UUID_MAP_ENTRY(IObject)
00032   UUID_MAP_ENTRY(IModuleLoader)
00033   UUID_MAP_END
00034 
00035 UUID_MAP_BEGIN(Module)
00036   UUID_MAP_ENTRY(IObject)
00037   UUID_MAP_ENTRY(IServiceHandler)
00038   UUID_MAP_ENTRY(IModule)
00039   UUID_MAP_END
00040 
00041 IModule* ModuleLoader::loadModule(const char* modulename) {
00042   return Module::loadModule(modulename);
00043 }
00044 
00045 Module* Module::loadModule(const char* modulename) {
00046   XPLC_ModuleInfo* moduleinfo = 0;
00047   void* dlh;
00048   const char* err;
00049 
00050   err = loaderOpen(modulename, &dlh);
00051   if(err)
00052     return NULL;
00053 
00054   void* symbol;
00055   err = loaderSymbol(dlh, "XPLC_Module", &symbol);
00056   moduleinfo = reinterpret_cast<XPLC_ModuleInfo*>(symbol);
00057 
00058   if(err
00059      || !moduleinfo
00060      || moduleinfo->magic != XPLC_MODULE_MAGIC) {
00061     loaderClose(dlh);
00062     return NULL;
00063   }
00064 
00065   switch(moduleinfo->version_major) {
00066 #ifdef UNSTABLE
00067   case -1:
00068     /* nothing to do */
00069     break;
00070 #endif
00071   default:
00072     loaderClose(dlh);
00073     return NULL;
00074   };
00075 
00076   return new Module(dlh, moduleinfo);
00077 }
00078 
00079 Module::Module(void* aHandle, const XPLC_ModuleInfo* aModuleInfo):
00080   handle(aHandle),
00081   moduleinfo(aModuleInfo)
00082 {
00083   assert(moduleinfo);
00084 
00085   if(moduleinfo->categories) {
00086     IServiceManager* servmgr;
00087     IObject* obj;
00088     ICategoryManager* catmgr;
00089     const XPLC_CategoryEntry* entry;
00090 
00091     servmgr = XPLC_getServiceManager();
00092     assert(servmgr);
00093 
00094     obj = servmgr->getObject(XPLC_categoryManager);
00095     assert(obj);
00096 
00097     servmgr->release();
00098 
00099     catmgr = mutate<ICategoryManager>(obj);
00100     assert(catmgr);
00101 
00102     entry = moduleinfo->categories;
00103     while(entry->category != UUID_null && entry->uuid != UUID_null) {
00104       catmgr->registerComponent(entry->category, entry->uuid, entry->string);
00105 
00106       ++entry;
00107     }
00108 
00109     catmgr->release();
00110   }
00111 }
00112 
00113 IObject* Module::getObject(const UUID& cid) {
00114   const XPLC_ComponentEntry* entry = moduleinfo->components;
00115   IObject* obj = 0;
00116 
00117   if(!entry)
00118     return NULL;
00119 
00120   while(!obj && entry->uuid != UUID_null) {
00121     if(entry->uuid == cid)
00122       obj = entry->getObject();
00123 
00124     ++entry;
00125   }
00126 
00127   return obj;
00128 }
00129 
00130 Module::~Module() {
00131   /*
00132    * FIXME: Adding the conditional here is for future expansion, where
00133    * this class could be used for a non-dynamically loaded module. But
00134    * for some reason, the size of this file increases in an odd way
00135    * when it is added. This should be investigated.
00136    */
00137   if(handle)
00138     loaderClose(handle);
00139 }
00140