Loading...
Searching...
No Matches
DllPluginLoader_impl.h
Go to the documentation of this file.
/*
* Robot Testing Framework
*
* Copyright (C) 2015-2019 Istituto Italiano di Tecnologia (IIT)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ROBOTTESTINGFRAMEWORK_DLLPLUGINLOADERIMPL_H
#define ROBOTTESTINGFRAMEWORK_DLLPLUGINLOADERIMPL_H
#include <robottestingframework/dll/Plugin.h>
#include <robottestingframework/dll/SharedLibrary.h>
#include <robottestingframework/dll/SharedLibraryClass.h>
#include <string>
template <class T>
class DllPluginLoaderImpl
{
class Plugin
{
public:
shlibpp::SharedLibraryClassFactory<T> factory;
shlibpp::SharedLibraryClass<T> test;
};
public:
DllPluginLoaderImpl() :
plugin(nullptr)
{
}
virtual ~DllPluginLoaderImpl()
{
close();
}
T* open(const std::string filename,
const std::string factory_name)
{
// close any previous loaded plugin
close();
// create an instance of plugin class and factory
plugin = new DllPluginLoaderImpl::Plugin;
// load the test case plugin
open_internal(filename, factory_name);
if (!plugin->factory.isValid()) {
if (plugin->factory.getStatus() == shlibpp::VOCAB('f', 'a', 'c', 't')) {
std::string plug_type = (factory_name == ROBOTTESTINGFRAMEWORK_PLUGIN_FACTORY_NAME) ? "test case" : "fixture manager";
error = "cannot load plugin " + filename + "; (it is not a Robot Testing Framework " + plug_type + " plugin!)";
} else {
error = "cannot load plugin " + filename + "; error (" + shlibpp::Vocab::decode(plugin->factory.getStatus()) + ") : " + plugin->factory.getError();
}
delete plugin;
plugin = nullptr;
return nullptr;
}
// TODO: check if this is neccessary!!!
//plugin->factory.addRef();
// create an instance of the test case from the plugin
plugin->test.open(plugin->factory);
if (!plugin->test.isValid()) {
//error = Asserter::format("cannot create an instance of TestCase from %s", filename.c_str());
delete plugin;
plugin = nullptr;
return nullptr;
}
return &plugin->test.getContent();
}
void close()
{
if (plugin)
delete plugin;
plugin = nullptr;
error.clear();
}
const std::string& getLastError()
{
return error;
}
private:
std::string error;
Plugin* plugin;
void open_internal(const std::string filename,
const std::string factory_name)
{
std::string fullpath;
#if defined(_WIN32)
std::string ext = ".dll";
#else
std::string ext = ".so";
#endif
std::string basename;
bool has_ext;
if (filename.find(ext) != std::string::npos) {
basename = filename.substr(0, filename.size() - ext.size());
has_ext = true;
} else {
basename = filename;
has_ext = false;
}
#if defined(_MSC_VER) && !defined(NDEBUG)
// MSVC DEBUG build: try debug name before basic name
if (!has_ext) {
fullpath = basename + "d" + ext;
if (plugin->factory.open(fullpath.c_str(), factory_name.c_str()))
return;
}
#endif
// Basic name
fullpath = basename + ext;
if (plugin->factory.open(fullpath.c_str(), factory_name.c_str()))
return;
#if defined(_MSC_VER) && defined(NDEBUG)
// MSVC RELEASE build: try debug name after basic name
if (!has_ext) {
fullpath = basename + "d" + ext;
if (plugin->factory.open(fullpath.c_str(), factory_name.c_str()))
return;
}
#endif
#ifdef CMAKE_INTDIR
// On multi-config system, try to find the plugin in the
// current config subdirectory
# if defined(_MSC_VER) && !defined(NDEBUG)
// MSVC DEBUG build: try debug name before basic name
if (!has_ext) {
fullpath = std::string(CMAKE_INTDIR) + "/" + basename + "d" + ext;
if (plugin->factory.open(fullpath.c_str(), factory_name.c_str()))
return;
}
# endif
// Basic name
fullpath = std::string(CMAKE_INTDIR) + "/" + basename + ext;
if (plugin->factory.open(fullpath.c_str(), factory_name.c_str()))
return;
# if defined(_MSC_VER) && defined(NDEBUG)
// MSVC RELEASE build: try debug name after basic name
if (!has_ext) {
fullpath = std::string(CMAKE_INTDIR) + "/" + basename + "d" + ext;
if (plugin->factory.open(fullpath.c_str(), factory_name.c_str()))
return;
}
# endif
#endif
}
};
#endif // ROBOTTESTINGFRAMEWORK_DLLPLUGINLOADERIMPL_H
Plugin.h
ROBOTTESTINGFRAMEWORK_PLUGIN_FACTORY_NAME
#define ROBOTTESTINGFRAMEWORK_PLUGIN_FACTORY_NAME
Definition Plugin.h:27
SharedLibraryClass.h
SharedLibrary.h
DllPluginLoaderImpl::Plugin
Definition DllPluginLoader_impl.h:39
DllPluginLoaderImpl::Plugin::factory
shlibpp::SharedLibraryClassFactory< T > factory
Definition DllPluginLoader_impl.h:41
DllPluginLoaderImpl::Plugin::test
shlibpp::SharedLibraryClass< T > test
Definition DllPluginLoader_impl.h:42
DllPluginLoaderImpl::open
T * open(const std::string filename, const std::string factory_name)
open Loads a generic plugin
Definition DllPluginLoader_impl.h:69
DllPluginLoaderImpl::open_internal
void open_internal(const std::string filename, const std::string factory_name)
Definition DllPluginLoader_impl.h:135
DllPluginLoaderImpl::plugin
Plugin * plugin
Definition DllPluginLoader_impl.h:133
DllPluginLoaderImpl::error
std::string error
Definition DllPluginLoader_impl.h:132
DllPluginLoaderImpl::getLastError
const std::string & getLastError()
getLastError gets the last error if any.
Definition DllPluginLoader_impl.h:126
DllPluginLoaderImpl::DllPluginLoaderImpl
DllPluginLoaderImpl()
DllPluginLoaderImpl constructor.
Definition DllPluginLoader_impl.h:49
DllPluginLoaderImpl::close
void close()
close Unloads the plugin and deletes any allocated memory.
Definition DllPluginLoader_impl.h:114
DllPluginLoaderImpl::~DllPluginLoaderImpl
virtual ~DllPluginLoaderImpl()
DllPluginLoaderImpl destructor.
Definition DllPluginLoader_impl.h:57
shlibpp::SharedLibraryClassFactory
A type-safe wrapper for SharedLibraryFactory, committing to creation/destruction of instances of a pa...
Definition SharedLibraryClassFactory.h:43
shlibpp::SharedLibraryClass
Container for an object created using a factory provided by a shared library.
Definition SharedLibraryClass.h:40
shlibpp::Vocab::decode
static std::string decode(int code)
Definition Vocab.h:63
shlibpp::VOCAB
constexpr int32_t VOCAB(char a, char b=0, char c=0, char d=0)
Definition Vocab.h:31