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 );
53 QByteArrayDataProvider::QByteArrayDataProvider()
54 : GpgME::DataProvider(), mOff( 0 ) {}
56 QByteArrayDataProvider::QByteArrayDataProvider(
const QByteArray & initialData )
57 : GpgME::DataProvider(), mArray( initialData ), mOff( 0 ) {}
59 QByteArrayDataProvider::~QByteArrayDataProvider() {}
61 ssize_t QByteArrayDataProvider::read(
void * buffer,
size_t bufSize ) {
69 Error::setSystemError( GPG_ERR_EINVAL );
72 if ( mOff >= mArray.size() ) {
75 size_t amount = qMin( bufSize, static_cast<size_t>( mArray.size() - mOff ) );
77 memcpy( buffer, mArray.data() + mOff, amount );
82 ssize_t QByteArrayDataProvider::write(
const void * buffer,
size_t bufSize ) {
90 Error::setSystemError( GPG_ERR_EINVAL );
93 if ( mOff >= mArray.size() ) {
94 resizeAndInit( mArray, mOff + bufSize );
96 if ( mOff >= mArray.size() ) {
97 Error::setSystemError( GPG_ERR_EIO );
100 assert( bufSize <= static_cast<size_t>( mArray.size() ) - mOff );
101 memcpy( mArray.data() + mOff, buffer, bufSize );
106 off_t QByteArrayDataProvider::seek( off_t offset,
int whence ) {
110 int newOffset = mOff;
119 newOffset = mArray.size() + offset;
122 Error::setSystemError( GPG_ERR_EINVAL );
125 return mOff = newOffset;
128 void QByteArrayDataProvider::release() {
142 QIODeviceDataProvider::QIODeviceDataProvider(
const boost::shared_ptr<QIODevice> & io )
143 : GpgME::DataProvider(),
145 mErrorOccurred( false ),
146 mHaveQProcess( qobject_cast<
QProcess*>( io.get() ) )
151 QIODeviceDataProvider::~QIODeviceDataProvider() {}
153 bool QIODeviceDataProvider::isSupported( Operation op )
const {
157 canRead = proc->
readChannel() == QProcess::StandardOutput;
161 case Read:
return mIO->isReadable() && canRead;
162 case Write:
return mIO->isWritable();
163 case Seek:
return !mIO->isSequential();
164 case Release:
return true;
165 default:
return false;
169 static qint64 blocking_read(
const boost::shared_ptr<QIODevice> & io,
char * buffer, qint64 maxSize ) {
170 while ( !io->bytesAvailable() ) {
171 if ( !io->waitForReadyRead( -1 ) ) {
172 if (
const QProcess *
const p = qobject_cast<QProcess*>( io.get() ) ) {
173 if ( p->error() == QProcess::UnknownError &&
174 p->exitStatus() == QProcess::NormalExit &&
175 p->exitCode() == 0 ) {
178 Error::setSystemError( GPG_ERR_EIO );
186 return io->read( buffer, maxSize );
189 ssize_t QIODeviceDataProvider::read(
void * buffer,
size_t bufSize ) {
193 if ( bufSize == 0 ) {
197 Error::setSystemError( GPG_ERR_EINVAL );
200 const qint64 numRead = mHaveQProcess
201 ? blocking_read( mIO, static_cast<char*>( buffer ), bufSize )
202 : mIO->read( static_cast<char*>( buffer ), bufSize );
207 ssize_t rc = numRead;
208 if ( numRead < 0 && !Error::hasSystemError() ) {
209 if ( mErrorOccurred ) {
210 Error::setSystemError( GPG_ERR_EIO );
216 mErrorOccurred =
true;
221 ssize_t QIODeviceDataProvider::write(
const void * buffer,
size_t bufSize ) {
225 if ( bufSize == 0 ) {
229 Error::setSystemError( GPG_ERR_EINVAL );
233 return mIO->write( static_cast<const char*>( buffer ), bufSize );
236 off_t QIODeviceDataProvider::seek( off_t offset,
int whence ) {
240 if ( mIO->isSequential() ) {
241 Error::setSystemError( GPG_ERR_ESPIPE );
244 qint64 newOffset = mIO->pos();
253 newOffset = mIO->size() + offset;
256 Error::setSystemError( GPG_ERR_EINVAL );
259 if ( !mIO->seek( newOffset ) ) {
260 Error::setSystemError( GPG_ERR_EINVAL );
266 void QIODeviceDataProvider::release() {
ProcessChannel readChannel() const