From a0bd9a4d8ff3a326f65cc585072d6547fd5bf22a Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 6 Jun 2011 13:43:58 +0200 Subject: [PATCH] Start work on on ZOOM filter This filter is an alternative to z3950_client, just based on ZOOM instead and with the ability to set ZOOM options. --- src/Makefile.am | 1 + src/factory_static.cpp | 2 + src/filter_zoom.cpp | 243 ++++++++++++++++++++++++++++++++++++++++++++++++ src/filter_zoom.hpp | 57 ++++++++++++ win/makefile | 1 + 5 files changed, 304 insertions(+) create mode 100644 src/filter_zoom.cpp create mode 100644 src/filter_zoom.hpp diff --git a/src/Makefile.am b/src/Makefile.am index ddd779e..0f756ea 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,6 +41,7 @@ libmetaproxy_la_SOURCES = \ filter_virt_db.cpp filter_virt_db.hpp \ filter_z3950_client.cpp filter_z3950_client.hpp \ filter_zeerex_explain.cpp filter_zeerex_explain.hpp \ + filter_zoom.cpp filter_zoom.hpp \ gduutil.cpp gduutil.hpp \ origin.cpp \ package.cpp \ diff --git a/src/factory_static.cpp b/src/factory_static.cpp index d34eed6..18f81ea 100644 --- a/src/factory_static.cpp +++ b/src/factory_static.cpp @@ -48,6 +48,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "filter_virt_db.hpp" #include "filter_z3950_client.hpp" #include "filter_zeerex_explain.hpp" +#include "filter_zoom.hpp" namespace mp = metaproxy_1; @@ -75,6 +76,7 @@ mp::FactoryStatic::FactoryStatic() &metaproxy_1_filter_virt_db, &metaproxy_1_filter_z3950_client, &metaproxy_1_filter_zeerex_explain, + &metaproxy_1_filter_zoom, 0 }; int i; diff --git a/src/filter_zoom.cpp b/src/filter_zoom.cpp new file mode 100644 index 0000000..b061e1b --- /dev/null +++ b/src/filter_zoom.cpp @@ -0,0 +1,243 @@ +/* This file is part of Metaproxy. + Copyright (C) 2005-2011 Index Data + +Metaproxy is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +Metaproxy 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 General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "config.hpp" +#include "filter_zoom.hpp" +#include +#include +#include + +#include +#include + +#include + +namespace mp = metaproxy_1; +namespace yf = mp::filter; + +namespace metaproxy_1 { + namespace filter { + class Zoom::Backend { + friend class Impl; + std::string zurl; + ZOOM_connection m_connection; + ZOOM_resultset m_resultset; + }; + class Zoom::Frontend { + friend class Impl; + Impl *m_p; + bool m_is_virtual; + bool m_in_use; + yazpp_1::GDU m_init_gdu; + public: + Frontend(Impl *impl); + ~Frontend(); + }; + class Zoom::Impl { + public: + Impl(); + ~Impl(); + void process(metaproxy_1::Package & package); + void configure(const xmlNode * ptr); + private: + FrontendPtr get_frontend(mp::Package &package); + void release_frontend(mp::Package &package); + + std::map m_clients; + boost::mutex m_mutex; + boost::condition m_cond_session_ready; + }; + } +} + +// define Pimpl wrapper forwarding to Impl + +yf::Zoom::Zoom() : m_p(new Impl) +{ +} + +yf::Zoom::~Zoom() +{ // must have a destructor because of boost::scoped_ptr +} + +void yf::Zoom::configure(const xmlNode *xmlnode, bool test_only) +{ + m_p->configure(xmlnode); +} + +void yf::Zoom::process(mp::Package &package) const +{ + m_p->process(package); +} + + +// define Implementation stuff + +yf::Zoom::Frontend::Frontend(Impl *impl) : + m_p(impl), m_is_virtual(false), m_in_use(true) +{ +} + +yf::Zoom::Frontend::~Frontend() +{ +} + +yf::Zoom::FrontendPtr yf::Zoom::Impl::get_frontend(mp::Package &package) +{ + boost::mutex::scoped_lock lock(m_mutex); + + std::map::iterator it; + + while(true) + { + it = m_clients.find(package.session()); + if (it == m_clients.end()) + break; + + if (!it->second->m_in_use) + { + it->second->m_in_use = true; + return it->second; + } + m_cond_session_ready.wait(lock); + } + FrontendPtr f(new Frontend(this)); + m_clients[package.session()] = f; + f->m_in_use = true; + return f; +} + +void yf::Zoom::Impl::release_frontend(mp::Package &package) +{ + boost::mutex::scoped_lock lock(m_mutex); + std::map::iterator it; + + it = m_clients.find(package.session()); + if (it != m_clients.end()) + { + if (package.session().is_closed()) + { + m_clients.erase(it); + } + else + { + it->second->m_in_use = false; + } + m_cond_session_ready.notify_all(); + } +} + +yf::Zoom::Impl::Impl() +{ +} + +yf::Zoom::Impl::~Impl() +{ +} + +void yf::Zoom::Impl::configure(const xmlNode *xmlnode) +{ +} + +void yf::Zoom::Impl::process(mp::Package &package) +{ + FrontendPtr f = get_frontend(package); + Z_GDU *gdu = package.request().get(); + + if (f->m_is_virtual) + { + if (gdu->which == Z_GDU_Z3950) + { + Z_APDU *apdu = gdu->u.z3950; + mp::odr odr; + + package.response() = odr.create_close( + apdu, + Z_Close_protocolError, + "not implemented"); + } + package.session().close(); + } + else if (gdu && gdu->which == Z_GDU_Z3950 && gdu->u.z3950->which == + Z_APDU_initRequest) + { + Z_InitRequest *req = gdu->u.z3950->u.initRequest; + f->m_init_gdu = gdu; + + mp::odr odr; + Z_APDU *apdu = odr.create_initResponse(gdu->u.z3950, 0, 0); + Z_InitResponse *resp = apdu->u.initResponse; + + int i; + static const int masks[] = { + Z_Options_search, + Z_Options_present, + -1 + }; + for (i = 0; masks[i] != -1; i++) + if (ODR_MASK_GET(req->options, masks[i])) + ODR_MASK_SET(resp->options, masks[i]); + + static const int versions[] = { + Z_ProtocolVersion_1, + Z_ProtocolVersion_2, + Z_ProtocolVersion_3, + -1 + }; + for (i = 0; versions[i] != -1; i++) + if (ODR_MASK_GET(req->protocolVersion, versions[i])) + ODR_MASK_SET(resp->protocolVersion, versions[i]); + else + break; + + *resp->preferredMessageSize = *req->preferredMessageSize; + *resp->maximumRecordSize = *req->maximumRecordSize; + + package.response() = apdu; + f->m_is_virtual = true; + } + else + package.move(); + + release_frontend(package); +} + + +static mp::filter::Base* filter_creator() +{ + return new mp::filter::Zoom; +} + +extern "C" { + struct metaproxy_1_filter_struct metaproxy_1_filter_zoom = { + 0, + "zoom", + filter_creator + }; +} + + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/filter_zoom.hpp b/src/filter_zoom.hpp new file mode 100644 index 0000000..f63f738 --- /dev/null +++ b/src/filter_zoom.hpp @@ -0,0 +1,57 @@ +/* This file is part of Metaproxy. + Copyright (C) 2005-2011 Index Data + +Metaproxy is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2, or (at your option) any later +version. + +Metaproxy 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 General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef FILTER_ZOOM_HPP +#define FILTER_ZOOM_HPP + +#include +#include + +#include + +namespace metaproxy_1 { + namespace filter { + class Zoom : public Base { + class Impl; + class Frontend; + class Backend; + boost::scoped_ptr m_p; + typedef boost::shared_ptr FrontendPtr; + public: + Zoom(); + ~Zoom(); + void process(metaproxy_1::Package & package) const; + void configure(const xmlNode * ptr, bool test_only); + }; + } +} + +extern "C" { + extern struct metaproxy_1_filter_struct metaproxy_1_filter_zoom; +} + +#endif +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/win/makefile b/win/makefile index d6cf870..b26d462 100644 --- a/win/makefile +++ b/win/makefile @@ -238,6 +238,7 @@ PROJECT_DLL_OBJS = \ $(OBJDIR)\filter_virt_db.obj \ $(OBJDIR)\filter_z3950_client.obj \ $(OBJDIR)\filter_zeerex_explain.obj \ + $(OBJDIR)\filter_zoom.obj \ $(OBJDIR)\gduutil.obj \ $(OBJDIR)\origin.obj \ $(OBJDIR)\package.obj \ -- 1.7.10.4