23 #include <qgpgme/dataprovider.h>
25 #include <gpgme++/error.h>
34 using namespace QGpgME;
35 using namespace GpgME;
43 static bool resizeAndInit( QByteArray & ba,
size_t newSize ) {
44 const size_t oldSize = ba.size();
46 const bool ok = ( newSize ==
static_cast<size_t>( ba.size() ) );
48 memset( ba.data() + oldSize, 0, newSize - oldSize );
52 QByteArrayDataProvider::QByteArrayDataProvider()
53 : GpgME::DataProvider(), mOff( 0 ) {}
55 QByteArrayDataProvider::QByteArrayDataProvider(
const QByteArray & initialData )
56 : GpgME::DataProvider(), mArray( initialData ), mOff( 0 ) {}
58 QByteArrayDataProvider::~QByteArrayDataProvider() {}
60 ssize_t QByteArrayDataProvider::read(
void * buffer,
size_t bufSize ) {
67 Error::setSystemError( GPG_ERR_EINVAL );
70 if ( mOff >= mArray.size() )
72 size_t amount = qMin( bufSize, static_cast<size_t>( mArray.size() - mOff ) );
74 memcpy( buffer, mArray.data() + mOff, amount );
79 ssize_t QByteArrayDataProvider::write(
const void * buffer,
size_t bufSize ) {
86 Error::setSystemError( GPG_ERR_EINVAL );
89 if ( mOff >= mArray.size() )
90 resizeAndInit( mArray, mOff + bufSize );
91 if ( mOff >= mArray.size() ) {
92 Error::setSystemError( GPG_ERR_EIO );
95 assert( bufSize <= static_cast<size_t>(mArray.size()) - mOff );
96 memcpy( mArray.data() + mOff, buffer, bufSize );
101 off_t QByteArrayDataProvider::seek( off_t offset,
int whence ) {
105 int newOffset = mOff;
114 newOffset = mArray.size() + offset;
117 Error::setSystemError( GPG_ERR_EINVAL );
120 return mOff = newOffset;
123 void QByteArrayDataProvider::release() {
127 mArray = QByteArray();
137 QIODeviceDataProvider::QIODeviceDataProvider(
const boost::shared_ptr<QIODevice> & io )
138 : GpgME::DataProvider(),
140 mErrorOccurred( false ),
141 mHaveQProcess( qobject_cast<QProcess*>( io.get() ) )
146 QIODeviceDataProvider::~QIODeviceDataProvider() {}
148 bool QIODeviceDataProvider::isSupported( Operation op )
const {
149 const QProcess*
const proc = qobject_cast<QProcess*>( mIO.get() );
152 canRead = proc->readChannel() == QProcess::StandardOutput;
156 case Read:
return mIO->isReadable() && canRead;
157 case Write:
return mIO->isWritable();
158 case Seek:
return !mIO->isSequential();
159 case Release:
return true;
160 default:
return false;
164 static qint64 blocking_read(
const boost::shared_ptr<QIODevice> & io,
char * buffer, qint64 maxSize ) {
165 while ( !io->bytesAvailable() ) {
166 if ( !io->waitForReadyRead( -1 ) ) {
167 if (
const QProcess *
const p = qobject_cast<QProcess*>( io.get() ) ) {
168 if ( p->error() == QProcess::UnknownError &&
169 p->exitStatus() == QProcess::NormalExit &&
170 p->exitCode() == 0 ) {
173 Error::setSystemError( GPG_ERR_EIO );
181 return io->read( buffer, maxSize );
184 ssize_t QIODeviceDataProvider::read(
void * buffer,
size_t bufSize ) {
191 Error::setSystemError( GPG_ERR_EINVAL );
194 const qint64 numRead = mHaveQProcess
195 ? blocking_read( mIO, static_cast<char*>(buffer), bufSize )
196 : mIO->read( static_cast<char*>(buffer), bufSize ) ;
201 ssize_t rc = numRead;
202 if ( numRead < 0 && !Error::hasSystemError() ) {
203 if ( mErrorOccurred )
204 Error::setSystemError( GPG_ERR_EIO );
209 mErrorOccurred =
true;
213 ssize_t QIODeviceDataProvider::write(
const void * buffer,
size_t bufSize ) {
220 Error::setSystemError( GPG_ERR_EINVAL );
224 return mIO->write( static_cast<const char*>(buffer), bufSize );
227 off_t QIODeviceDataProvider::seek( off_t offset,
int whence ) {
231 if ( mIO->isSequential() ) {
232 Error::setSystemError( GPG_ERR_ESPIPE );
235 qint64 newOffset = mIO->pos();
244 newOffset = mIO->size() + offset;
247 Error::setSystemError( GPG_ERR_EINVAL );
250 if ( !mIO->seek( newOffset ) ) {
251 Error::setSystemError( GPG_ERR_EINVAL );
257 void QIODeviceDataProvider::release() {