WvStreams
moduleloader.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  * Copyright (C) 2002-2004, Stéphane Lajoie
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21  * USA
22  */
23 
24 #include <assert.h>
25 #include <xplc/ICategoryManager.h>
26 #include <xplc/uuidops.h>
27 #include "moduleloader.h"
28 #include "loader.h"
29 
34 
40 
41 IModule* ModuleLoader::loadModule(const char* modulename) {
42  return Module::loadModule(modulename);
43 }
44 
45 Module* Module::loadModule(const char* modulename) {
46  XPLC_ModuleInfo* moduleinfo = 0;
47  void* dlh;
48  const char* err;
49 
50  err = loaderOpen(modulename, &dlh);
51  if(err)
52  return NULL;
53 
54  void* symbol;
55  err = loaderSymbol(dlh, "XPLC_Module", &symbol);
56  moduleinfo = reinterpret_cast<XPLC_ModuleInfo*>(symbol);
57 
58  if(err
59  || !moduleinfo
60  || moduleinfo->magic != XPLC_MODULE_MAGIC) {
61  loaderClose(dlh);
62  return NULL;
63  }
64 
65  switch(moduleinfo->version_major) {
66 #ifdef UNSTABLE
67  case -1u:
68  /* nothing to do */
69  break;
70 #endif
71  default:
72  loaderClose(dlh);
73  return NULL;
74  };
75 
76  return new Module(dlh, moduleinfo);
77 }
78 
79 Module::Module(void* aHandle, const XPLC_ModuleInfo* aModuleInfo):
80  handle(aHandle),
81  moduleinfo(aModuleInfo)
82 {
83  assert(moduleinfo);
84 
85  if(moduleinfo->categories) {
86  IServiceManager* servmgr;
87  IObject* obj;
88  ICategoryManager* catmgr;
89  const XPLC_CategoryEntry* entry;
90 
91  servmgr = XPLC_getServiceManager();
92  assert(servmgr);
93 
94  obj = servmgr->getObject(XPLC_categoryManager);
95  assert(obj);
96 
97  servmgr->release();
98 
99  catmgr = mutate<ICategoryManager>(obj);
100  assert(catmgr);
101 
102  entry = moduleinfo->categories;
103  while(entry->category != UUID_null && entry->uuid != UUID_null) {
104  catmgr->registerComponent(entry->category, entry->uuid, entry->string);
105 
106  ++entry;
107  }
108 
109  catmgr->release();
110  }
111 }
112 
114  const XPLC_ComponentEntry* entry = moduleinfo->components;
115  IObject* obj = 0;
116 
117  if(!entry)
118  return NULL;
119 
120  while(!obj && entry->uuid != UUID_null) {
121  if(entry->uuid == cid)
122  obj = entry->getObject();
123 
124  ++entry;
125  }
126 
127  return obj;
128 }
129 
130 Module::~Module() {
131  /*
132  * FIXME: Adding the conditional here is for future expansion, where
133  * this class could be used for a non-dynamically loaded module. But
134  * for some reason, the size of this file increases in an odd way
135  * when it is added. This should be investigated.
136  */
137  if(handle)
138  loaderClose(handle);
139 }
140 
XPLC_ModuleInfo::categories
const XPLC_CategoryEntry *const categories
List of category registrations for the module.
Definition: module.h:132
IServiceManager
Definition: IServiceManager.h:58
XPLC_ModuleInfo
Information for an XPLC module.
Definition: module.h:98
IServiceHandler::getObject
virtual IObject * getObject(const UUID &)=0
Get the object corresponding to the given UUID.
XPLC_CategoryEntry
Entry for a category registration.
Definition: module.h:87
XPLC_ComponentEntry
Entry for a component.
Definition: module.h:76
UUID_MAP_ENTRY
#define UUID_MAP_ENTRY(iface)
Add an entry to an interface map.
Definition: utils.h:68
UUID_MAP_BEGIN
#define UUID_MAP_BEGIN(component)
Start the interface map for "component".
Definition: utils.h:63
ICategoryManager
Definition: ICategoryManager.h:37
XPLC_MODULE_MAGIC
#define XPLC_MODULE_MAGIC
XPLC module magic number.
Definition: module.h:47
IServiceHandler
Definition: IServiceHandler.h:43
XPLC_ModuleInfo::magic
unsigned long magic
XPLC module magic number.
Definition: module.h:103
IModuleLoader
Definition: IModuleLoader.h:37
XPLC_ModuleInfo::version_major
unsigned int version_major
The XPLC module ABI version that this module conforms to.
Definition: module.h:109
IObject::release
virtual unsigned int release()=0
Indicate that you are finished using this object.
Module
Definition: moduleloader.h:37
UUID_MAP_END
#define UUID_MAP_END
Marks the end of an interface map.
Definition: utils.h:80
IObject
Definition: IObject.h:65
Module::getObject
virtual IObject * getObject(const UUID &cid)
Get the object corresponding to the given UUID.
Definition: moduleloader.cc:113
_GUID
The structure underlying UUIDs.
Definition: uuid.h:94
XPLC_ModuleInfo::components
const XPLC_ComponentEntry *const components
List of components supported by the module.
Definition: module.h:127
ICategoryManager::registerComponent
virtual void registerComponent(const UUID &category, const UUID &component, const char *extrastring)=0
Register a component with a category.
ModuleLoader
Definition: moduleloader.h:30
IModule
Definition: IModule.h:37