libkdenetwork Library API Documentation

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.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Oct 21 19:46:16 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003