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 | |
45 | class ModuleLoader |
46 | { |
47 | public: |
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 | |