1/*
2 * PROGRAM: JRD Module Loader
3 * MODULE: mod_loader.h
4 * DESCRIPTION: Abstract class for loadable modules.
5 *
6 * The contents of this file are subject to the Initial
7 * Developer's Public License Version 1.0 (the "License");
8 * you may not use this file except in compliance with the
9 * License. You may obtain a copy of the License at
10 * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
11 *
12 * Software distributed under the License is distributed AS IS,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied.
14 * See the License for the specific language governing rights
15 * and limitations under the License.
16 *
17 * The Original Code was created by John Bellardo
18 * for the Firebird Open Source RDBMS project.
19 *
20 * Copyright (c) 2002 John Bellardo <bellardo at cs.ucsd.edu>
21 * and all contributors signed below.
22 *
23 * All Rights Reserved.
24 * Contributor(s): ______________________________________.
25 *
26 */
27
28#ifndef JRD_OS_MOD_LOADER_H
29#define JRD_OS_MOD_LOADER_H
30
31#include "../common/classes/fb_string.h"
32
33/***
34 The ModuleLoader class is an abstraction of the dynamic code loading
35 facilities provided by the host operating system. The class provides
36 functions to determine if the file at a given path is a loadable module,
37 to load that module, and to modify the filename in a way that is
38 appropiate to the host computer.
39
40 All implementations of this interface are expected to provide definitions
41 for the 3 static functions in the ModuleLoader class, and provide a
42 subclass of ModuleLoader::Loader that implements findSymbol.
43***/
44
45class ModuleLoader
46{
47public:
48 /** ModuleLoader::Module is the abstract base class for all disk
49 based loadable modules after they are loaded into memory.
50 It provides a method to locate a pointer for a given symbol,
51 and automatically unloads the module from memory when the
52 object is destructed. Instances of this class are created
53 using the ModuleLoader::loadModule function.
54 **/
55 class Module
56 {
57 public:
58 /** findSymbol searchs through the module after it has been loaded into
59 memory, and returns a pointer to that symbol's location in memory.
60 If the symbol can't be found or doesn't exist the function returns
61 NULL.
62 **/
63 virtual void* findSymbol(const Firebird::string&) = 0;
64
65 template <typename T> T& findSymbol(const Firebird::string& symbol, T& ptr)
66 {
67 return (ptr = (T)(findSymbol(symbol)));
68 }
69
70 /// Destructor
71 virtual ~Module() {}
72 protected:
73 /// The constructor is protected so normal code can't allocate instances
74 /// of the class, but the class itself is still able to be subclassed.
75 Module() {}
76 private:
77 /// Copy construction is not supported, hence the copy constructor is private
78 Module(const Module&); // no impl
79 /// assignment of Modules isn't supported so the assignment operator is private
80 const Module& operator=(const Module&); // no impl
81 };
82
83 /** loadModule is given as a string the path to the module to load. It
84 attempts to load the module. If successful it returns the ModuleLoader::Module
85 object that represents the loaded module in memory and can be used to
86 perform symbol lookups on the module. If unsuccessful it returns NULL.
87 It is the callers responsibility to delete the returned module object
88 when it is no longer needed.
89 **/
90 static Module* loadModule(const Firebird::PathName&);
91
92 /** doctorModuleExtension modifies the given path name to add the platform
93 specific module extention. This allows the user to provide the root name
94 of the file, and the code to append the correct extention regardless of the
95 host operating system. This function is typically called after a failed attempt
96 to load the module without the extention.
97 **/
98 static void doctorModuleExtension(Firebird::PathName&);
99
100 /** Almost like loadModule(), but in case of failure invokes doctorModuleExtension()
101 and retries.
102 **/
103 static Module* fixAndLoadModule(const Firebird::PathName& modName)
104 {
105 Module* mod = loadModule(modName);
106 if (!mod)
107 {
108 Firebird::PathName fixed(modName);
109 doctorModuleExtension(fixed);
110 mod = loadModule(fixed);
111 }
112 return mod;
113 }
114
115 /** isLoadableModule checks the given file to see if it is a loadable
116 module. This function is required because different operating
117 systems require different checks.
118 **/
119 static bool isLoadableModule(const Firebird::PathName&);
120};
121
122#endif // JRD_OS_MOD_LOADER_H
123
124