NCBI C++ ToolKit
plugin_manager.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: plugin_manager.cpp 83621 2018-09-05 17:25:51Z ivanov $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Anatoliy Kuznetsov
27  *
28  * File Description:
29  * Plugin manager implementations
30  *
31  * ===========================================================================
32  */
33 
34 #include <ncbi_pch.hpp>
36 #include <corelib/ncbidll.hpp>
37 
39 
40 /////////////////////////////////////////////////////////////////////////////
41 // CPluginManager_DllResolver::
42 //
43 
45  : m_DllNamePrefix("ncbi_plugin"),
46  m_EntryPointPrefix("NCBI_EntryPoint"),
47  m_Version(CVersionInfo::kAny),
48  m_DllResolver(0)
49 {}
50 
51 
53  const string& interface_name,
54  const string& driver_name,
55  const CVersionInfo& version,
56  CDll::EAutoUnload unload_dll)
57  : m_DllNamePrefix("ncbi_plugin"),
58  m_EntryPointPrefix("NCBI_EntryPoint"),
59  m_InterfaceName(interface_name),
60  m_DriverName(driver_name),
61  m_Version(version),
62  m_DllResolver(0),
63  m_AutoUnloadDll(unload_dll)
64 {}
65 
66 
68 {
69  delete m_DllResolver;
70 }
71 
74  const string& driver_name,
75  const CVersionInfo& version,
77 {
78  CDllResolver* resolver = GetCreateDllResolver();
79  _ASSERT(resolver);
80 
81  const string& drv = driver_name.empty() ? m_DriverName : driver_name;
82  const CVersionInfo& ver = version.IsAny() ? m_Version : version;
83 
84  // Generate DLL masks
85 
86  // Ignore version to find dlls having no version in their names
87  vector<string> masks;
88  string mask = GetDllNameMask(m_InterfaceName, drv, ver);
89  masks.push_back(mask);
90 
91  if ( version == CVersionInfo::kAny ) {
93  masks.push_back(mask);
94 #if defined(NCBI_OS_UNIX)
96  masks.push_back(mask);
97 #endif
98  }
99  resolver->FindCandidates(paths, masks, std_path, drv);
100  return *resolver;
101 }
102 
104 {
105  _ASSERT(!path.empty());
106  vector<string> paths;
107  paths.push_back(path);
108  return ResolveFile(paths);
109 }
110 
111 
112 string
113 CPluginManager_DllResolver::GetDllName(const string& interface_name,
114  const string& driver_name,
115  const CVersionInfo& version) const
116 {
117  string name = GetDllNamePrefix();
118 
119  if (!interface_name.empty()) {
120  name.append("_");
121  name.append(interface_name);
122  }
123  if (!driver_name.empty()) {
124  name.append("_");
125  name.append(driver_name);
126  }
127 
128  if (version.IsAny()) {
129  return name;
130  } else {
131 
132 #if defined(NCBI_OS_MSWIN)
133  string delimiter = "_";
134 #elif defined(NCBI_OS_UNIX)
135  string delimiter = ".";
136  name.append(NCBI_PLUGIN_SUFFIX);
137 #endif
138  name.append(delimiter);
139  name.append(NStr::IntToString(version.GetMajor()));
140  name.append(delimiter);
141  name.append(NStr::IntToString(version.GetMinor()));
142  name.append(delimiter);
143  name.append(NStr::IntToString(version.GetPatchLevel()));
144  }
145  return name;
146 }
147 
148 string
150  const string& interface_name,
151  const string& driver_name,
152  const CVersionInfo& version,
153  EVersionLocation ver_lct) const
154 {
155  string name = GetDllNamePrefix();
156 
157  if ( !name.empty() ) {
158  name.append("_");
159  }
160  if (interface_name.empty()) {
161  name.append("*");
162  } else {
163  name.append(interface_name);
164  }
165  name.append("_");
166 
167  if (driver_name.empty()) {
168  name.append("*");
169  } else {
170  name.append(driver_name);
171  }
172  if (version.IsAny()) {
173  name.append(NCBI_PLUGIN_SUFFIX);
174  } else {
175 
176  string delimiter;
177 
178 #if defined(NCBI_OS_MSWIN)
179  delimiter = "_";
180 #elif defined(NCBI_OS_UNIX)
181  if ( ver_lct != eAfterSuffix ) {
182  delimiter = "_";
183  } else {
184  delimiter = ".";
185  }
186 #endif
187 
188  if ( ver_lct == eAfterSuffix ) {
189  name.append(NCBI_PLUGIN_SUFFIX);
190  }
191  name.append(delimiter);
192  if (version.GetMajor() <= 0) {
193  name.append("*");
194  } else {
195  name.append(NStr::IntToString(version.GetMajor()));
196  }
197  name.append(delimiter);
198 
199  if (version.GetMinor() <= 0) {
200  name.append("*");
201  } else {
202  name.append(NStr::IntToString(version.GetMinor()));
203  }
204  name.append(delimiter);
205  name.append("*"); // always get the best patch level
206 
207  if ( ver_lct != eAfterSuffix ) {
208  name.append(NCBI_PLUGIN_SUFFIX);
209  }
210  }
211 
212  return name;
213 }
214 
215 string
217  const string& interface_name,
218  const string& driver_name) const
219 {
220  string name = GetEntryPointPrefix();
221 
222  if (!interface_name.empty()) {
223  name.append("_");
224  name.append(interface_name);
225  }
226  if (!driver_name.empty()) {
227  name.append("_");
228  name.append(driver_name);
229  }
230  return name;
231 }
232 
233 
235 {
236  return m_EntryPointPrefix;
237 }
238 
239 
241 {
243 }
244 
245 
247 {
248  m_DllNamePrefix = prefix;
249 }
250 
251 
253 {
254  vector<string> entry_point_names;
255  string entry_name;
256 
257  // Generate all variants of entry point names
258  // some of them can duplicate, and that's legal. Resolver stops trying
259  // after the first success.
260 
261  entry_name = GetEntryPointName(m_InterfaceName, "${driver}");
262  entry_point_names.push_back(entry_name);
263 
264  entry_name = GetEntryPointName(kEmptyStr, kEmptyStr);
265  entry_point_names.push_back(entry_name);
266 
268  entry_point_names.push_back(entry_name);
269 
270  entry_name = GetEntryPointName(kEmptyStr, "${driver}");
271  entry_point_names.push_back(entry_name);
272 
273  // Make the library dependent entry point templates
274  string base_name_templ = "${basename}";
275  string prefix = GetEntryPointPrefix();
276 
277  // Make "NCBI_EntryPoint_libname" EP name
278  entry_name = prefix;
279  entry_name.append("_");
280  entry_name.append(base_name_templ);
281  entry_point_names.push_back(entry_name);
282 
283  // Make "NCBI_EntryPoint_interface_libname" EP name
284  if (!m_InterfaceName.empty()) {
285  entry_name = prefix;
286  entry_name.append("_");
287  entry_name.append(m_InterfaceName);
288  entry_name.append("_");
289  entry_name.append(base_name_templ);
290  entry_point_names.push_back(entry_name);
291  }
292 
293  // Make "NCBI_EntryPoint_driver_libname" EP name
294  if (!m_DriverName.empty()) {
295  entry_name = prefix;
296  entry_name.append("_");
297  entry_name.append(m_DriverName);
298  entry_name.append("_");
299  entry_name.append(base_name_templ);
300  entry_point_names.push_back(entry_name);
301  }
302 
303  CDllResolver* resolver = new CDllResolver(entry_point_names, m_AutoUnloadDll);
304  return resolver;
305  }
306 
308 {
309  if (m_DllResolver == 0) {
311  }
312  return m_DllResolver;
313 }
314 
315 
316 #if defined(NCBI_PLUGIN_AUTO_LOAD) || defined(NCBI_DLL_BUILD)
317 # define LOAD_PLUGINS_FROM_DLLS_BY_DEFAULT true
318 #else
319 # define LOAD_PLUGINS_FROM_DLLS_BY_DEFAULT false
320 #endif
321 NCBI_PARAM_DECL(bool, NCBI, Load_Plugins_From_DLLs);
322 NCBI_PARAM_DEF_EX(bool, NCBI, Load_Plugins_From_DLLs,
324  eParam_NoThread, NCBI_LOAD_PLUGINS_FROM_DLLS);
325 typedef NCBI_PARAM_TYPE(NCBI, Load_Plugins_From_DLLs) TLoadPluginsFromDLLsParam;
326 
327 
329 {
330  return TLoadPluginsFromDLLsParam::GetDefault();
331 }
332 
334 {
336 }
337 
339 {
340  TLoadPluginsFromDLLsParam::SetDefault(enable);
341 }
342 
344 {
345  switch (GetErrCode()) {
346  case eResolveFailure: return "eResolveFailure";
347  case eParameterMissing: return "eParameterMissing";
348  default: return CException::GetErrCodeString();
349  }
350 }
351 
352 
ncbi::TMaskedQueryRegions mask
Class for entry point resolution when there are several DLL candidates.
Definition: ncbidll.hpp:373
CVersionInfo –.
int TExtraDllPath
Definition: ncbidll.hpp:473
EAutoUnload
Whether to unload DLL in the destructor.
Definition: ncbidll.hpp:143
#define NCBI_PLUGIN_SUFFIX
Definition: ncbidll.hpp:67
#define NCBI_PLUGIN_PREFIX
Definition: ncbidll.hpp:57
void FindCandidates(const TClass1 &paths, const TClass2 &masks, TExtraDllPath extra_path=fDefaultDllPath, const string &driver_name=kEmptyStr)
Try to resolve all files matching the specified masks in the specified directories.
Definition: ncbidll.hpp:487
TErrCode GetErrCode(void) const
Definition: ncbiexpt.hpp:1493
virtual const char * GetErrCodeString(void) const
Get error code interpreted as text.
Definition: ncbiexpt.cpp:444
@ eParam_NoThread
Do not use per-thread values.
Definition: ncbi_param.hpp:418
CDllResolver * GetCreateDllResolver()
static bool IsEnabledGlobally()
Return whether to allow loading plugins from DLLs in general.
virtual void SetDllNamePrefix(const string &prefix)
Set DLL file name prefix.
vector< string > TSearchPaths
Container for the DLL search paths.
virtual const char * GetErrCodeString(void) const override
Translate from the error code value to its string representation.
CDllResolver * CreateDllResolver() const
CDll::EAutoUnload m_AutoUnloadDll
CDllResolver & ResolveFile(const TSearchPaths &paths, const string &driver_name=kEmptyStr, const CVersionInfo &version=CVersionInfo::kAny, CDllResolver::TExtraDllPath std_path=CDllResolver::fDefaultDllPath)
Search for plugin DLLs, resolve entry points.
virtual string GetEntryPointPrefix() const
Return DLL entry point prefix ("NCBI_EntryPoint")
static bool IsEnabledGloballyByDefault()
Return whether to allow loading plugins from DLLs in general by default.
virtual ~CPluginManager_DllResolver(void)
CDllResolver & Resolve(const string &path)
Search for plugin DLLs, resolve entry points.
virtual string GetDllNamePrefix() const
Return DLL file name prefix ("ncbi_plugin")
static void EnableGlobally(bool enable=true)
Enable (or disable, if called with enable = false) loading plugins from DLLs in general.
virtual string GetDllNameMask(const string &interface_name, const string &driver_name=kEmptyStr, const CVersionInfo &version=CVersionInfo::kAny, EVersionLocation ver_lct=eBeforeSuffix) const
Return DLL name mask.
virtual string GetEntryPointName(const string &interface_name=kEmptyStr, const string &driver_name=kEmptyStr) const
Return DLL entry point name:
virtual string GetDllName(const string &interface_name, const string &driver_name=kEmptyStr, const CVersionInfo &version=CVersionInfo::kAny) const
Return dll file name.
@ eResolveFailure
Cannot resolve interface driver.
@ eParameterMissing
Missing mandatory parameter.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define kEmptyStr
Definition: ncbistr.hpp:123
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5078
const string version
version string
Definition: variables.hpp:66
Define class Dll and for Portable DLL handling.
NCBI_PARAM_DEF_EX(bool, NCBI, Load_Plugins_From_DLLs, false, eParam_NoThread, NCBI_LOAD_PLUGINS_FROM_DLLS)
NCBI_PARAM_DECL(bool, NCBI, Load_Plugins_From_DLLs)
typedef NCBI_PARAM_TYPE(NCBI, Load_Plugins_From_DLLs) TLoadPluginsFromDLLsParam
#define LOAD_PLUGINS_FROM_DLLS_BY_DEFAULT
Plugin manager (using class factory paradigm).
static const char delimiter[]
NCBI
Definition: static_set.hpp:72
#define _ASSERT
Modified on Fri Sep 20 14:58:24 2024 by modify_doxy.py rev. 669887