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 #if defined(SOLARIS) || defined(MACOS) 00083 #define PATH_MAX 4096 00084 #endif 00085 00086 IServiceHandler* ModuleManagerFactory::createModuleManager(const char* directory) { 00087 #if !defined(WIN32) 00088 DIR* dir; 00089 struct dirent* ent; 00090 char fname[PATH_MAX]; 00091 IServiceManager* servmgr = XPLC_getServiceManager(); 00092 IModuleLoader* loader; 00093 ModuleNode* modules = 0; 00094 00095 if(!servmgr) 00096 return 0; 00097 00098 loader = mutate<IModuleLoader>(servmgr->getObject(XPLC_moduleLoader)); 00099 servmgr->release(); 00100 if(!loader) 00101 return 0; 00102 00103 dir = opendir(directory); 00104 if(!dir) { 00105 loader->release(); 00106 return 0; 00107 } 00108 00109 rewinddir(dir); 00110 while((ent = readdir(dir))) { 00111 IModule* module; 00112 00113 snprintf(fname, PATH_MAX, "%s/%s", directory, ent->d_name); 00114 00115 module = loader->loadModule(fname); 00116 if(module) { 00117 ModuleNode* node = new ModuleNode(module, modules); 00118 00119 if(node) 00120 modules = node; 00121 } 00122 } 00123 00124 loader->release(); 00125 00126 closedir(dir); 00127 00128 return new ModuleManager(modules); 00129 00130 #else 00131 00132 intptr_t dir; 00133 _finddata_t ent; 00134 char fname[4096]; 00135 char pattern[4096]; 00136 IServiceManager* servmgr = XPLC_getServiceManager(); 00137 IModuleLoader* loader; 00138 ModuleNode* modules = 0; 00139 00140 if(!servmgr) 00141 return 0; 00142 00143 loader = mutate<IModuleLoader>(servmgr->getObject(XPLC_moduleLoader)); 00144 servmgr->release(); 00145 if(!loader) 00146 return 0; 00147 00148 snprintf(pattern, sizeof(pattern), "%s/*.*", directory); 00149 00150 dir = _findfirst(pattern, &ent); 00151 00152 if(!dir) { 00153 loader->release(); 00154 return 0; 00155 } 00156 00157 do { 00158 IModule* module; 00159 00160 _snprintf(fname, sizeof(fname), "%s/%s", directory, ent.name); 00161 00162 module = loader->loadModule(fname); 00163 if(module) { 00164 ModuleNode* node = new ModuleNode(module, modules); 00165 00166 if(node) 00167 modules = node; 00168 } 00169 } while(_findnext(dir, &ent) == 0); 00170 00171 loader->release(); 00172 00173 _findclose(dir); 00174 00175 return new ModuleManager(modules); 00176 #endif 00177 } 00178 00179 ModuleManager::ModuleManager(ModuleNode* aModules): 00180 modules(aModules) { 00181 } 00182 00183 IObject* ModuleManager::getObject(const UUID& cid) { 00184 ModuleNode* node = modules; 00185 00186 while(node) { 00187 IObject* obj = node->module->getObject(cid); 00188 00189 if(obj) 00190 return obj; 00191 00192 node = node->next; 00193 } 00194 00195 return 0; 00196 } 00197 00198 ModuleManager::~ModuleManager() { 00199 ModuleNode* node = modules; 00200 00201 while(node) { 00202 ModuleNode* next = node->next; 00203 00204 delete node; 00205 00206 node = next; 00207 } 00208 } 00209