• Skip to content
  • Skip to link menu
KDE 4.5 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                 }
00167             } else {
00168                 return 0; // assume EOF (loses error cases :/ )
00169             }
00170         }
00171     }
00172     return io->read( buffer, maxSize );
00173 }
00174 
00175 ssize_t QIODeviceDataProvider::read( void * buffer, size_t bufSize ) {
00176 #ifndef NDEBUG
00177   //qDebug( "QIODeviceDataProvider::read( %p, %lu )", buffer, bufSize );
00178 #endif
00179   if ( bufSize == 0 )
00180     return 0;
00181   if ( !buffer ) {
00182     errno = EINVAL;
00183     return -1;
00184   }
00185   const qint64 numRead = mHaveQProcess
00186       ? blocking_read( mIO, static_cast<char*>(buffer), bufSize )
00187       : mIO->read( static_cast<char*>(buffer), bufSize ) ;
00188 
00189   //workaround: some QIODevices (known example: QProcess) might not return 0 (EOF), but immediately -1 when finished. If no
00190   //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
00191 
00192   ssize_t rc = numRead;
00193   if ( numRead < 0 && errno == 0 ) {
00194       if ( mErrorOccurred )
00195           errno = EIO;
00196       else
00197           rc = 0;
00198   }
00199   if ( numRead < 0 )
00200       mErrorOccurred = true;
00201   return rc;
00202 }
00203 
00204 ssize_t QIODeviceDataProvider::write( const void * buffer, size_t bufSize ) {
00205 #ifndef NDEBUG
00206   //qDebug( "QIODeviceDataProvider::write( %p, %lu )", buffer, static_cast<unsigned long>( bufSize ) );
00207 #endif
00208   if ( bufSize == 0 )
00209     return 0;
00210   if ( !buffer ) {
00211      errno = EINVAL;
00212      return -1;
00213   }
00214 
00215   return mIO->write( static_cast<const char*>(buffer), bufSize );
00216 }
00217 
00218 off_t QIODeviceDataProvider::seek( off_t offset, int whence ) {
00219 #ifndef NDEBUG
00220   //qDebug( "QIODeviceDataProvider::seek( %d, %d )", int(offset), whence );
00221 #endif
00222   if ( mIO->isSequential() ) {
00223     errno = ESPIPE;
00224     return (off_t)-1;
00225   }
00226   qint64 newOffset = mIO->pos();
00227   switch ( whence ) {
00228   case SEEK_SET:
00229     newOffset = offset;
00230     break;
00231   case SEEK_CUR:
00232     newOffset += offset;
00233     break;
00234   case SEEK_END:
00235     newOffset = mIO->size() + offset;
00236     break;
00237   default:
00238     errno = EINVAL;
00239     return (off_t)-1;
00240   }
00241   if ( !mIO->seek( newOffset ) ) {
00242     errno = EINVAL;
00243     return (off_t)-1;
00244   }
00245   return newOffset;
00246 }
00247 
00248 void QIODeviceDataProvider::release() {
00249 #ifndef NDEBUG
00250   //qDebug( "QIODeviceDataProvider::release()" );
00251 #endif
00252   mIO->close();
00253 }

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.7.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