#ifndef __JEEP__JFUNCTIONADAPTOR__ #define __JEEP__JFUNCTIONADAPTOR__ #include #include #include #include #include "JLang/JException.hh" #include "JLang/JSharedCounter.hh" /** * \author mdejong */ namespace JEEP {} namespace JPP { using namespace JEEP; } namespace JEEP { using JLANG::JSharedCounter; using JLANG::JFileOpenException; using JLANG::JFileReadException; /** * Auxiliary base class for function adaptor. * * Note that the dynamic load library internally maintains link counts for the file handles. */ template struct JFunctionAdaptorHelper : JSharedCounter { /** * Separation character between library file name and function name. */ static const char SEPARATOR = ':'; /** * Virtual destructor. */ virtual ~JFunctionAdaptorHelper() { reset(); } /** * Check validity of function. * * \return true if valid function; else false */ bool is_valid() const { return (function != NULL); } /** * Reset function adaptor helper. */ void reset() { if (detach()) { close(); } function = NULL; } /** * Set function. * * \param pf pointer to function */ void set(__pF__ pf) { reset(); function = pf; } /** * Get function with given name according to specific protocol. * * \param symbol function name */ void get(const char* symbol) { function = NULL; if (handle != NULL) { dlerror(); // reset errors function = (__pF__) dlsym(handle, symbol); const char* error = dlerror(); if (error != NULL) { THROW(JFileReadException, error); } } else { THROW(JFileReadException, "Invalid handle."); } } /** * Check if shared library file is open. * * \return true if open; else false */ bool is_open() const { return (handle != NULL); } /** * Open file. * * \param file_name file name */ void open(const char* file_name) { reset(); handle = dlopen(file_name, RTLD_LOCAL | RTLD_LAZY); if (!handle) { THROW(JFileOpenException, dlerror()); } initialise(); } /** * Close file. * * Note that the file should remain open as long as the library function is used. */ void close() { if (handle != NULL) { dlclose(handle); dlclose(handle); } handle = NULL; } /** * Load function from shared library. * * \param libso file name * \param symbol function name */ void load(const std::string& libso, const std::string& symbol) { this->libso = libso; this->symbol = symbol; reload(); } /** * Reload function from shared library. */ void reload() { open(libso.c_str()); get(symbol.c_str()); } /** * Read function adaptor helper from input stream. * * The input format should be conform \[SEPARATOR\]. * * \param in input stream * \param object function adaptor helper * \return input stream */ friend std::istream& operator>>(std::istream& in, JFunctionAdaptorHelper& object) { using namespace std; object.reset(); string buffer; if (in >> buffer) { const string::size_type pos = buffer.rfind(SEPARATOR); if (pos != string::npos) { object.libso = buffer.substr(0,pos); object.symbol = buffer.substr(pos+1); } else { object.libso = buffer; } object.reload(); } return in; } /** * Write function adaptor helper to output stream. * * \param out output stream * \param object function adaptor helper * \return output stream */ friend std::ostream& operator<<(std::ostream& out, const JFunctionAdaptorHelper& object) { return out; } protected: /** * Default constructor. */ JFunctionAdaptorHelper() : handle (NULL), function(NULL) {} /** * Constructor. * * \param pf pointer to function */ JFunctionAdaptorHelper(__pF__ pf) : handle (NULL), function(pf) {} /** * Constructor. * * \param libso file name * \param symbol function name */ JFunctionAdaptorHelper(const std::string& libso, const std::string& symbol) : handle (NULL), function(NULL) { this->load(libso, symbol); } /** * Copy constructor. * * \param helper helper */ JFunctionAdaptorHelper(const JFunctionAdaptorHelper& helper) : handle (helper.handle), function(helper.function), libso (helper.libso), symbol (helper.symbol) { if (is_open()) { attach(helper); } } void* handle; __pF__ function; std::string libso; std::string symbol; }; /** * Function adaptor. */ template struct JFunctionAdaptor : public JFunctionAdaptorHelper { /** * Type definition of method. */ typedef JReturn_t (*pF)(Args...); /** * Default constructor. */ JFunctionAdaptor() : JFunctionAdaptorHelper() {} /** * Constructor. * * \param pf pointer to function */ JFunctionAdaptor(pF pf) : JFunctionAdaptorHelper(pf) {} /** * Constructor. * * \param libso file name * \param symbol function name */ JFunctionAdaptor(const std::string& libso, const std::string& symbol) : JFunctionAdaptorHelper(libso, symbol) {} /** * Function operation. * * \param args arguments * \return return value */ JReturn_t operator()(Args... args) const { return this->function(args...); } }; } #endif