• Skip to content
  • Skip to link menu
KDE 4.8 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • KDE Home
  • Contact Us
 

qgpgme

dataprovider.cpp
00001 /* dataprovider.cpp
00002    Copyright (C) 2004 Klar�vdalens Datakonsult AB
00003 
00004    This file is part of QGPGME.
00005 
00006    QGPGME is free software; you can redistribute it and/or modify it
00007    under the terms of the GNU Library General Public License as published
00008    by the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010 
00011    QGPGME 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
00014    GNU Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with QGPGME; see the file COPYING.LIB.  If not, write to the
00018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019    Boston, MA 02110-1301, USA. */
00020 
00021 // -*- c++ -*-
00022 
00023 #include <qgpgme/dataprovider.h>
00024 
00025 #include <gpgme++/error.h>
00026 
00027 #include <QIODevice>
00028 #include <QProcess>
00029 
00030 #include <cstdio>
00031 #include <cstring>
00032 #include <cassert>
00033 
00034 using namespace QGpgME;
00035 using namespace GpgME;
00036 
00037 //
00038 //
00039 // QByteArrayDataProvider
00040 //
00041 //
00042 
00043 static bool resizeAndInit( QByteArray & ba, size_t newSize ) {
00044   const size_t oldSize = ba.size();
00045   ba.resize( newSize );
00046   const bool ok = ( newSize == static_cast<size_t>( ba.size() ) );
00047   if ( ok )
00048     memset( ba.data() + oldSize, 0, newSize - oldSize );
00049   return ok;
00050 }
00051 
00052 QByteArrayDataProvider::QByteArrayDataProvider()
00053   : GpgME::DataProvider(), mOff( 0 ) {}
00054 
00055 QByteArrayDataProvider::QByteArrayDataProvider( const QByteArray & initialData )
00056   : GpgME::DataProvider(), mArray( initialData ), mOff( 0 ) {}
00057 
00058 QByteArrayDataProvider::~QByteArrayDataProvider() {}
00059 
00060 ssize_t QByteArrayDataProvider::read( void * buffer, size_t bufSize ) {
00061 #ifndef NDEBUG
00062   //qDebug( "QByteArrayDataProvider::read( %p, %d )", buffer, bufSize );
00063 #endif
00064   if ( bufSize == 0 )
00065     return 0;
00066   if ( !buffer ) {
00067     Error::setSystemError( GPG_ERR_EINVAL );
00068     return -1;
00069   }
00070   if ( mOff >= mArray.size() )
00071     return 0; // EOF
00072   size_t amount = qMin( bufSize, static_cast<size_t>( mArray.size() - mOff ) );
00073   assert( amount > 0 );
00074   memcpy( buffer, mArray.data() + mOff, amount );
00075   mOff += amount;
00076   return amount;
00077 }
00078 
00079 ssize_t QByteArrayDataProvider::write( const void * buffer, size_t bufSize ) {
00080 #ifndef NDEBUG
00081   //qDebug( "QByteArrayDataProvider::write( %p, %lu )", buffer, static_cast<unsigned long>( bufSize ) );
00082 #endif
00083   if ( bufSize == 0 )
00084     return 0;
00085   if ( !buffer ) {
00086     Error::setSystemError( GPG_ERR_EINVAL );
00087     return -1;
00088   }
00089   if ( mOff >= mArray.size() )
00090     resizeAndInit( mArray, mOff + bufSize );
00091   if ( mOff >= mArray.size() ) {
00092     Error::setSystemError( GPG_ERR_EIO );
00093     return -1;
00094   }
00095   assert( bufSize <= static_cast<size_t>(mArray.size()) - mOff );
00096   memcpy( mArray.data() + mOff, buffer, bufSize );
00097   mOff += bufSize;
00098   return bufSize;
00099 }
00100 
00101 off_t QByteArrayDataProvider::seek( off_t offset, int whence ) {
00102 #ifndef NDEBUG
00103   //qDebug( "QByteArrayDataProvider::seek( %d, %d )", int(offset), whence );
00104 #endif
00105   int newOffset = mOff;
00106   switch ( whence ) {
00107   case SEEK_SET:
00108     newOffset = offset;
00109     break;
00110   case SEEK_CUR:
00111     newOffset += offset;
00112     break;
00113   case SEEK_END:
00114     newOffset = mArray.size() + offset;
00115     break;
00116   default:
00117     Error::setSystemError( GPG_ERR_EINVAL );
00118     return (off_t)-1;
00119   }
00120   return mOff = newOffset;
00121 }
00122 
00123 void QByteArrayDataProvider::release() {
00124 #ifndef NDEBUG
00125   //qDebug( "QByteArrayDataProvider::release()" );
00126 #endif
00127   mArray = QByteArray();
00128 }
00129 
00130 
00131 //
00132 //
00133 // QIODeviceDataProvider
00134 //
00135 //
00136 
00137 QIODeviceDataProvider::QIODeviceDataProvider( const boost::shared_ptr<QIODevice> & io )
00138   : GpgME::DataProvider(),
00139     mIO( io ),
00140     mErrorOccurred( false ),
00141     mHaveQProcess( qobject_cast<QProcess*>( io.get() ) )
00142 {
00143   assert( mIO );
00144 }
00145 
00146 QIODeviceDataProvider::~QIODeviceDataProvider() {}
00147 
00148 bool QIODeviceDataProvider::isSupported( Operation op ) const {
00149     const QProcess* const proc = qobject_cast<QProcess*>( mIO.get() );
00150     bool canRead = true;
00151     if ( proc ) {
00152         canRead = proc->readChannel() == QProcess::StandardOutput;
00153     }
00154 
00155     switch ( op ) {
00156     case Read:    return mIO->isReadable() && canRead;
00157     case Write:   return mIO->isWritable();
00158     case Seek:    return !mIO->isSequential();
00159     case Release: return true;
00160     default:      return false;
00161     }
00162 }
00163 
00164 static qint64 blocking_read( const boost::shared_ptr<QIODevice> & io, char * buffer, qint64 maxSize ) {
00165     while ( !io->bytesAvailable() ) {
00166         if ( !io->waitForReadyRead( -1 ) ) {
00167             if ( const QProcess * const p = qobject_cast<QProcess*>( io.get() ) ) {
00168                 if ( p->error() == QProcess::UnknownError &&
00169                      p->exitStatus() == QProcess::NormalExit &&
00170                      p->exitCode() == 0 ) {
00171                     return 0;
00172                 } else {
00173                     Error::setSystemError( GPG_ERR_EIO );
00174                     return -1;
00175                 }
00176             } else {
00177                 return 0; // assume EOF (loses error cases :/ )
00178             }
00179         }
00180     }
00181     return io->read( buffer, maxSize );
00182 }
00183 
00184 ssize_t QIODeviceDataProvider::read( void * buffer, size_t bufSize ) {
00185 #ifndef NDEBUG
00186   //qDebug( "QIODeviceDataProvider::read( %p, %lu )", buffer, bufSize );
00187 #endif
00188   if ( bufSize == 0 )
00189     return 0;
00190   if ( !buffer ) {
00191     Error::setSystemError( GPG_ERR_EINVAL );
00192     return -1;
00193   }
00194   const qint64 numRead = mHaveQProcess
00195       ? blocking_read( mIO, static_cast<char*>(buffer), bufSize )
00196       : mIO->read( static_cast<char*>(buffer), bufSize ) ;
00197 
00198   //workaround: some QIODevices (known example: QProcess) might not return 0 (EOF), but immediately -1 when finished. If no
00199   //errno is set, gpgme doesn't detect the error and loops forever. So return 0 on the very first -1 in case errno is 0
00200 
00201   ssize_t rc = numRead;
00202   if ( numRead < 0 && !Error::hasSystemError() ) {
00203       if ( mErrorOccurred )
00204           Error::setSystemError( GPG_ERR_EIO );
00205       else
00206           rc = 0;
00207   }
00208   if ( numRead < 0 )
00209       mErrorOccurred = true;
00210   return rc;
00211 }
00212 
00213 ssize_t QIODeviceDataProvider::write( const void * buffer, size_t bufSize ) {
00214 #ifndef NDEBUG
00215   //qDebug( "QIODeviceDataProvider::write( %p, %lu )", buffer, static_cast<unsigned long>( bufSize ) );
00216 #endif
00217   if ( bufSize == 0 )
00218     return 0;
00219   if ( !buffer ) {
00220      Error::setSystemError( GPG_ERR_EINVAL );
00221      return -1;
00222   }
00223 
00224   return mIO->write( static_cast<const char*>(buffer), bufSize );
00225 }
00226 
00227 off_t QIODeviceDataProvider::seek( off_t offset, int whence ) {
00228 #ifndef NDEBUG
00229   //qDebug( "QIODeviceDataProvider::seek( %d, %d )", int(offset), whence );
00230 #endif
00231   if ( mIO->isSequential() ) {
00232     Error::setSystemError( GPG_ERR_ESPIPE );
00233     return (off_t)-1;
00234   }
00235   qint64 newOffset = mIO->pos();
00236   switch ( whence ) {
00237   case SEEK_SET:
00238     newOffset = offset;
00239     break;
00240   case SEEK_CUR:
00241     newOffset += offset;
00242     break;
00243   case SEEK_END:
00244     newOffset = mIO->size() + offset;
00245     break;
00246   default:
00247     Error::setSystemError( GPG_ERR_EINVAL );
00248     return (off_t)-1;
00249   }
00250   if ( !mIO->seek( newOffset ) ) {
00251     Error::setSystemError( GPG_ERR_EINVAL );
00252     return (off_t)-1;
00253   }
00254   return newOffset;
00255 }
00256 
00257 void QIODeviceDataProvider::release() {
00258 #ifndef NDEBUG
00259   //qDebug( "QIODeviceDataProvider::release()" );
00260 #endif
00261   mIO->close();
00262 }

qgpgme

Skip menu "qgpgme"
  • Main Page
  • File List

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.7.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal