LCOV - code coverage report
Current view: top level - lang/qt/src - dataprovider.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 128 0.0 %
Date: 2016-12-15 13:18:47 Functions: 0 18 0.0 %

          Line data    Source code
       1             : /* dataprovider.cpp
       2             :    Copyright (C) 2004 Klarävdalens Datakonsult AB
       3             :     Copyright (c) 2016 Intevation GmbH
       4             : 
       5             :    This file is part of QGPGME.
       6             : 
       7             :    QGPGME is free software; you can redistribute it and/or modify it
       8             :    under the terms of the GNU Library General Public License as published
       9             :    by the Free Software Foundation; either version 2 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    QGPGME is distributed in the hope that it will be useful, but
      13             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU Library General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU Library General Public License
      18             :    along with QGPGME; see the file COPYING.LIB.  If not, write to the
      19             :    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
      20             :    Boston, MA 02110-1301, USA. */
      21             : 
      22             : // -*- c++ -*-
      23             : 
      24             : #ifdef HAVE_CONFIG_H
      25             :  #include "config.h"
      26             : #endif
      27             : 
      28             : #include <dataprovider.h>
      29             : 
      30             : #include <error.h>
      31             : 
      32             : #include <QIODevice>
      33             : #include <QProcess>
      34             : 
      35             : #include <cstdio>
      36             : #include <cstring>
      37             : #include <cassert>
      38             : 
      39             : using namespace QGpgME;
      40             : using namespace GpgME;
      41             : 
      42             : //
      43             : //
      44             : // QByteArrayDataProvider
      45             : //
      46             : //
      47             : 
      48           0 : static bool resizeAndInit(QByteArray &ba, size_t newSize)
      49             : {
      50           0 :     const size_t oldSize = ba.size();
      51           0 :     ba.resize(newSize);
      52           0 :     const bool ok = (newSize == static_cast<size_t>(ba.size()));
      53           0 :     if (ok) {
      54           0 :         memset(ba.data() + oldSize, 0, newSize - oldSize);
      55             :     }
      56           0 :     return ok;
      57             : }
      58             : 
      59           0 : QByteArrayDataProvider::QByteArrayDataProvider()
      60           0 :     : GpgME::DataProvider(), mOff(0) {}
      61             : 
      62           0 : QByteArrayDataProvider::QByteArrayDataProvider(const QByteArray &initialData)
      63           0 :     : GpgME::DataProvider(), mArray(initialData), mOff(0) {}
      64             : 
      65           0 : QByteArrayDataProvider::~QByteArrayDataProvider() {}
      66             : 
      67           0 : ssize_t QByteArrayDataProvider::read(void *buffer, size_t bufSize)
      68             : {
      69             : #ifndef NDEBUG
      70             :     //qDebug( "QByteArrayDataProvider::read( %p, %d )", buffer, bufSize );
      71             : #endif
      72           0 :     if (bufSize == 0) {
      73           0 :         return 0;
      74             :     }
      75           0 :     if (!buffer) {
      76           0 :         Error::setSystemError(GPG_ERR_EINVAL);
      77           0 :         return -1;
      78             :     }
      79           0 :     if (mOff >= mArray.size()) {
      80           0 :         return 0; // EOF
      81             :     }
      82           0 :     size_t amount = qMin(bufSize, static_cast<size_t>(mArray.size() - mOff));
      83           0 :     assert(amount > 0);
      84           0 :     memcpy(buffer, mArray.data() + mOff, amount);
      85           0 :     mOff += amount;
      86           0 :     return amount;
      87             : }
      88             : 
      89           0 : ssize_t QByteArrayDataProvider::write(const void *buffer, size_t bufSize)
      90             : {
      91             : #ifndef NDEBUG
      92             :     //qDebug( "QByteArrayDataProvider::write( %p, %lu )", buffer, static_cast<unsigned long>( bufSize ) );
      93             : #endif
      94           0 :     if (bufSize == 0) {
      95           0 :         return 0;
      96             :     }
      97           0 :     if (!buffer) {
      98           0 :         Error::setSystemError(GPG_ERR_EINVAL);
      99           0 :         return -1;
     100             :     }
     101           0 :     if (mOff >= mArray.size()) {
     102           0 :         resizeAndInit(mArray, mOff + bufSize);
     103             :     }
     104           0 :     if (mOff >= mArray.size()) {
     105           0 :         Error::setSystemError(GPG_ERR_EIO);
     106           0 :         return -1;
     107             :     }
     108           0 :     assert(bufSize <= static_cast<size_t>(mArray.size()) - mOff);
     109           0 :     memcpy(mArray.data() + mOff, buffer, bufSize);
     110           0 :     mOff += bufSize;
     111           0 :     return bufSize;
     112             : }
     113             : 
     114           0 : off_t QByteArrayDataProvider::seek(off_t offset, int whence)
     115             : {
     116             : #ifndef NDEBUG
     117             :     //qDebug( "QByteArrayDataProvider::seek( %d, %d )", int(offset), whence );
     118             : #endif
     119           0 :     int newOffset = mOff;
     120           0 :     switch (whence) {
     121             :     case SEEK_SET:
     122           0 :         newOffset = offset;
     123           0 :         break;
     124             :     case SEEK_CUR:
     125           0 :         newOffset += offset;
     126           0 :         break;
     127             :     case SEEK_END:
     128           0 :         newOffset = mArray.size() + offset;
     129           0 :         break;
     130             :     default:
     131           0 :         Error::setSystemError(GPG_ERR_EINVAL);
     132           0 :         return (off_t) - 1;
     133             :     }
     134           0 :     return mOff = newOffset;
     135             : }
     136             : 
     137           0 : void QByteArrayDataProvider::release()
     138             : {
     139             : #ifndef NDEBUG
     140             :     //qDebug( "QByteArrayDataProvider::release()" );
     141             : #endif
     142           0 :     mArray = QByteArray();
     143           0 : }
     144             : 
     145             : //
     146             : //
     147             : // QIODeviceDataProvider
     148             : //
     149             : //
     150             : 
     151           0 : QIODeviceDataProvider::QIODeviceDataProvider(const std::shared_ptr<QIODevice> &io)
     152             :     : GpgME::DataProvider(),
     153             :       mIO(io),
     154             :       mErrorOccurred(false),
     155           0 :       mHaveQProcess(qobject_cast<QProcess *>(io.get()))
     156             : {
     157           0 :     assert(mIO);
     158           0 : }
     159             : 
     160           0 : QIODeviceDataProvider::~QIODeviceDataProvider() {}
     161             : 
     162           0 : bool QIODeviceDataProvider::isSupported(Operation op) const
     163             : {
     164           0 :     const QProcess *const proc = qobject_cast<QProcess *>(mIO.get());
     165           0 :     bool canRead = true;
     166           0 :     if (proc) {
     167           0 :         canRead = proc->readChannel() == QProcess::StandardOutput;
     168             :     }
     169             : 
     170           0 :     switch (op) {
     171           0 :     case Read:    return mIO->isReadable() && canRead;
     172           0 :     case Write:   return mIO->isWritable();
     173           0 :     case Seek:    return !mIO->isSequential();
     174           0 :     case Release: return true;
     175           0 :     default:      return false;
     176             :     }
     177             : }
     178             : 
     179           0 : static qint64 blocking_read(const std::shared_ptr<QIODevice> &io, char *buffer, qint64 maxSize)
     180             : {
     181           0 :     while (!io->bytesAvailable()) {
     182           0 :         if (!io->waitForReadyRead(-1)) {
     183           0 :             if (const QProcess *const p = qobject_cast<QProcess *>(io.get())) {
     184           0 :                 if (p->error() == QProcess::UnknownError &&
     185           0 :                         p->exitStatus() == QProcess::NormalExit &&
     186           0 :                         p->exitCode() == 0) {
     187           0 :                     return 0;
     188             :                 } else {
     189           0 :                     Error::setSystemError(GPG_ERR_EIO);
     190           0 :                     return -1;
     191             :                 }
     192             :             } else {
     193           0 :                 return 0; // assume EOF (loses error cases :/ )
     194             :             }
     195             :         }
     196             :     }
     197           0 :     return io->read(buffer, maxSize);
     198             : }
     199             : 
     200           0 : ssize_t QIODeviceDataProvider::read(void *buffer, size_t bufSize)
     201             : {
     202             : #ifndef NDEBUG
     203             :     //qDebug( "QIODeviceDataProvider::read( %p, %lu )", buffer, bufSize );
     204             : #endif
     205           0 :     if (bufSize == 0) {
     206           0 :         return 0;
     207             :     }
     208           0 :     if (!buffer) {
     209           0 :         Error::setSystemError(GPG_ERR_EINVAL);
     210           0 :         return -1;
     211             :     }
     212           0 :     const qint64 numRead = mHaveQProcess
     213           0 :                            ? blocking_read(mIO, static_cast<char *>(buffer), bufSize)
     214           0 :                            : mIO->read(static_cast<char *>(buffer), bufSize);
     215             : 
     216             :     //workaround: some QIODevices (known example: QProcess) might not return 0 (EOF), but immediately -1 when finished. If no
     217             :     //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
     218             : 
     219           0 :     ssize_t rc = numRead;
     220           0 :     if (numRead < 0 && !Error::hasSystemError()) {
     221           0 :         if (mErrorOccurred) {
     222           0 :             Error::setSystemError(GPG_ERR_EIO);
     223             :         } else {
     224           0 :             rc = 0;
     225             :         }
     226             :     }
     227           0 :     if (numRead < 0) {
     228           0 :         mErrorOccurred = true;
     229             :     }
     230           0 :     return rc;
     231             : }
     232             : 
     233           0 : ssize_t QIODeviceDataProvider::write(const void *buffer, size_t bufSize)
     234             : {
     235             : #ifndef NDEBUG
     236             :     //qDebug( "QIODeviceDataProvider::write( %p, %lu )", buffer, static_cast<unsigned long>( bufSize ) );
     237             : #endif
     238           0 :     if (bufSize == 0) {
     239           0 :         return 0;
     240             :     }
     241           0 :     if (!buffer) {
     242           0 :         Error::setSystemError(GPG_ERR_EINVAL);
     243           0 :         return -1;
     244             :     }
     245             : 
     246           0 :     return mIO->write(static_cast<const char *>(buffer), bufSize);
     247             : }
     248             : 
     249           0 : off_t QIODeviceDataProvider::seek(off_t offset, int whence)
     250             : {
     251             : #ifndef NDEBUG
     252             :     //qDebug( "QIODeviceDataProvider::seek( %d, %d )", int(offset), whence );
     253             : #endif
     254           0 :     if (mIO->isSequential()) {
     255           0 :         Error::setSystemError(GPG_ERR_ESPIPE);
     256           0 :         return (off_t) - 1;
     257             :     }
     258           0 :     qint64 newOffset = mIO->pos();
     259           0 :     switch (whence) {
     260             :     case SEEK_SET:
     261           0 :         newOffset = offset;
     262           0 :         break;
     263             :     case SEEK_CUR:
     264           0 :         newOffset += offset;
     265           0 :         break;
     266             :     case SEEK_END:
     267           0 :         newOffset = mIO->size() + offset;
     268           0 :         break;
     269             :     default:
     270           0 :         Error::setSystemError(GPG_ERR_EINVAL);
     271           0 :         return (off_t) - 1;
     272             :     }
     273           0 :     if (!mIO->seek(newOffset)) {
     274           0 :         Error::setSystemError(GPG_ERR_EINVAL);
     275           0 :         return (off_t) - 1;
     276             :     }
     277           0 :     return newOffset;
     278             : }
     279             : 
     280           0 : void QIODeviceDataProvider::release()
     281             : {
     282             : #ifndef NDEBUG
     283             :     //qDebug( "QIODeviceDataProvider::release()" );
     284             : #endif
     285           0 :     mIO->close();
     286           0 : }

Generated by: LCOV version 1.12