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 
69 struct 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 
86 IServiceHandler* 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 
179 ModuleManager::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 
198 ModuleManager::~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 
IServiceManager
Definition: IServiceManager.h:58
IServiceHandler::getObject
virtual IObject * getObject(const UUID &)=0
Get the object corresponding to the given UUID.
ModuleManager::getObject
virtual IObject * getObject(const UUID &cid)
Get the object corresponding to the given UUID.
Definition: modulemgr.cc:183
UUID_MAP_ENTRY
#define UUID_MAP_ENTRY(iface)
Add an entry to an interface map.
Definition: utils.h:68
ModuleManager
Definition: modulemgr.h:42
UUID_MAP_BEGIN
#define UUID_MAP_BEGIN(component)
Start the interface map for "component".
Definition: utils.h:63
IServiceHandler
Definition: IServiceHandler.h:43
IModuleLoader
Definition: IModuleLoader.h:37
ModuleNode
Definition: modulemgr.cc:69
IObject::release
virtual unsigned int release()=0
Indicate that you are finished using this object.
UUID_MAP_END
#define UUID_MAP_END
Marks the end of an interface map.
Definition: utils.h:80
IObject
Definition: IObject.h:65
IModuleManagerFactory
Definition: IModuleManagerFactory.h:31
_GUID
The structure underlying UUIDs.
Definition: uuid.h:94
ModuleManagerFactory
Definition: modulemgr.h:29
IModule
Definition: IModule.h:37