eventloopinteractor.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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:
00142 ;
00143 }
00144 }
00145
00146
00147
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
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 }
This file is part of the documentation for libkdenetwork Library Version 3.3.0.