a5406bdfa3f4b793bf22ac608088bdc112c6aebc
[metaproxy-moved-to-github.git] / src / filter_factory.cpp
1 /* $Id: filter_factory.cpp,v 1.2 2005-12-10 09:59:10 adam Exp $
2    Copyright (c) 2005, Index Data.
3
4 %LICENSE%
5  */
6
7 #include "config.hpp"
8
9 #include "filter_factory.hpp"
10
11 #if HAVE_DLFCN_H
12 #include <dlfcn.h>
13 #endif
14 #include <stdexcept>
15 #include <iostream>
16 #include <string>
17 #include <map>
18
19 namespace yp2 {
20     class FilterFactory::Rep {
21         typedef std::map<std::string, CreateFilterCallback> CallbackMap;
22     public:
23         friend class FilterFactory;
24         CallbackMap m_fcm;
25         Rep();
26         ~Rep();
27     };
28 }
29
30 yp2::FilterFactoryException::FilterFactoryException(const std::string message)
31     : std::runtime_error("FilterException: " + message)
32 {
33 }
34
35 yp2::FilterFactory::Rep::Rep()
36 {
37 }
38
39 yp2::FilterFactory::Rep::~Rep()
40 {
41 }
42
43 yp2::FilterFactory::FilterFactory() : m_p(new yp2::FilterFactory::Rep)
44 {
45
46 }
47
48 yp2::FilterFactory::~FilterFactory()
49 {
50
51 }
52
53 bool yp2::FilterFactory::add_creator(std::string fi,
54                                      CreateFilterCallback cfc)
55 {
56     return m_p->m_fcm.insert(Rep::CallbackMap::value_type(fi, cfc)).second;
57 }
58
59
60 bool yp2::FilterFactory::drop_creator(std::string fi)
61 {
62     return m_p->m_fcm.erase(fi) == 1;
63 }
64
65 yp2::filter::Base* yp2::FilterFactory::create(std::string fi)
66 {
67     Rep::CallbackMap::const_iterator it = m_p->m_fcm.find(fi);
68     
69     if (it == m_p->m_fcm.end()){
70         std::string msg = "filter type '" + fi + "' not found";
71             throw yp2::FilterFactoryException(msg);
72     }
73     // call create function
74     return (it->second());
75 }
76
77 #if HAVE_DLFCN_H
78 bool yp2::FilterFactory::add_creator_dyn(const std::string &fi,
79                                          const std::string &path)
80 {
81     std::string full_path = path + "/yp2_filter_" + fi + ".so";
82     void *dl_handle = dlopen(full_path.c_str(), RTLD_GLOBAL|RTLD_NOW);
83     if (!dl_handle)
84     {
85         const char *dl = dlerror();
86         std::cout << "dlopen " << full_path << " failed. dlerror=" << dl << 
87             std::endl;
88         return false;
89     }
90
91     std::string full_name = "yp2_filter_" + fi;
92     
93     void *dlsym_ptr = dlsym(dl_handle, full_name.c_str());
94     if (!dlsym_ptr)
95     {
96         std::cout << "dlsym " << full_name << " failed\n";
97         return false;
98     }
99     struct yp2_filter_struct *s = (struct yp2_filter_struct *) dlsym_ptr;
100     return add_creator(fi, s->creator);
101 }
102 #endif
103
104 /*
105  * Local variables:
106  * c-basic-offset: 4
107  * indent-tabs-mode: nil
108  * c-file-style: "stroustrup"
109  * End:
110  * vim: shiftwidth=4 tabstop=8 expandtab
111  */