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 }
00184 return numRead;
00185 }
00186
00187 ssize_t QIODeviceDataProvider::write( const void * buffer, size_t bufSize ) {
00188 #ifndef NDEBUG
00189 qDebug( "QIODeviceDataProvider::write( %p, %lu )", buffer, static_cast<unsigned long>( bufSize ) );
00190 #endif
00191 if ( bufSize == 0 )
00192 return 0;
00193 if ( !buffer ) {
00194 errno = EINVAL;
00195 return -1;
00196 }
00197
00198 return mIO->write( static_cast<const char*>(buffer), bufSize );
00199 }
00200
00201 off_t QIODeviceDataProvider::seek( off_t offset, int whence ) {
00202 #ifndef NDEBUG
00203 qDebug( "QIODeviceDataProvider::seek( %d, %d )", int(offset), whence );
00204 #endif
00205 if ( mIO->isSequential() ) {
00206 errno = ESPIPE;
00207 return (off_t)-1;
00208 }
00209 qint64 newOffset = mIO->pos();
00210 switch ( whence ) {
00211 case SEEK_SET:
00212 newOffset = offset;
00213 break;
00214 case SEEK_CUR:
00215 newOffset += offset;
00216 break;
00217 case SEEK_END:
00218 newOffset = mIO->size() + offset;
00219 break;
00220 default:
00221 errno = EINVAL;
00222 return (off_t)-1;
00223 }
00224 if ( !mIO->seek( newOffset ) ) {
00225 errno = EINVAL;
00226 return (off_t)-1;
00227 }
00228 return newOffset;
00229 }
00230
00231 void QIODeviceDataProvider::release() {
00232 #ifndef NDEBUG
00233 qDebug( "QIODeviceDataProvider::release()" );
00234 #endif
00235 mIO->close();
00236 }