Jpp  master_rocky-40-g5f0272dcd
the software that should make you happy
JFunctionAdaptor.hh
Go to the documentation of this file.
1 #ifndef __JEEP__JFUNCTIONADAPTOR__
2 #define __JEEP__JFUNCTIONADAPTOR__
3 
4 #include <istream>
5 #include <ostream>
6 #include <string>
7 #include <dlfcn.h>
8 
9 #include "JLang/JException.hh"
10 #include "JLang/JSharedCounter.hh"
11 
12 
13 /**
14  * \author mdejong
15  */
16 
17 namespace JEEP {}
18 namespace JPP { using namespace JEEP; }
19 
20 namespace JEEP {
21 
25 
26 
27  /**
28  * Auxiliary base class for function adaptor.
29  *
30  * Note that the dynamic load library internally maintains link counts for the file handles.
31  */
32  template<class __pF__>
35  {
36  /**
37  * Separation character between library file name and function name.
38  */
39  static const char SEPARATOR = ':';
40 
41 
42  /**
43  * Virtual destructor.
44  */
46  {
47  reset();
48  }
49 
50 
51  /**
52  * Check validity of function.
53  *
54  * \return true if valid function; else false
55  */
56  bool is_valid() const
57  {
58  return (function != NULL);
59  }
60 
61 
62  /**
63  * Reset function adaptor helper.
64  */
65  void reset()
66  {
67  if (detach()) {
68  close();
69  }
70 
71  function = NULL;
72  }
73 
74 
75  /**
76  * Set function.
77  *
78  * \param pf pointer to function
79  */
80  void set(__pF__ pf)
81  {
82  reset();
83 
84  function = pf;
85  }
86 
87 
88  /**
89  * Get function with given name according to specific protocol.
90  *
91  * \param symbol function name
92  */
93  void get(const char* symbol)
94  {
95  function = NULL;
96 
97  if (handle != NULL) {
98 
99  dlerror(); // reset errors
100 
101  function = (__pF__) dlsym(handle, symbol);
102 
103  const char* error = dlerror();
104 
105  if (error != NULL) {
106  THROW(JFileReadException, error);
107  }
108 
109  } else {
110 
111  THROW(JFileReadException, "Invalid handle.");
112  }
113  }
114 
115 
116  /**
117  * Check if shared library file is open.
118  *
119  * \return true if open; else false
120  */
121  bool is_open() const
122  {
123  return (handle != NULL);
124  }
125 
126 
127  /**
128  * Open file.
129  *
130  * \param file_name file name
131  */
132  void open(const char* file_name)
133  {
134  reset();
135 
136  handle = dlopen(file_name, RTLD_LOCAL | RTLD_LAZY);
137 
138  if (!handle) {
139  THROW(JFileOpenException, dlerror());
140  }
141 
142  initialise();
143  }
144 
145 
146  /**
147  * Close file.
148  *
149  * Note that the file should remain open as long as the library function is used.
150  */
151  void close()
152  {
153  if (handle != NULL) {
154  dlclose(handle);
155  dlclose(handle);
156  }
157 
158  handle = NULL;
159  }
160 
161 
162  /**
163  * Load function from shared library.
164  *
165  * \param libso file name
166  * \param symbol function name
167  */
168  void load(const std::string& libso, const std::string& symbol)
169  {
170  this->libso = libso;
171  this->symbol = symbol;
172 
173  reload();
174  }
175 
176 
177  /**
178  * Reload function from shared library.
179  */
180  void reload()
181  {
182  open(libso.c_str());
183 
184  get(symbol.c_str());
185  }
186 
187 
188  /**
189  * Read function adaptor helper from input stream.
190  *
191  * The input format should be conform <tt><file name>[</tt>SEPARATOR<tt><symbol>]</tt>.
192  *
193  * \param in input stream
194  * \param object function adaptor helper
195  * \return input stream
196  */
197  friend std::istream& operator>>(std::istream& in, JFunctionAdaptorHelper& object)
198  {
199  using namespace std;
200 
201  object.reset();
202 
203  string buffer;
204 
205  if (in >> buffer) {
206 
207  const string::size_type pos = buffer.rfind(SEPARATOR);
208 
209  if (pos != string::npos) {
210 
211  object.libso = buffer.substr(0,pos);
212  object.symbol = buffer.substr(pos+1);
213 
214  } else {
215 
216  object.libso = buffer;
217  }
218 
219  object.reload();
220  }
221 
222  return in;
223  }
224 
225 
226  /**
227  * Write function adaptor helper to output stream.
228  *
229  * \param out output stream
230  * \param object function adaptor helper
231  * \return output stream
232  */
233  friend std::ostream& operator<<(std::ostream& out, const JFunctionAdaptorHelper& object)
234  {
235  return out;
236  }
237 
238  protected:
239  /**
240  * Default constructor.
241  */
243  handle (NULL),
244  function(NULL)
245  {}
246 
247 
248  /**
249  * Constructor.
250  *
251  * \param pf pointer to function
252  */
254  handle (NULL),
255  function(pf)
256  {}
257 
258 
259  /**
260  * Constructor.
261  *
262  * \param libso file name
263  * \param symbol function name
264  */
265  JFunctionAdaptorHelper(const std::string& libso,
266  const std::string& symbol) :
267  handle (NULL),
268  function(NULL)
269  {
270  this->load(libso, symbol);
271  }
272 
273 
274  /**
275  * Copy constructor.
276  *
277  * \param helper helper
278  */
280  handle (helper.handle),
281  function(helper.function),
282  libso (helper.libso),
283  symbol (helper.symbol)
284  {
285  if (is_open()) {
286  attach(helper);
287  }
288  }
289 
290  void* handle;
291  __pF__ function;
292  std::string libso;
293  std::string symbol;
294  };
295 
296 
297  /**
298  * Function adaptor.
299  */
300  template<class JReturn_t = void, class ...Args>
302  public JFunctionAdaptorHelper<JReturn_t (*)(Args...)>
303  {
304  /**
305  * Type definition of method.
306  */
307  typedef JReturn_t (*pF)(Args...);
308 
309 
310  /**
311  * Default constructor.
312  */
315  {}
316 
317 
318  /**
319  * Constructor.
320  *
321  * \param pf pointer to function
322  */
324  JFunctionAdaptorHelper<pF>(pf)
325  {}
326 
327 
328  /**
329  * Constructor.
330  *
331  * \param libso file name
332  * \param symbol function name
333  */
334  JFunctionAdaptor(const std::string& libso,
335  const std::string& symbol) :
337  {}
338 
339 
340  /**
341  * Function operation.
342  *
343  * \param args arguments
344  * \return return value
345  */
346  JReturn_t operator()(Args... args) const
347  {
348  return this->function(args...);
349  }
350  };
351 }
352 
353 #endif
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:712
Exception for opening of file.
Definition: JException.hh:360
Exception for reading of file.
Definition: JException.hh:396
void initialise()
Initialise counter.
void attach(const JSharedCounter &object)
Attach this counter to given shared counter object.
General puprpose classes and methods.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Definition: JSTDTypes.hh:14
Auxiliary base class for function adaptor.
JFunctionAdaptorHelper(const JFunctionAdaptorHelper &helper)
Copy constructor.
bool is_valid() const
Check validity of function.
void get(const char *symbol)
Get function with given name according to specific protocol.
void reload()
Reload function from shared library.
friend std::ostream & operator<<(std::ostream &out, const JFunctionAdaptorHelper &object)
Write function adaptor helper to output stream.
static const char SEPARATOR
Separation character between library file name and function name.
JFunctionAdaptorHelper()
Default constructor.
bool is_open() const
Check if shared library file is open.
void set(__pF__ pf)
Set function.
friend std::istream & operator>>(std::istream &in, JFunctionAdaptorHelper &object)
Read function adaptor helper from input stream.
JFunctionAdaptorHelper(__pF__ pf)
Constructor.
JFunctionAdaptorHelper(const std::string &libso, const std::string &symbol)
Constructor.
void open(const char *file_name)
Open file.
virtual ~JFunctionAdaptorHelper()
Virtual destructor.
void load(const std::string &libso, const std::string &symbol)
Load function from shared library.
void reset()
Reset function adaptor helper.
JFunctionAdaptor(const std::string &libso, const std::string &symbol)
Constructor.
JFunctionAdaptor(pF pf)
Constructor.
JFunctionAdaptor()
Default constructor.
JReturn_t operator()(Args... args) const
Function operation.