-## $Id: Makefile.am,v 1.37 2005-12-02 12:21:07 adam Exp $
+## $Id: Makefile.am,v 1.38 2005-12-10 09:59:10 adam Exp $
MAINTAINERCLEANFILES = Makefile.in config.in config.hpp
# Rules for the library..
lib_LTLIBRARIES = libyp2.la
-libyp2_la_LDFLAGS = -version-info 0:0:0
+libyp2_la_LDFLAGS = -version-info 0:0:0 -export-dynamic
libyp2_la_SOURCES = \
session.cpp session.hpp \
LDADD= libyp2.la $(YAZPPLALIB) $(XSLT_LIBS)
bin_PROGRAMS =
-noinst_PROGRAMS = ex_filter_frontend_net ex_router_flexml
+noinst_PROGRAMS = ex_filter_frontend_net ex_router_flexml tstdl
ex_filter_frontend_net_SOURCES = ex_filter_frontend_net.cpp
ex_router_flexml_SOURCES = ex_router_flexml.cpp
+tstdl_SOURCES = tstdl.cpp
+
+# Rules for dl programs
+pkglib_LTLIBRARIES = yp2_filter_dl.la
+
+yp2_filter_dl_la_SOURCES = filter_dl.cpp
+yp2_filter_dl_la_LDFLAGS = -rpath $(pkglibdir) -module -avoid-version
+yp2_filter_dl_la_LIBADD = libyp2.la
+
# Rules for test programs..
check_PROGRAMS = \
test_boost_time_SOURCES=test_boost_time.cpp
test_thread_pool_observer_SOURCES = test_thread_pool_observer.cpp
test_filter_factory_SOURCES = test_filter_factory.cpp
+test_filter_factory_LDFLAGS = -export-dynamic
test_filter_frontend_net_SOURCES = test_filter_frontend_net.cpp
test_filter_log_SOURCES = test_filter_log.cpp
test_filter_z3950_client_SOURCES = test_filter_z3950_client.cpp
-/* $Id: filter.hpp,v 1.9 2005-11-03 14:45:15 adam Exp $
+/* $Id: filter.hpp,v 1.10 2005-12-10 09:59:10 adam Exp $
Copyright (c) 2005, Index Data.
%LICENSE%
///sends Package off to next Filter, returns altered Package
virtual void process(Package & package) const = 0;
- virtual void configure(const xmlNode * ptr = 0) { };
- };
-
- struct Creator {
- const char* type;
- yp2::filter::Base* (*creator)();
+ virtual void configure(const xmlNode * ptr) { };
};
class FilterException : public std::runtime_error {
};
}
-
}
+struct yp2_filter_struct {
+ int ver;
+ yp2::filter::Base* (*creator)();
+};
+
#endif
/*
* Local variables:
--- /dev/null
+/* $Id: filter_dl.cpp,v 1.1 2005-12-10 09:59:10 adam Exp $
+ Copyright (c) 2005, Index Data.
+
+%LICENSE%
+ */
+
+#include "config.hpp"
+
+#include "filter.hpp"
+#include "router.hpp"
+#include "package.hpp"
+
+namespace yp2 {
+ namespace filter {
+ class Filter_dl: public yp2::filter::Base {
+ public:
+ void process(yp2::Package & package) const;
+ };
+ }
+}
+
+void yp2::filter::Filter_dl::process(yp2::Package & package) const
+{
+ package.data() = 42;
+}
+
+static yp2::filter::Base* filter_creator()
+{
+ return new yp2::filter::Filter_dl;
+}
+
+extern "C" {
+ struct yp2_filter_struct yp2_filter_dl = {
+ 0,
+ filter_creator
+ };
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * c-file-style: "stroustrup"
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
-/* $Id: filter_factory.cpp,v 1.1 2005-11-10 23:10:42 adam Exp $
+/* $Id: filter_factory.cpp,v 1.2 2005-12-10 09:59:10 adam Exp $
Copyright (c) 2005, Index Data.
%LICENSE%
*/
+#include "config.hpp"
+
#include "filter_factory.hpp"
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
#include <stdexcept>
#include <iostream>
#include <string>
namespace yp2 {
class FilterFactory::Rep {
+ typedef std::map<std::string, CreateFilterCallback> CallbackMap;
public:
friend class FilterFactory;
CallbackMap m_fcm;
bool yp2::FilterFactory::add_creator(std::string fi,
CreateFilterCallback cfc)
{
- return m_p->m_fcm.insert(CallbackMap::value_type(fi, cfc)).second;
+ return m_p->m_fcm.insert(Rep::CallbackMap::value_type(fi, cfc)).second;
}
yp2::filter::Base* yp2::FilterFactory::create(std::string fi)
{
- CallbackMap::const_iterator it = m_p->m_fcm.find(fi);
+ Rep::CallbackMap::const_iterator it = m_p->m_fcm.find(fi);
if (it == m_p->m_fcm.end()){
std::string msg = "filter type '" + fi + "' not found";
return (it->second());
}
+#if HAVE_DLFCN_H
+bool yp2::FilterFactory::add_creator_dyn(const std::string &fi,
+ const std::string &path)
+{
+ std::string full_path = path + "/yp2_filter_" + fi + ".so";
+ void *dl_handle = dlopen(full_path.c_str(), RTLD_GLOBAL|RTLD_NOW);
+ if (!dl_handle)
+ {
+ const char *dl = dlerror();
+ std::cout << "dlopen " << full_path << " failed. dlerror=" << dl <<
+ std::endl;
+ return false;
+ }
+
+ std::string full_name = "yp2_filter_" + fi;
+
+ void *dlsym_ptr = dlsym(dl_handle, full_name.c_str());
+ if (!dlsym_ptr)
+ {
+ std::cout << "dlsym " << full_name << " failed\n";
+ return false;
+ }
+ struct yp2_filter_struct *s = (struct yp2_filter_struct *) dlsym_ptr;
+ return add_creator(fi, s->creator);
+}
+#endif
+
/*
* Local variables:
* c-basic-offset: 4
-/* $Id: filter_factory.hpp,v 1.6 2005-11-10 23:10:42 adam Exp $
+/* $Id: filter_factory.hpp,v 1.7 2005-12-10 09:59:10 adam Exp $
Copyright (c) 2005, Index Data.
%LICENSE%
class FilterFactory : public boost::noncopyable
{
typedef yp2::filter::Base* (*CreateFilterCallback)();
- typedef std::map<std::string, CreateFilterCallback> CallbackMap;
class Rep;
public:
~FilterFactory();
bool add_creator(std::string fi, CreateFilterCallback cfc);
- /// true if unregistration ok
bool drop_creator(std::string fi);
- /// factory create method
-
yp2::filter::Base* create(std::string fi);
-
+
+ bool add_creator_dyn(const std::string &fi, const std::string &path);
private:
boost::scoped_ptr<Rep> m_p;
};
-/* $Id: test_filter_factory.cpp,v 1.6 2005-12-02 12:21:07 adam Exp $
+/* $Id: test_filter_factory.cpp,v 1.7 2005-12-10 09:59:10 adam Exp $
Copyright (c) 2005, Index Data.
%LICENSE%
*/
-
#include <iostream>
#include <stdexcept>
#include "config.hpp"
#include "filter.hpp"
+#include "package.hpp"
#include "filter_factory.hpp"
using namespace boost::unit_test;
+// XFilter
class XFilter: public yp2::filter::Base {
public:
- void process(yp2::Package & package) const {};
+ void process(yp2::Package & package) const;
};
+void XFilter::process(yp2::Package & package) const
+{
+ package.data() = 1;
+}
-yp2::filter::Base* xfilter_creator(){
+static yp2::filter::Base* xfilter_creator(){
return new XFilter;
}
+// YFilter ...
class YFilter: public yp2::filter::Base {
public:
- void process(yp2::Package & package) const {};
+ void process(yp2::Package & package) const;
};
-yp2::filter::Base* yfilter_creator(){
- return new YFilter;
+void YFilter::process(yp2::Package & package) const
+{
+ package.data() = 2;
}
+static yp2::filter::Base* yfilter_creator(){
+ return new YFilter;
+}
BOOST_AUTO_UNIT_TEST( test_filter_factory_1 )
{
const std::string xfid = "XFilter";
const std::string yfid = "YFilter";
- //std::cout << "Xfilter name: " << xfid << std::endl;
- //std::cout << "Yfilter name: " << yfid << std::endl;
-
- BOOST_CHECK_EQUAL(ffactory.add_creator(xfid, xfilter_creator),
- true);
- BOOST_CHECK_EQUAL(ffactory.drop_creator(xfid),
- true);
- BOOST_CHECK_EQUAL(ffactory.add_creator(xfid, xfilter_creator),
- true);
- BOOST_CHECK_EQUAL(ffactory.add_creator(yfid, yfilter_creator),
- true);
+ BOOST_CHECK(ffactory.add_creator(xfid, xfilter_creator));
+ BOOST_CHECK(ffactory.drop_creator(xfid));
+ BOOST_CHECK(ffactory.add_creator(xfid, xfilter_creator));
+ BOOST_CHECK(ffactory.add_creator(yfid, yfilter_creator));
yp2::filter::Base* xfilter = 0;
xfilter = ffactory.create(xfid);
yp2::filter::Base* yfilter = 0;
yfilter = ffactory.create(yfid);
- //BOOST_CHECK_EQUAL(sizeof(xf), sizeof(*xfilter));
- //BOOST_CHECK_EQUAL(sizeof(yf), sizeof(*yfilter));
-
BOOST_CHECK(0 != xfilter);
BOOST_CHECK(0 != yfilter);
+
+ yp2::Package pack;
+ xfilter->process(pack);
+ BOOST_CHECK_EQUAL(pack.data(), 1);
+
+ yfilter->process(pack);
+ BOOST_CHECK_EQUAL(pack.data(), 2);
}
catch ( ... ) {
throw;
BOOST_CHECK (false);
}
-
- std::exit(0);
}
-// get function - right val in assignment
-//std::string name() const {
-//return m_name;
-// return "Base";
-//}
-
-// set function - left val in assignment
-//std::string & name() {
-// return m_name;
-//}
+#if HAVE_DLFCN_H
+BOOST_AUTO_UNIT_TEST( test_filter_factory_2 )
+{
+ try {
+ yp2::FilterFactory ffactory;
+
+ const std::string id = "dl";
+
+ BOOST_CHECK(ffactory.add_creator_dyn(id, ".libs"));
+
+ yp2::filter::Base* filter = 0;
+ filter = ffactory.create(id);
-// set function - can be chained
-//Base & name(const std::string & name){
-// m_name = name;
-// return *this;
-//}
+ BOOST_CHECK(0 != filter);
+ yp2::Package pack;
+ filter->process(pack);
+ BOOST_CHECK_EQUAL(pack.data(), 42); // magic from filter_dl ..
+ }
+ catch ( ... ) {
+ throw;
+ BOOST_CHECK (false);
+ }
+}
+#endif
/*
* Local variables:
--- /dev/null
+/* $Id: tstdl.cpp,v 1.1 2005-12-10 09:59:10 adam Exp $
+ Copyright (c) 2005, Index Data.
+
+%LICENSE%
+ */
+
+#include "config.hpp"
+
+#include <stdlib.h>
+#include <iostream>
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+using namespace std;
+
+int main(int argc, char **argv)
+{
+#if HAVE_DLFCN_H
+ if (argc != 3)
+ {
+ cerr << "bad args" << endl << "Usage: tstdl filename symbol" << endl;
+ exit(1);
+ }
+ void *mod = dlopen(argv[1][0] ? argv[1] : 0, RTLD_NOW|RTLD_LOCAL);
+ if (!mod)
+ {
+ cerr << "dlopen failed for file " << argv[1] <<
+ "dlerror=" << dlerror() << endl;
+ exit(1);
+ }
+ void *sym = dlsym(mod, argv[2]);
+ printf("sym=%p\n", sym);
+ dlclose(mod);
+ exit(0);
+#else
+ cerr << "dl lib not enabled or not supported" << endl;
+ exit(1);
+#endif
+
+}
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * c-file-style: "stroustrup"
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */