00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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