From be0ca741fd12897337408d1d7a7d8f5f18e1fac9 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Wed, 16 Nov 2011 16:06:07 -0600 Subject: Finish rename from prior commit --- libtdenetwork/gpgmepp/eventloopinteractor.cpp | 185 ++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 libtdenetwork/gpgmepp/eventloopinteractor.cpp (limited to 'libtdenetwork/gpgmepp/eventloopinteractor.cpp') diff --git a/libtdenetwork/gpgmepp/eventloopinteractor.cpp b/libtdenetwork/gpgmepp/eventloopinteractor.cpp new file mode 100644 index 000000000..cdac7d567 --- /dev/null +++ b/libtdenetwork/gpgmepp/eventloopinteractor.cpp @@ -0,0 +1,185 @@ +/* eventloopinteractor.cpp + Copyright (C) 2003,2004 Klarälvdalens Datakonsult AB + + This file is part of GPGME++. + + GPGME++ 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 of the License, or + (at your option) any later version. + + GPGME++ 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 GPGME; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include "context_p.h" +#include +#include + +#include + +#include +using std::vector; +#ifndef NDEBUG +# include +#endif +#include + +namespace GpgME { + + // + // EventLoopInteractor::Private Declaration + // + + struct EventLoopInteractor::Private { + struct OneFD { + OneFD( int aFd, int aDir, gpgme_io_cb_t aFnc, + void * aFncData, void * aExternalTag ) + : fd( aFd ), dir( aDir ), fnc( aFnc ), + fncData( aFncData ), externalTag( aExternalTag ) {} + int fd; + int dir; + gpgme_io_cb_t fnc; + void * fncData; + void * externalTag; + }; + + vector mCallbacks; + + static void removeIOCb( void * tag ); + static gpgme_error_t registerIOCb( void * data, int fd, int dir, + gpgme_io_cb_t fnc, void * fnc_data, + void ** r_tag ); + static void eventIOCb( void *, gpgme_event_io_t type, void * type_data ); + + static gpgme_io_cbs iocbs; + }; + + gpgme_io_cbs EventLoopInteractor::Private::iocbs = { + &EventLoopInteractor::Private::registerIOCb, + 0, + &EventLoopInteractor::Private::removeIOCb, + &EventLoopInteractor::Private::eventIOCb, + 0 + }; + + + // + // EventLoopInteractor::Private IO Callback Implementations + // + + gpgme_error_t EventLoopInteractor::Private::registerIOCb( void *, int fd, int dir, + gpgme_io_cb_t fnc, void * fnc_data, + void ** r_tag ) + { + assert( instance() ); assert( instance()->d ); + bool ok = false; + void * etag = instance()->registerWatcher( fd, dir ? Read : Write, ok ); + if ( !ok ) return GPG_ERR_GENERAL; + instance()->d->mCallbacks.push_back( new OneFD( fd, dir, fnc, fnc_data, etag ) ); + if ( r_tag ) + *r_tag = instance()->d->mCallbacks.back(); + return GPG_ERR_NO_ERROR; + } + + void EventLoopInteractor::Private::removeIOCb( void * tag ) { + assert( instance() ); assert( instance()->d ); + + for ( vector::iterator it = instance()->d->mCallbacks.begin() ; + it != instance()->d->mCallbacks.end() ; ++it ) { + if ( *it == tag ) { + instance()->unregisterWatcher( (*it)->externalTag ); + delete *it; *it = 0; + instance()->d->mCallbacks.erase( it ); + return; + } + } + } + + void EventLoopInteractor::Private::eventIOCb( void * data, gpgme_event_io_t type, void * type_data ) { + assert( instance() ); + Context * ctx = static_cast( data ); + switch( type ) { + case GPGME_EVENT_START: + { + // hmmm, what to do here? + } + break; + case GPGME_EVENT_DONE: + { + gpgme_error_t e = *static_cast( type_data ); + if ( ctx && ctx->impl() ) + ctx->impl()->lasterr = e; + instance()->operationDoneEvent( ctx, e ); + } + break; + case GPGME_EVENT_NEXT_KEY: + { + gpgme_key_t key = static_cast( type_data ); + instance()->nextKeyEvent( ctx, Key( key, false, ctx ? ctx->keyListMode() : 0 ) ); + } + break; + case GPGME_EVENT_NEXT_TRUSTITEM: + { + gpgme_trust_item_t item = static_cast( type_data ); + instance()->nextTrustItemEvent( ctx, TrustItem( item ) ); + gpgme_trust_item_unref( item ); + } + break; + default: // warn + ; + } + } + + // + // EventLoopInteractor Implementation + // + + EventLoopInteractor * EventLoopInteractor::mSelf = 0; + + EventLoopInteractor::EventLoopInteractor() { + assert( !mSelf ); + d = new Private(); + mSelf = this; + } + + EventLoopInteractor::~EventLoopInteractor() { + // warn if there are still callbacks registered + mSelf = 0; + delete d; d = 0; + } + + void EventLoopInteractor::manage( Context * context ) { + if ( !context || context->managedByEventLoopInteractor() ) return; + gpgme_io_cbs * iocbs = new gpgme_io_cbs( Private::iocbs ); + iocbs->event_priv = context; + context->installIOCallbacks( iocbs ); + } + + void EventLoopInteractor::unmanage( Context * context ) { + if ( context ) + context->uninstallIOCallbacks(); + } + + void EventLoopInteractor::actOn( int fd, Direction dir ) { + for ( vector::const_iterator it = d->mCallbacks.begin() ; + it != d->mCallbacks.end() ; ++it ) + if ( (*it)->fd == fd && ( (*it)->dir ? Read : Write ) == dir ) { + (*((*it)->fnc))( (*it)->fncData, fd ); + break; + } + } + +} // namespace GpgME -- cgit v1.2.1