WvStreams
|
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 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, but 00013 * WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00020 * USA 00021 */ 00022 00023 #include <assert.h> 00024 #include "modulemgr.h" 00025 #include <xplc/IModuleLoader.h> 00026 00027 #include "config.h" 00028 00029 #ifdef HAVE_STDINT_H 00030 # include <stdint.h> 00031 #endif 00032 #ifdef HAVE_LIMITS_H 00033 # include <limits.h> 00034 #endif 00035 00036 #if !defined(WIN32) 00037 # if HAVE_DIRENT_H 00038 # include <dirent.h> 00039 # define NAMLEN(dirent) strlen((dirent)->d_name) 00040 # else 00041 # define dirent direct 00042 # define NAMLEN(dirent) (dirent)->d_namlen 00043 # if HAVE_SYS_NDIR_H 00044 # include <sys/ndir.h> 00045 # endif 00046 # if HAVE_SYS_DIR_H 00047 # include <sys/dir.h> 00048 # endif 00049 # if HAVE_NDIR_H 00050 # include <ndir.h> 00051 # endif 00052 # endif 00053 #else 00054 # include <io.h> 00055 #endif 00056 00057 #include <stdio.h> 00058 00059 UUID_MAP_BEGIN(ModuleManagerFactory) 00060 UUID_MAP_ENTRY(IObject) 00061 UUID_MAP_ENTRY(IModuleManagerFactory) 00062 UUID_MAP_END 00063 00064 UUID_MAP_BEGIN(ModuleManager) 00065 UUID_MAP_ENTRY(IObject) 00066 UUID_MAP_ENTRY(IServiceHandler) 00067 UUID_MAP_END 00068 00069 struct ModuleNode { 00070 ModuleNode* next; 00071 IModule* module; 00072 ModuleNode(IModule* aModule, ModuleNode* aNext): 00073 next(aNext), module(aModule) { 00074 assert(module); 00075 } 00076 ~ModuleNode() { 00077 if(module) 00078 module->release(); 00079 } 00080 }; 00081 00082 IServiceHandler* ModuleManagerFactory::createModuleManager(const char* directory) { 00083 #if !defined(WIN32) 00084 DIR* dir; 00085 struct dirent* ent; 00086 char fname[PATH_MAX]; 00087 IServiceManager* servmgr = XPLC_getServiceManager(); 00088 IModuleLoader* loader; 00089 ModuleNode* modules = 0; 00090 00091 if(!servmgr) 00092 return 0; 00093 00094 loader = mutate<IModuleLoader>(servmgr->getObject(XPLC_moduleLoader)); 00095 servmgr->release(); 00096 if(!loader) 00097 return 0; 00098 00099 dir = opendir(directory); 00100 if(!dir) { 00101 loader->release(); 00102 return 0; 00103 } 00104 00105 rewinddir(dir); 00106 while((ent = readdir(dir))) { 00107 IModule* module; 00108 00109 snprintf(fname, PATH_MAX, "%s/%s", directory, ent->d_name); 00110 00111 module = loader->loadModule(fname); 00112 if(module) { 00113 ModuleNode* node = new ModuleNode(module, modules); 00114 00115 if(node) 00116 modules = node; 00117 } 00118 } 00119 00120 loader->release(); 00121 00122 closedir(dir); 00123 00124 return new ModuleManager(modules); 00125 00126 #else 00127 00128 intptr_t dir; 00129 _finddata_t ent; 00130 char fname[4096]; 00131 char pattern[4096]; 00132 IServiceManager* servmgr = XPLC_getServiceManager(); 00133 IModuleLoader* loader; 00134 ModuleNode* modules = 0; 00135 00136 if(!servmgr) 00137 return 0; 00138 00139 loader = mutate<IModuleLoader>(servmgr->getObject(XPLC_moduleLoader)); 00140 servmgr->release(); 00141 if(!loader) 00142 return 0; 00143 00144 snprintf(pattern, sizeof(pattern), "%s/*.*", directory); 00145 00146 dir = _findfirst(pattern, &ent); 00147 00148 if(!dir) { 00149 loader->release(); 00150 return 0; 00151 } 00152 00153 do { 00154 IModule* module; 00155 00156 _snprintf(fname, sizeof(fname), "%s/%s", directory, ent.name); 00157 00158 module = loader->loadModule(fname); 00159 if(module) { 00160 ModuleNode* node = new ModuleNode(module, modules); 00161 00162 if(node) 00163 modules = node; 00164 } 00165 } while(_findnext(dir, &ent) == 0); 00166 00167 loader->release(); 00168 00169 _findclose(dir); 00170 00171 return new ModuleManager(modules); 00172 #endif 00173 } 00174 00175 ModuleManager::ModuleManager(ModuleNode* aModules): 00176 modules(aModules) { 00177 } 00178 00179 IObject* ModuleManager::getObject(const UUID& cid) { 00180 ModuleNode* node = modules; 00181 00182 while(node) { 00183 IObject* obj = node->module->getObject(cid); 00184 00185 if(obj) 00186 return obj; 00187 00188 node = node->next; 00189 } 00190 00191 return 0; 00192 } 00193 00194 ModuleManager::~ModuleManager() { 00195 ModuleNode* node = modules; 00196 00197 while(node) { 00198 ModuleNode* next = node->next; 00199 00200 delete node; 00201 00202 node = next; 00203 } 00204 } 00205