libkdenetwork Library API Documentation

gpgmepp/eventloopinteractor.cpp

00001 /* eventloopinteractor.cpp
00002    Copyright (C) 2003,2004 Klarälvdalens Datakonsult AB
00003 
00004    This file is part of GPGME++.
00005  
00006    GPGME++ is free software; you can redistribute it and/or modify it
00007    under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010  
00011    GPGME++ is distributed in the hope that it will be useful, but
00012    WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with GPGME; if not, write to the Free Software Foundation,
00018    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA.  */
00019 
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023 
00024 #include <gpgmepp/eventloopinteractor.h>
00025 
00026 #include <gpgmepp/context.h>
00027 #include "context_p.h"
00028 #include <gpgmepp/key.h>
00029 #include <gpgmepp/trustitem.h>
00030 
00031 #include <gpgme.h>
00032 
00033 #include <vector>
00034 using std::vector;
00035 #ifndef NDEBUG
00036 # include <iostream>
00037 #endif
00038 #include <cassert>
00039 
00040 namespace GpgME {
00041 
00042   //
00043   // EventLoopInteractor::Private Declaration
00044   //
00045 
00046   struct EventLoopInteractor::Private {
00047     struct OneFD {
00048       OneFD( int aFd, int aDir, gpgme_io_cb_t aFnc,
00049          void * aFncData, void * aExternalTag )
00050     : fd( aFd ), dir( aDir ), fnc( aFnc ),
00051       fncData( aFncData ), externalTag( aExternalTag ) {}
00052       int fd;
00053       int dir;
00054       gpgme_io_cb_t fnc;
00055       void * fncData;
00056       void * externalTag;
00057     };
00058 
00059     vector<OneFD*> mCallbacks;
00060 
00061     static void removeIOCb( void * tag );
00062     static gpgme_error_t registerIOCb( void * data, int fd, int dir,
00063                     gpgme_io_cb_t fnc, void * fnc_data,
00064                     void ** r_tag );
00065     static void eventIOCb( void *, gpgme_event_io_t type, void * type_data );
00066 
00067     static gpgme_io_cbs iocbs;
00068   };
00069 
00070   gpgme_io_cbs EventLoopInteractor::Private::iocbs = {
00071     &EventLoopInteractor::Private::registerIOCb,
00072     0,
00073     &EventLoopInteractor::Private::removeIOCb,
00074     &EventLoopInteractor::Private::eventIOCb,
00075     0
00076   };
00077 
00078 
00079   //
00080   // EventLoopInteractor::Private IO Callback Implementations
00081   //
00082 
00083   gpgme_error_t EventLoopInteractor::Private::registerIOCb( void *, int fd, int dir,
00084                              gpgme_io_cb_t fnc, void * fnc_data,
00085                              void ** r_tag )
00086   {
00087     assert( instance() ); assert( instance()->d );
00088     bool ok = false;
00089     void * etag = instance()->registerWatcher( fd, dir ? Read : Write, ok );
00090     if ( !ok ) return GPG_ERR_GENERAL;
00091     instance()->d->mCallbacks.push_back( new OneFD( fd, dir, fnc, fnc_data, etag ) );
00092     if ( r_tag )
00093       *r_tag = instance()->d->mCallbacks.back();
00094     return GPG_ERR_NO_ERROR;
00095   }
00096 
00097   void EventLoopInteractor::Private::removeIOCb( void * tag ) {
00098     assert( instance() ); assert( instance()->d );
00099 
00100     for ( vector<OneFD*>::iterator it = instance()->d->mCallbacks.begin() ;
00101      it != instance()->d->mCallbacks.end() ; ++it ) {
00102       if ( *it == tag ) {
00103     instance()->unregisterWatcher( (*it)->externalTag );
00104     delete *it; *it = 0;
00105     instance()->d->mCallbacks.erase( it );
00106     return;
00107       }
00108     }
00109   }
00110 
00111   void EventLoopInteractor::Private::eventIOCb( void * data, gpgme_event_io_t type, void * type_data ) {
00112     assert( instance() );
00113     Context * ctx = static_cast<Context*>( data );
00114     switch( type ) {
00115     case GPGME_EVENT_START:
00116       {
00117     // hmmm, what to do here?
00118       }
00119       break;
00120     case GPGME_EVENT_DONE:
00121       {
00122     gpgme_error_t e = *static_cast<gpgme_error_t*>( type_data );
00123     if ( ctx && ctx->impl() )
00124       ctx->impl()->lasterr = e;
00125     instance()->operationDoneEvent( ctx, e );
00126       }
00127       break;
00128     case GPGME_EVENT_NEXT_KEY:
00129       {
00130     gpgme_key_t key = static_cast<gpgme_key_t>( type_data );
00131     instance()->nextKeyEvent( ctx, Key( key, false, ctx ? ctx->keyListMode() : 0 ) );
00132       }
00133       break;
00134     case GPGME_EVENT_NEXT_TRUSTITEM:
00135       {
00136     gpgme_trust_item_t item = static_cast<gpgme_trust_item_t>( type_data );
00137     instance()->nextTrustItemEvent( ctx, TrustItem( item ) );
00138     gpgme_trust_item_unref( item );
00139       }
00140       break;
00141     default: // warn
00142       ;
00143     }
00144   }
00145 
00146   //
00147   // EventLoopInteractor Implementation
00148   //
00149 
00150   EventLoopInteractor * EventLoopInteractor::mSelf = 0;
00151 
00152   EventLoopInteractor::EventLoopInteractor() {
00153     assert( !mSelf );
00154     d = new Private();
00155     mSelf = this;
00156   }
00157 
00158   EventLoopInteractor::~EventLoopInteractor() {
00159     // warn if there are still callbacks registered
00160     mSelf = 0;
00161     delete d; d = 0;
00162   }
00163 
00164   void EventLoopInteractor::manage( Context * context ) {
00165     if ( !context || context->managedByEventLoopInteractor() ) return;
00166     gpgme_io_cbs * iocbs = new gpgme_io_cbs( Private::iocbs );
00167     iocbs->event_priv = context;
00168     context->installIOCallbacks( iocbs );
00169   }
00170 
00171   void EventLoopInteractor::unmanage( Context * context ) {
00172     if ( context )
00173       context->uninstallIOCallbacks();
00174   }
00175 
00176   void EventLoopInteractor::actOn( int fd, Direction dir ) {
00177     for ( vector<Private::OneFD*>::const_iterator it = d->mCallbacks.begin() ;
00178       it != d->mCallbacks.end() ; ++it )
00179       if ( (*it)->fd == fd && ( (*it)->dir ? Read : Write ) == dir ) {
00180     (*((*it)->fnc))( (*it)->fncData, fd );
00181     break;
00182       }
00183   }
00184 
00185 } // namespace GpgME
KDE Logo
This file is part of the documentation for libkdenetwork Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Aug 2 09:52:01 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003