qgpgme
dataprovider.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <qgpgme/dataprovider.h>
00024
00025 #include <QIODevice>
00026
00027 #include <stdio.h>
00028 #include <string.h>
00029 #include <errno.h>
00030 #include <assert.h>
00031
00032 using namespace QGpgME;
00033
00034
00035
00036
00037
00038
00039
00040 static bool resizeAndInit( QByteArray & ba, size_t newSize ) {
00041 const size_t oldSize = ba.size();
00042 ba.resize( newSize );
00043 const bool ok = ( newSize == static_cast<size_t>( ba.size() ) );
00044 if ( ok )
00045 memset( ba.data() + oldSize, 0, newSize - oldSize );
00046 return ok;
00047 }
00048
00049 QByteArrayDataProvider::QByteArrayDataProvider()
00050 : GpgME::DataProvider(), mOff( 0 ) {}
00051
00052 QByteArrayDataProvider::QByteArrayDataProvider( const QByteArray & initialData )
00053 : GpgME::DataProvider(), mArray( initialData ), mOff( 0 ) {}
00054
00055 QByteArrayDataProvider::~QByteArrayDataProvider() {}
00056
00057 ssize_t QByteArrayDataProvider::read( void * buffer, size_t bufSize ) {
00058 #ifndef NDEBUG
00059
00060 #endif
00061 if ( bufSize == 0 )
00062 return 0;
00063 if ( !buffer ) {
00064 errno = EINVAL;
00065 return -1;
00066 }
00067 if ( mOff >= mArray.size() )
00068 return 0;
00069 size_t amount = qMin( bufSize, static_cast<size_t>( mArray.size() - mOff ) );
00070 assert( amount > 0 );
00071 memcpy( buffer, mArray.data() + mOff, amount );
00072 mOff += amount;
00073 return amount;
00074 }
00075
00076 ssize_t QByteArrayDataProvider::write( const void * buffer, size_t bufSize ) {
00077 #ifndef NDEBUG
00078 qDebug( "QByteArrayDataProvider::write( %p, %lu )", buffer, static_cast<unsigned long>( bufSize ) );
00079 #endif
00080 if ( bufSize == 0 )
00081 return 0;
00082 if ( !buffer ) {
00083 errno = EINVAL;
00084 return -1;
00085 }
00086 if ( mOff >= mArray.size() )
00087 resizeAndInit( mArray, mOff + bufSize );
00088 if ( mOff >= mArray.size() ) {
00089 errno = EIO;
00090 return -1;
00091 }
00092 assert( bufSize <= static_cast<size_t>(mArray.size()) - mOff );
00093 memcpy( mArray.data() + mOff, buffer, bufSize );
00094 mOff += bufSize;
00095 return bufSize;
00096 }
00097
00098 off_t QByteArrayDataProvider::seek( off_t offset, int whence ) {
00099 #ifndef NDEBUG
00100 qDebug( "QByteArrayDataProvider::seek( %d, %d )", int(offset), whence );
00101 #endif
00102 int newOffset = mOff;
00103 switch ( whence ) {
00104 case SEEK_SET:
00105 newOffset = offset;
00106 break;
00107 case SEEK_CUR:
00108 newOffset += offset;
00109 break;
00110 case SEEK_END:
00111 newOffset = mArray.size() + offset;
00112 break;
00113 default:
00114 errno = EINVAL;
00115 return (off_t)-1;
00116 }
00117 return mOff = newOffset;
00118 }
00119
00120 void QByteArrayDataProvider::release() {
00121 #ifndef NDEBUG
00122 qDebug( "QByteArrayDataProvider::release()" );
00123 #endif
00124 mArray = QByteArray();
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134 QIODeviceDataProvider::QIODeviceDataProvider( const boost::shared_ptr<QIODevice> & io )
00135 : GpgME::DataProvider(),
00136 mIO( io ),
00137 mErrorOccurred( false )
00138 {
00139 assert( mIO );
00140 }
00141
00142 QIODeviceDataProvider::~QIODeviceDataProvider() {}
00143
00144 bool QIODeviceDataProvider::isSupported( Operation op ) const {
00145 switch ( op ) {
00146 case Read: return mIO->isReadable();
00147 case Write: return mIO->isWritable();
00148 case Seek: return !mIO->isSequential();
00149 case Release: return true;
00150 default: return false;
00151 }
00152 }
00153
00154 namespace {
00155 struct Enabler {
00156 explicit Enabler( bool* b_ ) : b( b_) {}
00157 ~Enabler() { if ( b ) *b = true; }
00158 bool* const b;
00159 };
00160 }
00161
00162 ssize_t QIODeviceDataProvider::read( void * buffer, size_t bufSize ) {
00163 #ifndef NDEBUG
00164
00165 #endif
00166 if ( bufSize == 0 )
00167 return 0;
00168 if ( !buffer ) {
00169 errno = EINVAL;
00170 return -1;
00171 }
00172
00173
00174
00175 const qint64 numRead = mIO->read( static_cast<char*>(buffer), bufSize );
00176
00177 Enabler en( numRead < 0 ? &mErrorOccurred : 0 );
00178 if ( numRead < 0 && errno == 0 )
00179 if ( mErrorOccurred )
00180 errno = EIO;
00181 else
00182 return 0;
00183 return numRead;
00184 }
00185
00186 ssize_t QIODeviceDataProvider::write( const void * buffer, size_t bufSize ) {
00187 #ifndef NDEBUG
00188 qDebug( "QIODeviceDataProvider::write( %p, %lu )", buffer, static_cast<unsigned long>( bufSize ) );
00189 #endif
00190 if ( bufSize == 0 )
00191 return 0;
00192 if ( !buffer ) {
00193 errno = EINVAL;
00194 return -1;
00195 }
00196
00197 return mIO->write( static_cast<const char*>(buffer), bufSize );
00198 }
00199
00200 off_t QIODeviceDataProvider::seek( off_t offset, int whence ) {
00201 #ifndef NDEBUG
00202 qDebug( "QIODeviceDataProvider::seek( %d, %d )", int(offset), whence );
00203 #endif
00204 if ( mIO->isSequential() ) {
00205 errno = ESPIPE;
00206 return (off_t)-1;
00207 }
00208 qint64 newOffset = mIO->pos();
00209 switch ( whence ) {
00210 case SEEK_SET:
00211 newOffset = offset;
00212 break;
00213 case SEEK_CUR:
00214 newOffset += offset;
00215 break;
00216 case SEEK_END:
00217 newOffset = mIO->size() + offset;
00218 break;
00219 default:
00220 errno = EINVAL;
00221 return (off_t)-1;
00222 }
00223 if ( !mIO->seek( newOffset ) ) {
00224 errno = EINVAL;
00225 return (off_t)-1;
00226 }
00227 return newOffset;
00228 }
00229
00230 void QIODeviceDataProvider::release() {
00231 #ifndef NDEBUG
00232 qDebug( "QIODeviceDataProvider::release()" );
00233 #endif
00234 mIO->close();
00235 }