• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • 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 <QIODevice>
00026 #include <QProcess>
00027 
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <errno.h>
00031 #include <assert.h>
00032 
00033 using namespace QGpgME;
00034 
00035 //
00036 //
00037 // QByteArrayDataProvider
00038 //
00039 //
00040 
00041 static bool resizeAndInit( QByteArray & ba, size_t newSize ) {
00042   const size_t oldSize = ba.size();
00043   ba.resize( newSize );
00044   const bool ok = ( newSize == static_cast<size_t>( ba.size() ) );
00045   if ( ok )
00046     memset( ba.data() + oldSize, 0, newSize - oldSize );
00047   return ok;
00048 }
00049 
00050 QByteArrayDataProvider::QByteArrayDataProvider()
00051   : GpgME::DataProvider(), mOff( 0 ) {}
00052 
00053 QByteArrayDataProvider::QByteArrayDataProvider( const QByteArray & initialData )
00054   : GpgME::DataProvider(), mArray( initialData ), mOff( 0 ) {}
00055 
00056 QByteArrayDataProvider::~QByteArrayDataProvider() {}
00057 
00058 ssize_t QByteArrayDataProvider::read( void * buffer, size_t bufSize ) {
00059 #ifndef NDEBUG
00060   //qDebug( "QByteArrayDataProvider::read( %p, %d )", buffer, bufSize );
00061 #endif
00062   if ( bufSize == 0 )
00063     return 0;
00064   if ( !buffer ) {
00065     errno = EINVAL;
00066     return -1;
00067   }
00068   if ( mOff >= mArray.size() )
00069     return 0; // EOF
00070   size_t amount = qMin( bufSize, static_cast<size_t>( mArray.size() - mOff ) );
00071   assert( amount > 0 );
00072   memcpy( buffer, mArray.data() + mOff, amount );
00073   mOff += amount;
00074   return amount;
00075 }
00076 
00077 ssize_t QByteArrayDataProvider::write( const void * buffer, size_t bufSize ) {
00078 #ifndef NDEBUG
00079   //qDebug( "QByteArrayDataProvider::write( %p, %lu )", buffer, static_cast<unsigned long>( bufSize ) );
00080 #endif
00081   if ( bufSize == 0 )
00082     return 0;
00083   if ( !buffer ) {
00084     errno = EINVAL;
00085     return -1;
00086   }
00087   if ( mOff >= mArray.size() )
00088     resizeAndInit( mArray, mOff + bufSize );
00089   if ( mOff >= mArray.size() ) {
00090     errno = EIO;
00091     return -1;
00092   }
00093   assert( bufSize <= static_cast<size_t>(mArray.size()) - mOff );
00094   memcpy( mArray.data() + mOff, buffer, bufSize );
00095   mOff += bufSize;
00096   return bufSize;
00097 }
00098 
00099 off_t QByteArrayDataProvider::seek( off_t offset, int whence ) {
00100 #ifndef NDEBUG
00101   //qDebug( "QByteArrayDataProvider::seek( %d, %d )", int(offset), whence );
00102 #endif
00103   int newOffset = mOff;
00104   switch ( whence ) {
00105   case SEEK_SET:
00106     newOffset = offset;
00107     break;
00108   case SEEK_CUR:
00109     newOffset += offset;
00110     break;
00111   case SEEK_END:
00112     newOffset = mArray.size() + offset;
00113     break;
00114   default:
00115     errno = EINVAL;
00116     return (off_t)-1;
00117   }
00118   return mOff = newOffset;
00119 }
00120 
00121 void QByteArrayDataProvider::release() {
00122 #ifndef NDEBUG
00123   //qDebug( "QByteArrayDataProvider::release()" );
00124 #endif
00125   mArray = QByteArray();
00126 }
00127 
00128 
00129 //
00130 //
00131 // QIODeviceDataProvider
00132 //
00133 //
00134 
00135 QIODeviceDataProvider::QIODeviceDataProvider( const boost::shared_ptr<QIODevice> & io )
00136   : GpgME::DataProvider(),
00137     mIO( io ),
00138     mErrorOccurred( false ),
00139     mHaveQProcess( qobject_cast<QProcess*>( io.get() ) )
00140 {
00141   assert( mIO );
00142 }
00143 
00144 QIODeviceDataProvider::~QIODeviceDataProvider() {}
00145 
00146 bool QIODeviceDataProvider::isSupported( Operation op ) const {
00147     switch ( op ) {
00148     case Read:    return mIO->isReadable();
00149     case Write:   return mIO->isWritable();
00150     case Seek:    return !mIO->isSequential();
00151     case Release: return true;
00152     default:      return false;
00153     }
00154 }
00155 
00156 static qint64 blocking_read( const boost::shared_ptr<QIODevice> & io, char * buffer, qint64 maxSize ) {
00157     while ( !io->bytesAvailable() )
00158         if ( !io->waitForReadyRead( -1 ) )
00159             if ( const QProcess * const p = qobject_cast<QProcess*>( io.get() ) )
00160                 if ( p->error() == QProcess::UnknownError &&
00161                      p->exitStatus() == QProcess::NormalExit &&
00162                      p->exitCode() == 0 )
00163                     return 0;
00164                 else
00165                     return errno = EIO, -1;
00166             else
00167                 return 0; // assume EOF (loses error cases :/ )
00168 
00169     return io->read( buffer, maxSize );
00170 }
00171 
00172 ssize_t QIODeviceDataProvider::read( void * buffer, size_t bufSize ) {
00173 #ifndef NDEBUG
00174   //qDebug( "QIODeviceDataProvider::read( %p, %lu )", buffer, bufSize );
00175 #endif
00176   if ( bufSize == 0 )
00177     return 0;
00178   if ( !buffer ) {
00179     errno = EINVAL;
00180     return -1;
00181   }
00182   const qint64 numRead = mHaveQProcess
00183       ? blocking_read( mIO, static_cast<char*>(buffer), bufSize )
00184       : mIO->read( static_cast<char*>(buffer), bufSize ) ;
00185 
00186   //workaround: some QIODevices (known example: QProcess) might not return 0 (EOF), but immediately -1 when finished. If no
00187   //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
00188 
00189   ssize_t rc = numRead;
00190   if ( numRead < 0 && errno == 0 ) {
00191       if ( mErrorOccurred )
00192           errno = EIO;
00193       else
00194           rc = 0;
00195   }
00196   if ( numRead < 0 )
00197       mErrorOccurred = true;
00198   return rc;
00199 }
00200 
00201 ssize_t QIODeviceDataProvider::write( const void * buffer, size_t bufSize ) {
00202 #ifndef NDEBUG
00203   //qDebug( "QIODeviceDataProvider::write( %p, %lu )", buffer, static_cast<unsigned long>( bufSize ) );
00204 #endif
00205   if ( bufSize == 0 )
00206     return 0;
00207   if ( !buffer ) {
00208      errno = EINVAL;
00209      return -1;
00210   }
00211 
00212   return mIO->write( static_cast<const char*>(buffer), bufSize );
00213 }
00214 
00215 off_t QIODeviceDataProvider::seek( off_t offset, int whence ) {
00216 #ifndef NDEBUG
00217   //qDebug( "QIODeviceDataProvider::seek( %d, %d )", int(offset), whence );
00218 #endif
00219   if ( mIO->isSequential() ) {
00220     errno = ESPIPE;
00221     return (off_t)-1;
00222   }
00223   qint64 newOffset = mIO->pos();
00224   switch ( whence ) {
00225   case SEEK_SET:
00226     newOffset = offset;
00227     break;
00228   case SEEK_CUR:
00229     newOffset += offset;
00230     break;
00231   case SEEK_END:
00232     newOffset = mIO->size() + offset;
00233     break;
00234   default:
00235     errno = EINVAL;
00236     return (off_t)-1;
00237   }
00238   if ( !mIO->seek( newOffset ) ) {
00239     errno = EINVAL;
00240     return (off_t)-1;
00241   }
00242   return newOffset;
00243 }
00244 
00245 void QIODeviceDataProvider::release() {
00246 #ifndef NDEBUG
00247   //qDebug( "QIODeviceDataProvider::release()" );
00248 #endif
00249   mIO->close();
00250 }

qgpgme

Skip menu "qgpgme"
  • Main Page
  • File List

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.6.2-20100208
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