WvStreams
modulemgr.cc
1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 *
3 * XPLC - Cross-Platform Lightweight Components
4 * Copyright (C) 2002-2004, Net Integration Technologies, Inc.
5 * Copyright (C) 2002-2004, Pierre Phaneuf
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 */
22
23#include <assert.h>
24#include "modulemgr.h"
25#include <xplc/IModuleLoader.h>
26
27#include "config.h"
28
29#ifdef HAVE_STDINT_H
30# include <stdint.h>
31#endif
32#ifdef HAVE_LIMITS_H
33# include <limits.h>
34#endif
35
36#if !defined(WIN32)
37# if HAVE_DIRENT_H
38# include <dirent.h>
39# define NAMLEN(dirent) strlen((dirent)->d_name)
40# else
41# define dirent direct
42# define NAMLEN(dirent) (dirent)->d_namlen
43# if HAVE_SYS_NDIR_H
44# include <sys/ndir.h>
45# endif
46# if HAVE_SYS_DIR_H
47# include <sys/dir.h>
48# endif
49# if HAVE_NDIR_H
50# include <ndir.h>
51# endif
52# endif
53#else
54# include <io.h>
55#endif
56
57#include <stdio.h>
58
63
68
69struct ModuleNode {
70 ModuleNode* next;
71 IModule* module;
72 ModuleNode(IModule* aModule, ModuleNode* aNext):
73 next(aNext), module(aModule) {
74 assert(module);
75 }
76 ~ModuleNode() {
77 if(module)
78 module->release();
79 }
80};
81
82#if defined(SOLARIS) || defined(MACOS)
83#define PATH_MAX 4096
84#endif
85
86IServiceHandler* ModuleManagerFactory::createModuleManager(const char* directory) {
87#if !defined(WIN32)
88 DIR* dir;
89 struct dirent* ent;
90 char fname[PATH_MAX];
91 IServiceManager* servmgr = XPLC_getServiceManager();
92 IModuleLoader* loader;
93 ModuleNode* modules = 0;
94
95 if(!servmgr)
96 return 0;
97
98 loader = mutate<IModuleLoader>(servmgr->getObject(XPLC_moduleLoader));
99 servmgr->release();
100 if(!loader)
101 return 0;
102
103 dir = opendir(directory);
104 if(!dir) {
105 loader->release();
106 return 0;
107 }
108
109 rewinddir(dir);
110 while((ent = readdir(dir))) {
111 IModule* module;
112
113 snprintf(fname, PATH_MAX, "%s/%s", directory, ent->d_name);
114
115 module = loader->loadModule(fname);
116 if(module) {
117 ModuleNode* node = new ModuleNode(module, modules);
118
119 if(node)
120 modules = node;
121 }
122 }
123
124 loader->release();
125
126 closedir(dir);
127
128 return new ModuleManager(modules);
129
130#else
131
132 intptr_t dir;
133 _finddata_t ent;
134 char fname[4096];
135 char pattern[4096];
136 IServiceManager* servmgr = XPLC_getServiceManager();
137 IModuleLoader* loader;
138 ModuleNode* modules = 0;
139
140 if(!servmgr)
141 return 0;
142
143 loader = mutate<IModuleLoader>(servmgr->getObject(XPLC_moduleLoader));
144 servmgr->release();
145 if(!loader)
146 return 0;
147
148 snprintf(pattern, sizeof(pattern), "%s/*.*", directory);
149
150 dir = _findfirst(pattern, &ent);
151
152 if(!dir) {
153 loader->release();
154 return 0;
155 }
156
157 do {
158 IModule* module;
159
160 _snprintf(fname, sizeof(fname), "%s/%s", directory, ent.name);
161
162 module = loader->loadModule(fname);
163 if(module) {
164 ModuleNode* node = new ModuleNode(module, modules);
165
166 if(node)
167 modules = node;
168 }
169 } while(_findnext(dir, &ent) == 0);
170
171 loader->release();
172
173 _findclose(dir);
174
175 return new ModuleManager(modules);
176#endif
177}
178
179ModuleManager::ModuleManager(ModuleNode* aModules):
180 modules(aModules) {
181}
182
184 ModuleNode* node = modules;
185
186 while(node) {
187 IObject* obj = node->module->getObject(cid);
188
189 if(obj)
190 return obj;
191
192 node = node->next;
193 }
194
195 return 0;
196}
197
198ModuleManager::~ModuleManager() {
199 ModuleNode* node = modules;
200
201 while(node) {
202 ModuleNode* next = node->next;
203
204 delete node;
205
206 node = next;
207 }
208}
209
The interface to control the module loader.
Definition: IModuleLoader.h:37
The interface that a module should provide.
Definition: IModule.h:37
The basic interface which is included by all other XPLC interfaces and objects.
Definition: IObject.h:65
virtual unsigned int release()=0
Indicate that you are finished using this object.
Interface to an object which can be used to find other objects, given their UUIDs.
virtual IObject * getObject(const UUID &)=0
Get the object corresponding to the given UUID.
The XPLC service manager interface.
virtual IObject * getObject(const UUID &cid)
Get the object corresponding to the given UUID.
Definition: modulemgr.cc:183
The structure underlying UUIDs.
Definition: uuid.h:94
#define UUID_MAP_END
Marks the end of an interface map.
Definition: utils.h:80
#define UUID_MAP_BEGIN(component)
Start the interface map for "component".
Definition: utils.h:63
#define UUID_MAP_ENTRY(iface)
Add an entry to an interface map.
Definition: utils.h:68